From c4439aba82541e3ec8830eebe44c078299b4b70a Mon Sep 17 00:00:00 2001 From: James Nugent Date: Wed, 24 May 2017 18:44:35 -0500 Subject: [PATCH] builder/vmware: Add vmx_remove_ethernet_interfaces This commit adds a new option, `vmx_remove_ethernet_interfaces`, to both of the VMWare builders. This is useful when building Vagrant boxes, since Vagrant now produces output such as: ``` WARNING: The VMX file for this box contains a setting that is automatically overwritten by Vagrant when started. Vagrant will stop overwriting this setting in an upcoming release which may pre vent proper networking setup. Below is the detected VMX setting: ethernet0.pcislotnumber = "33" If networking fails to properly configure, it may require this VMX setting. It can be manually applied via the Vagrantfile: Vagrant.configure(2) do |config| config.vm.provider :vmware_fusion do |vmware| vmware.vmx["ethernet0.pcislotnumber"] = "33" end end ``` This can be avoided entirely by removing the ethernet adapters from the VMX file prior to packaging as a Vagrant box, in which case adapters are created as expected according to the Vagrantfile specification. --- builder/vmware/common/step_clean_vmx.go | 14 +++- builder/vmware/common/step_clean_vmx_test.go | 65 +++++++++++++++++++ builder/vmware/common/vmx_config.go | 5 +- builder/vmware/iso/builder.go | 4 +- builder/vmware/vmx/builder.go | 4 +- .../source/docs/builders/vmware-iso.html.md | 5 ++ .../source/docs/builders/vmware-vmx.html.md | 5 ++ 7 files changed, 97 insertions(+), 5 deletions(-) diff --git a/builder/vmware/common/step_clean_vmx.go b/builder/vmware/common/step_clean_vmx.go index 816a353b6..d016f35a3 100644 --- a/builder/vmware/common/step_clean_vmx.go +++ b/builder/vmware/common/step_clean_vmx.go @@ -19,7 +19,9 @@ import ( // // Produces: // -type StepCleanVMX struct{} +type StepCleanVMX struct { + RemoveEthernetInterfaces bool +} func (s StepCleanVMX) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) @@ -60,6 +62,16 @@ func (s StepCleanVMX) Run(state multistep.StateBag) multistep.StepAction { ui.Message("Disabling VNC server...") vmxData["remotedisplay.vnc.enabled"] = "FALSE" + if s.RemoveEthernetInterfaces { + ui.Message("Removing Ethernet Interfaces...") + for k := range vmxData { + if strings.HasPrefix(k, "ethernet") { + log.Printf("Deleting key: %s", k) + delete(vmxData, k) + } + } + } + // Rewrite the VMX if err := WriteVMX(vmxPath, vmxData); err != nil { state.Put("error", fmt.Errorf("Error writing VMX: %s", err)) diff --git a/builder/vmware/common/step_clean_vmx_test.go b/builder/vmware/common/step_clean_vmx_test.go index ea30fb54a..aad39e8b0 100644 --- a/builder/vmware/common/step_clean_vmx_test.go +++ b/builder/vmware/common/step_clean_vmx_test.go @@ -128,6 +128,61 @@ func TestStepCleanVMX_isoPath(t *testing.T) { } } +func TestStepCleanVMX_ethernet(t *testing.T) { + state := testState(t) + step := &StepCleanVMX{ + RemoveEthernetInterfaces: true, + } + + vmxPath := testVMXFile(t) + defer os.Remove(vmxPath) + if err := ioutil.WriteFile(vmxPath, []byte(testVMXEthernet), 0644); err != nil { + t.Fatalf("err: %s", err) + } + + state.Put("vmx_path", vmxPath) + + // Test the run + if action := step.Run(state); action != multistep.ActionContinue { + t.Fatalf("bad action: %#v", action) + } + if _, ok := state.GetOk("error"); ok { + t.Fatal("should NOT have error") + } + + // Test the resulting data + vmxContents, err := ioutil.ReadFile(vmxPath) + if err != nil { + t.Fatalf("err: %s", err) + } + vmxData := ParseVMX(string(vmxContents)) + + cases := []struct { + Key string + Value string + }{ + {"ethernet0.addresstype", ""}, + {"ethernet0.bsdname", ""}, + {"ethernet0.connectiontype", ""}, + {"ethernet1.addresstype", ""}, + {"ethernet1.bsdname", ""}, + {"ethernet1.connectiontype", ""}, + {"foo", "bar"}, + } + + for _, tc := range cases { + if tc.Value == "" { + if _, ok := vmxData[tc.Key]; ok { + t.Fatalf("should not have key: %s", tc.Key) + } + } else { + if vmxData[tc.Key] != tc.Value { + t.Fatalf("bad: %s %#v", tc.Key, vmxData[tc.Key]) + } + } + } +} + const testVMXFloppyPath = ` floppy0.present = "TRUE" floppy0.filetype = "file" @@ -139,3 +194,13 @@ ide0:0.filename = "foo" ide0:1.filename = "bar" foo = "bar" ` + +const testVMXEthernet = ` +ethernet0.addresstype = "generated" +ethernet0.bsdname = "en0" +ethernet0.connectiontype = "nat" +ethernet1.addresstype = "generated" +ethernet1.bsdname = "en1" +ethernet1.connectiontype = "nat" +foo = "bar" +` diff --git a/builder/vmware/common/vmx_config.go b/builder/vmware/common/vmx_config.go index c8f19fa0d..2f6d9333f 100644 --- a/builder/vmware/common/vmx_config.go +++ b/builder/vmware/common/vmx_config.go @@ -5,8 +5,9 @@ import ( ) type VMXConfig struct { - VMXData map[string]string `mapstructure:"vmx_data"` - VMXDataPost map[string]string `mapstructure:"vmx_data_post"` + VMXData map[string]string `mapstructure:"vmx_data"` + VMXDataPost map[string]string `mapstructure:"vmx_data_post"` + VMXRemoveEthernet bool `mapstructure:"vmx_remove_ethernet_interfaces"` } func (c *VMXConfig) Prepare(ctx *interpolate.Context) []error { diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 1f78944b7..42038b96a 100644 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -298,7 +298,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe CustomData: b.config.VMXDataPost, SkipFloppy: true, }, - &vmwcommon.StepCleanVMX{}, + &vmwcommon.StepCleanVMX{ + RemoveEthernetInterfaces: b.config.VMXConfig.VMXRemoveEthernet, + }, &StepUploadVMX{ RemoteType: b.config.RemoteType, }, diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index 6576db462..c5c1f10b7 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -119,7 +119,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe CustomData: b.config.VMXDataPost, SkipFloppy: true, }, - &vmwcommon.StepCleanVMX{}, + &vmwcommon.StepCleanVMX{ + RemoveEthernetInterfaces: b.config.VMXConfig.VMXRemoveEthernet, + }, } // Run the steps. diff --git a/website/source/docs/builders/vmware-iso.html.md b/website/source/docs/builders/vmware-iso.html.md index 377ab9018..e7da246e5 100644 --- a/website/source/docs/builders/vmware-iso.html.md +++ b/website/source/docs/builders/vmware-iso.html.md @@ -278,6 +278,11 @@ builder. except that it is run after the virtual machine is shutdown, and before the virtual machine is exported. +- `vmx_remove_ethernet_interfaces` (boolean) - Remove all ethernet interfaces from + the VMX file after building. This is for advanced users who understand the + ramifications, but is useful for building Vagrant boxes since Vagrant will + create ethernet interfaces when provisioning a box. + - `vmx_template_path` (string) - Path to a [configuration template](/docs/templates/engine.html) that defines the contents of the virtual machine VMX file for VMware. This is for **advanced diff --git a/website/source/docs/builders/vmware-vmx.html.md b/website/source/docs/builders/vmware-vmx.html.md index 53d884165..8c885c653 100644 --- a/website/source/docs/builders/vmware-vmx.html.md +++ b/website/source/docs/builders/vmware-vmx.html.md @@ -163,6 +163,11 @@ builder. except that it is run after the virtual machine is shutdown, and before the virtual machine is exported. +- `vmx_remove_ethernet_interfaces` (boolean) - Remove all ethernet interfaces from + the VMX file after building. This is for advanced users who understand the + ramifications, but is useful for building Vagrant boxes since Vagrant will + create ethernet interfaces when provisioning a box. + - `vnc_bind_address` (string / IP address) - The IP address that should be binded to for VNC. By default packer will use 127.0.0.1 for this.