Prevalidate Hardware Specs on Linux
Prevalidates hardware resources on Linux platforms for Virtualbox and VMware builders. This is currently only available on Linux, as enabling for both Darwin and Windows platforms, relies on cgo bindings that would prevent effective cross-compilation. Packer will now fail to build and validate templates if the template is requesting that the VM to be created would allocate more system resources than the host system has available. This _however_ doesn't catch parallel builds that overflow the hosts resources, will probably still need a better error message for VM's failing to boot in that case. Example Outputs: ``` $ $GOPATH/bin/packer build -debug ./vmware-iso.json Debug mode enabled. Builds will not be parallelized. vmware-iso output will be in this color. 2 error(s) occurred: * Unavailable Resources: RAM - Requested - 204800000MB - Available 21721MB * Unavailable Resources: Disk - Requested - 4000000000MB - Available 76701MB ``` ``` $ $GOPATH/bin/packer build -debug ./vbox-iso.json Debug mode enabled. Builds will not be parallelized. virtualbox-iso output will be in this color. 2 error(s) occurred: * Unavailable Resources: RAM - Requested - 10240000MB - Available 21721MB * Unavailable Resources: Disk - Requested - 1000000000MB - Available 76701MB ```
This commit is contained in:
parent
1f8ebab4de
commit
eda84cb2d3
|
@ -1,6 +1,10 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/mitchellh/packer/common"
|
||||||
"github.com/mitchellh/packer/template/interpolate"
|
"github.com/mitchellh/packer/template/interpolate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,7 +15,25 @@ type VBoxManageConfig struct {
|
||||||
func (c *VBoxManageConfig) Prepare(ctx *interpolate.Context) []error {
|
func (c *VBoxManageConfig) Prepare(ctx *interpolate.Context) []error {
|
||||||
if c.VBoxManage == nil {
|
if c.VBoxManage == nil {
|
||||||
c.VBoxManage = make([][]string, 0)
|
c.VBoxManage = make([][]string, 0)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
var errs []error
|
||||||
|
var err error
|
||||||
|
var desiredMem uint64
|
||||||
|
|
||||||
|
for _, cmd := range c.VBoxManage {
|
||||||
|
if cmd[2] == "--memory" {
|
||||||
|
desiredMem, err = strconv.ParseUint(cmd[3], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Error parsing string: %s", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = common.AvailableMem(desiredMem); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Unavailable Resources: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
b.config.GuestAdditionsSHA256 = strings.ToLower(b.config.GuestAdditionsSHA256)
|
b.config.GuestAdditionsSHA256 = strings.ToLower(b.config.GuestAdditionsSHA256)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine if DiskSize is able to be allocated
|
||||||
|
if err = common.AvailableDisk(uint64(b.config.DiskSize)); err != nil {
|
||||||
|
errs = packer.MultiErrorAppend(errs,
|
||||||
|
fmt.Errorf("Unavailable Resources: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
// Warnings
|
// Warnings
|
||||||
if b.config.ShutdownCommand == "" {
|
if b.config.ShutdownCommand == "" {
|
||||||
warnings = append(warnings,
|
warnings = append(warnings,
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/mitchellh/packer/common"
|
||||||
"github.com/mitchellh/packer/template/interpolate"
|
"github.com/mitchellh/packer/template/interpolate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,5 +14,22 @@ type VMXConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *VMXConfig) Prepare(ctx *interpolate.Context) []error {
|
func (c *VMXConfig) Prepare(ctx *interpolate.Context) []error {
|
||||||
return nil
|
var errs []error
|
||||||
|
var err error
|
||||||
|
var desiredMem uint64
|
||||||
|
|
||||||
|
for k, v := range c.VMXData {
|
||||||
|
if k == "memsize" {
|
||||||
|
desiredMem, err = strconv.ParseUint(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Error parsing string: %s", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = common.AvailableMem(desiredMem); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Unavailable Resources: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,6 +171,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine if DiskSize is able to be allocated
|
||||||
|
if err = common.AvailableDisk(uint64(b.config.DiskSize)); err != nil {
|
||||||
|
errs = packer.MultiErrorAppend(errs,
|
||||||
|
fmt.Errorf("Unavailable Resources: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
// Warnings
|
// Warnings
|
||||||
if b.config.ShutdownCommand == "" {
|
if b.config.ShutdownCommand == "" {
|
||||||
warnings = append(warnings,
|
warnings = append(warnings,
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
sigar "github.com/cloudfoundry/gosigar"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AvailableMem(desired uint64) error {
|
||||||
|
free := freeMem()
|
||||||
|
if desired > free {
|
||||||
|
return fmt.Errorf("RAM - Requested - %dMB - Available %dMB", desired, free)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func freeMem() uint64 {
|
||||||
|
mem := sigar.Mem{}
|
||||||
|
mem.Get()
|
||||||
|
return (mem.Free / 1024 / 1024)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AvailableDisk(desired uint64) error {
|
||||||
|
free := freeDisk()
|
||||||
|
if desired > free {
|
||||||
|
return fmt.Errorf("Disk - Requested - %dMB - Available %dMB", desired, free)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func freeDisk() uint64 {
|
||||||
|
disk := sigar.FileSystemUsage{}
|
||||||
|
workingDirectory, _ := os.Getwd()
|
||||||
|
disk.Get(workingDirectory)
|
||||||
|
return (disk.Avail / 1024)
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
func AvailableMem(desired uint64) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func AvailableDisk(desired uint64) error {
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue