From 22d4b7e7330a6d1fb56c5118fab2e396e8631a02 Mon Sep 17 00:00:00 2001 From: Michael Kuzmin Date: Sun, 2 Jul 2017 01:34:29 +0300 Subject: [PATCH 1/6] rename file --- step_configure_hw.go => step_hardware.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename step_configure_hw.go => step_hardware.go (100%) diff --git a/step_configure_hw.go b/step_hardware.go similarity index 100% rename from step_configure_hw.go rename to step_hardware.go From a03c91e73a7b3449a10203037eedeb952ace7963 Mon Sep 17 00:00:00 2001 From: Michael Kuzmin Date: Sun, 2 Jul 2017 01:34:50 +0300 Subject: [PATCH 2/6] Refactor hardware customization --- builder.go | 4 ++-- config.go | 14 +------------ config_test.go | 14 ------------- step_hardware.go | 53 ++++++++++++++---------------------------------- 4 files changed, 18 insertions(+), 67 deletions(-) diff --git a/builder.go b/builder.go index 479c4c2f0..f3404f1ba 100644 --- a/builder.go +++ b/builder.go @@ -70,8 +70,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &StepCloneVM{ config: b.config, }, - &StepConfigureHW{ - config: b.config, + &StepConfigureHardware{ + config: &b.config.HardwareConfig, }, &StepRun{}, &communicator.StepConnect{ diff --git a/config.go b/config.go index 246447d30..80405a5c5 100644 --- a/config.go +++ b/config.go @@ -8,7 +8,6 @@ import ( "github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" - "strconv" "time" ) @@ -32,8 +31,7 @@ type Config struct { LinkedClone bool `mapstructure:"linked_clone"` // Customization - CPUs string `mapstructure:"CPUs"` - RAM string `mapstructure:"RAM"` + HardwareConfig `mapstructure:",squash"` // Provisioning communicator.Config `mapstructure:",squash"` @@ -83,16 +81,6 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("vSphere host is required")) } - if c.CPUs != "" { - if _, err := strconv.Atoi(c.CPUs); err != nil { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Invalid number of CPU sockets")) - } - } - if c.RAM != "" { - if _, err := strconv.Atoi(c.RAM); err != nil { - errs = packer.MultiErrorAppend(errs, fmt.Errorf("Invalid number for RAM")) - } - } if c.RawShutdownTimeout != "" { timeout, err := time.ParseDuration(c.RawShutdownTimeout) if err != nil { diff --git a/config_test.go b/config_test.go index 3188dfadf..46f80662b 100644 --- a/config_test.go +++ b/config_test.go @@ -11,20 +11,6 @@ func TestMinimalConfig(t *testing.T) { testConfigOk(t, warns, errs) } -func TestInvalidCpu(t *testing.T) { - raw := minimalConfig() - raw["CPUs"] = "string" - _, warns, errs := NewConfig(raw) - testConfigErr(t, warns, errs) -} - -func TestInvalidRam(t *testing.T) { - raw := minimalConfig() - raw["RAM"] = "string" - _, warns, errs := NewConfig(raw) - testConfigErr(t, warns, errs) -} - func TestTimeout(t *testing.T) { raw := minimalConfig() raw["shutdown_timeout"] = "3m" diff --git a/step_hardware.go b/step_hardware.go index 4b5f7d2e2..38771c332 100644 --- a/step_hardware.go +++ b/step_hardware.go @@ -3,53 +3,32 @@ package main import ( "github.com/mitchellh/multistep" "github.com/hashicorp/packer/packer" - "strconv" "github.com/vmware/govmomi/vim25/types" "context" "github.com/vmware/govmomi/object" ) -type StepConfigureHW struct{ - config *Config +type HardwareConfig struct { + CPUs int32 `mapstructure:"CPUs"` + RAM int64 `mapstructure:"RAM"` } -type ConfigParametersFlag struct { - NumCPUsPtr *int32 - MemoryMBPtr *int64 +type StepConfigureHardware struct { + config *HardwareConfig } -func (s *StepConfigureHW) Run(state multistep.StateBag) multistep.StepAction { +func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepAction { vm := state.Get("vm").(*object.VirtualMachine) ctx := state.Get("ctx").(context.Context) - - var confSpec types.VirtualMachineConfigSpec - parametersFlag := ConfigParametersFlag{} - // configure HW - if s.config.CPUs != "" { - CPUs, err := strconv.Atoi(s.config.CPUs) - if err != nil { - state.Put("error", err) - return multistep.ActionHalt - } - - confSpec.NumCPUs = int32(CPUs) - parametersFlag.NumCPUsPtr = &(confSpec.NumCPUs) - } - if s.config.RAM != "" { - ram, err := strconv.Atoi(s.config.RAM) - if err != nil { - state.Put("error", err) - return multistep.ActionHalt - } - - confSpec.MemoryMB = int64(ram) - parametersFlag.MemoryMBPtr = &(confSpec.MemoryMB) - } - ui := state.Get("ui").(packer.Ui) - if parametersFlag != (ConfigParametersFlag{}) { - ui.Say("configuring virtual hardware...") - // Reconfigure hardware + + if *s.config != (HardwareConfig{}) { + ui.Say("Customizing hardware parameters...") + + var confSpec types.VirtualMachineConfigSpec + confSpec.NumCPUs = s.config.CPUs + confSpec.MemoryMB = s.config.RAM + task, err := vm.Reconfigure(ctx, confSpec) if err != nil { state.Put("error", err) @@ -60,11 +39,9 @@ func (s *StepConfigureHW) Run(state multistep.StateBag) multistep.StepAction { state.Put("error", err) return multistep.ActionHalt } - } else { - ui.Say("skipping the virtual hardware configration...") } return multistep.ActionContinue } -func (s *StepConfigureHW) Cleanup(multistep.StateBag) {} +func (s *StepConfigureHardware) Cleanup(multistep.StateBag) {} From 3991b0e95cb786803c0ca836a8f1e444f2114631 Mon Sep 17 00:00:00 2001 From: Michael Kuzmin Date: Sat, 1 Jul 2017 23:43:40 +0300 Subject: [PATCH 3/6] Add 'CPU_reservation' parameter --- README.md | 2 ++ step_hardware.go | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bc51a0807..3fd9f9ec0 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ Destination: Hardware customization: * `CPUs` - number of CPU sockets. Inherited from source VM by default. +* `CPU_reservation` - Amount of reserved CPU resources in MHz. Inherited from source VM by default. * `RAM` - Amount of RAM in megabytes. Inherited from source VM by default. Provisioning: @@ -98,6 +99,7 @@ Post-processing: "linked_clone": true, "CPUs": 2, + "CPU_reservation": 1000, "RAM": 8192, "ssh_username": "root", diff --git a/step_hardware.go b/step_hardware.go index 38771c332..2a1ea04af 100644 --- a/step_hardware.go +++ b/step_hardware.go @@ -9,8 +9,9 @@ import ( ) type HardwareConfig struct { - CPUs int32 `mapstructure:"CPUs"` - RAM int64 `mapstructure:"RAM"` + CPUs int32 `mapstructure:"CPUs"` + CPUReservation int64 `mapstructure:"CPU_reservation"` + RAM int64 `mapstructure:"RAM"` } type StepConfigureHardware struct { @@ -29,6 +30,10 @@ func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepActi confSpec.NumCPUs = s.config.CPUs confSpec.MemoryMB = s.config.RAM + var cpuSpec types.ResourceAllocationInfo + cpuSpec.Reservation = s.config.CPUReservation + confSpec.CpuAllocation = &cpuSpec + task, err := vm.Reconfigure(ctx, confSpec) if err != nil { state.Put("error", err) From d2dacfbc6b1cafe25abc8e917cbe9eb7edc5f317 Mon Sep 17 00:00:00 2001 From: Michael Kuzmin Date: Sat, 1 Jul 2017 23:52:35 +0300 Subject: [PATCH 4/6] Add 'CPU_limit' parameter --- README.md | 2 ++ step_hardware.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 3fd9f9ec0..7071f9b51 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ Destination: Hardware customization: * `CPUs` - number of CPU sockets. Inherited from source VM by default. * `CPU_reservation` - Amount of reserved CPU resources in MHz. Inherited from source VM by default. +* `CPU_limit` - Upper limit of available CPU resources in MHz. Inherited from source VM by default, set to `-1` for reset. * `RAM` - Amount of RAM in megabytes. Inherited from source VM by default. Provisioning: @@ -100,6 +101,7 @@ Post-processing: "CPUs": 2, "CPU_reservation": 1000, + "CPU_limit": 2000, "RAM": 8192, "ssh_username": "root", diff --git a/step_hardware.go b/step_hardware.go index 2a1ea04af..a420f122e 100644 --- a/step_hardware.go +++ b/step_hardware.go @@ -11,6 +11,7 @@ import ( type HardwareConfig struct { CPUs int32 `mapstructure:"CPUs"` CPUReservation int64 `mapstructure:"CPU_reservation"` + CPULimit int64 `mapstructure:"CPU_limit"` RAM int64 `mapstructure:"RAM"` } @@ -32,6 +33,7 @@ func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepActi var cpuSpec types.ResourceAllocationInfo cpuSpec.Reservation = s.config.CPUReservation + cpuSpec.Limit = s.config.CPULimit confSpec.CpuAllocation = &cpuSpec task, err := vm.Reconfigure(ctx, confSpec) From 71c211fa0979cbeae0c4ab9550612aa099ff7c1b Mon Sep 17 00:00:00 2001 From: Michael Kuzmin Date: Sun, 2 Jul 2017 00:02:49 +0300 Subject: [PATCH 5/6] Add 'RAM_reservation' parameter --- README.md | 2 ++ step_hardware.go | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 7071f9b51..417b658e9 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Hardware customization: * `CPU_reservation` - Amount of reserved CPU resources in MHz. Inherited from source VM by default. * `CPU_limit` - Upper limit of available CPU resources in MHz. Inherited from source VM by default, set to `-1` for reset. * `RAM` - Amount of RAM in megabytes. Inherited from source VM by default. +* `RAM_reservation` - Amount of reserved RAM in MB. Inherited from source VM by default. Provisioning: * `ssh_username` - [**mandatory**] username in guest OS. @@ -103,6 +104,7 @@ Post-processing: "CPU_reservation": 1000, "CPU_limit": 2000, "RAM": 8192, + "RAM_reservation": 2048, "ssh_username": "root", "ssh_password": "{{user `guest_password`}}", diff --git a/step_hardware.go b/step_hardware.go index a420f122e..5675ab4f5 100644 --- a/step_hardware.go +++ b/step_hardware.go @@ -13,6 +13,7 @@ type HardwareConfig struct { CPUReservation int64 `mapstructure:"CPU_reservation"` CPULimit int64 `mapstructure:"CPU_limit"` RAM int64 `mapstructure:"RAM"` + RAMReservation int64 `mapstructure:"RAM_reservation"` } type StepConfigureHardware struct { @@ -36,6 +37,10 @@ func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepActi cpuSpec.Limit = s.config.CPULimit confSpec.CpuAllocation = &cpuSpec + var ramSpec types.ResourceAllocationInfo + ramSpec.Reservation = s.config.RAMReservation + confSpec.MemoryAllocation = &ramSpec + task, err := vm.Reconfigure(ctx, confSpec) if err != nil { state.Put("error", err) From 5987795a23aa94dfc9151e457ff0b3f3188dab5d Mon Sep 17 00:00:00 2001 From: Michael Kuzmin Date: Sun, 2 Jul 2017 00:50:01 +0300 Subject: [PATCH 6/6] Add 'RAM_reserve_all' parameter --- README.md | 1 + config.go | 2 ++ config_test.go | 16 ++++++++++++---- step_hardware.go | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 417b658e9..9362a2797 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ Hardware customization: * `CPU_limit` - Upper limit of available CPU resources in MHz. Inherited from source VM by default, set to `-1` for reset. * `RAM` - Amount of RAM in megabytes. Inherited from source VM by default. * `RAM_reservation` - Amount of reserved RAM in MB. Inherited from source VM by default. +* `RAM_reserve_all` - Reserve all available RAM (bool). `false` by default. Cannot be used together with `RAM_reservation`. Provisioning: * `ssh_username` - [**mandatory**] username in guest OS. diff --git a/config.go b/config.go index 80405a5c5..4f1c22968 100644 --- a/config.go +++ b/config.go @@ -81,6 +81,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, fmt.Errorf("vSphere host is required")) } + errs = packer.MultiErrorAppend(errs, c.HardwareConfig.Prepare()...) + if c.RawShutdownTimeout != "" { timeout, err := time.ParseDuration(c.RawShutdownTimeout) if err != nil { diff --git a/config_test.go b/config_test.go index 46f80662b..4281ef086 100644 --- a/config_test.go +++ b/config_test.go @@ -21,6 +21,14 @@ func TestTimeout(t *testing.T) { } } +func TestRAMReservation(t *testing.T) { + raw := minimalConfig() + raw["RAM_reservation"] = 1000 + raw["RAM_reserve_all"] = true + _, warns, err := NewConfig(raw) + testConfigErr(t, warns, err) +} + func minimalConfig() map[string]interface{} { return map[string]interface{}{ "vcenter_server": "vcenter.domain.local", @@ -36,18 +44,18 @@ func minimalConfig() map[string]interface{} { func testConfigOk(t *testing.T, warns []string, err error) { if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) + t.Fatalf("Should be no warnings: %#v", warns) } if err != nil { - t.Fatalf("bad: %s", err) + t.Fatalf("Unexpected error: %s", err) } } func testConfigErr(t *testing.T, warns []string, err error) { if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) + t.Fatalf("Should be no warnings: %#v", warns) } if err == nil { - t.Fatal("should error") + t.Fatal("An error is not raised") } } diff --git a/step_hardware.go b/step_hardware.go index 5675ab4f5..076fa1c73 100644 --- a/step_hardware.go +++ b/step_hardware.go @@ -6,6 +6,7 @@ import ( "github.com/vmware/govmomi/vim25/types" "context" "github.com/vmware/govmomi/object" + "fmt" ) type HardwareConfig struct { @@ -14,6 +15,17 @@ type HardwareConfig struct { CPULimit int64 `mapstructure:"CPU_limit"` RAM int64 `mapstructure:"RAM"` RAMReservation int64 `mapstructure:"RAM_reservation"` + RAMReserveAll bool `mapstructure:"RAM_reserve_all"` +} + +func (c *HardwareConfig) Prepare() []error { + var errs []error + + if c.RAMReservation > 0 && c.RAMReserveAll != false { + errs = append(errs, fmt.Errorf("'RAM_reservation' and 'RAM_reserve_all' cannot be used together")) + } + + return errs } type StepConfigureHardware struct { @@ -41,6 +53,8 @@ func (s *StepConfigureHardware) Run(state multistep.StateBag) multistep.StepActi ramSpec.Reservation = s.config.RAMReservation confSpec.MemoryAllocation = &ramSpec + confSpec.MemoryReservationLockedToMax = &s.config.RAMReserveAll + task, err := vm.Reconfigure(ctx, confSpec) if err != nil { state.Put("error", err)