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.