diff --git a/builder/virtualbox/common/vboxmanage_config.go b/builder/virtualbox/common/vboxmanage_config.go index 1670aee0d..b243400a1 100644 --- a/builder/virtualbox/common/vboxmanage_config.go +++ b/builder/virtualbox/common/vboxmanage_config.go @@ -1,6 +1,10 @@ package common import ( + "fmt" + "strconv" + + "github.com/mitchellh/packer/common" "github.com/mitchellh/packer/template/interpolate" ) @@ -11,7 +15,25 @@ type VBoxManageConfig struct { func (c *VBoxManageConfig) Prepare(ctx *interpolate.Context) []error { if c.VBoxManage == nil { c.VBoxManage = make([][]string, 0) + 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 nil + return errs } diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index b8b08959a..c30fd83ee 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -152,6 +152,12 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { 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 if b.config.ShutdownCommand == "" { warnings = append(warnings, diff --git a/builder/vmware/common/vmx_config.go b/builder/vmware/common/vmx_config.go index aac16d1e0..9b3162382 100644 --- a/builder/vmware/common/vmx_config.go +++ b/builder/vmware/common/vmx_config.go @@ -1,6 +1,10 @@ package common import ( + "fmt" + "strconv" + + "github.com/mitchellh/packer/common" "github.com/mitchellh/packer/template/interpolate" ) @@ -9,6 +13,26 @@ type VMXConfig struct { VMXDataPost map[string]string `mapstructure:"vmx_data_post"` } -func (c *VMXConfig) Prepare(ctx *interpolate.Context) []error { - return nil +func (c *VMXConfig) Prepare(ctx *interpolate.Context, remoteType string) []error { + var errs []error + var err error + var desiredMem uint64 + + // Validate memory resources, only on local hosts + if remoteType == "" { + 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 } diff --git a/builder/vmware/common/vmx_config_test.go b/builder/vmware/common/vmx_config_test.go index 4b8172cb0..0278ae74c 100644 --- a/builder/vmware/common/vmx_config_test.go +++ b/builder/vmware/common/vmx_config_test.go @@ -11,7 +11,7 @@ func TestVMXConfigPrepare(t *testing.T) { "two": "bar", } - errs := c.Prepare(testConfigTemplate(t)) + errs := c.Prepare(testConfigTemplate(t), "") if len(errs) > 0 { t.Fatalf("bad: %#v", errs) } diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 95395c73c..15ef41238 100755 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -93,7 +93,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ToolsConfig.Prepare(&b.config.ctx)...) - errs = packer.MultiErrorAppend(errs, b.config.VMXConfig.Prepare(&b.config.ctx)...) + errs = packer.MultiErrorAppend(errs, b.config.VMXConfig.Prepare(&b.config.ctx, b.config.RemoteType)...) if b.config.DiskName == "" { b.config.DiskName = "disk" @@ -171,6 +171,14 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } + // Determine if DiskSize is able to be allocated, only when running locally + if b.config.RemoteType == "" { + if err = common.AvailableDisk(uint64(b.config.DiskSize)); err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Unavailable Resources: %s", err)) + } + } + // Warnings if b.config.ShutdownCommand == "" { warnings = append(warnings, diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go index 4f93db9f3..87aad7d59 100644 --- a/builder/vmware/vmx/config.go +++ b/builder/vmware/vmx/config.go @@ -63,7 +63,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ToolsConfig.Prepare(&c.ctx)...) - errs = packer.MultiErrorAppend(errs, c.VMXConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.VMXConfig.Prepare(&c.ctx, c.RemoteType)...) if c.SourcePath == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("source_path is blank, but is required")) diff --git a/common/resources_linux.go b/common/resources_linux.go new file mode 100644 index 000000000..fd9b0cf16 --- /dev/null +++ b/common/resources_linux.go @@ -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) +} diff --git a/common/resources_universal.go b/common/resources_universal.go new file mode 100644 index 000000000..3ecc7d2e8 --- /dev/null +++ b/common/resources_universal.go @@ -0,0 +1,11 @@ +// +build !linux + +package common + +func AvailableMem(desired uint64) error { + return nil +} + +func AvailableDisk(desired uint64) error { + return nil +}