From ac2ddbcbf5e2f0c202e43a006d20e6ed95f6bb97 Mon Sep 17 00:00:00 2001 From: Ali Rizvi-Santiago Date: Tue, 20 Feb 2018 19:42:45 -0600 Subject: [PATCH] Fixes the assumption that all the VMware builder's drivers will implement a network mapper for mapping a network name to it's corresponding device. The ESX5 driver doesn't have a way of mapping the network name to its device name because a .vmx template uses different field names for it and so packer let's ESX handle filling this in. This patch will check to see if the driver that packer determines is missing a NetworkMapper implementation (by checking for nil). If it is, then fall back to using "nat" despite ESX not using the network type at all. This is what packer did prior to exposing the network type to the user back in version 1.1.3. This closes issue #5916. --- builder/vmware/iso/driver_esx5.go | 23 ++++++++++++++ builder/vmware/iso/step_create_vmx.go | 45 ++++++++++++++++++--------- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/builder/vmware/iso/driver_esx5.go b/builder/vmware/iso/driver_esx5.go index 1dc352999..47fe70666 100644 --- a/builder/vmware/iso/driver_esx5.go +++ b/builder/vmware/iso/driver_esx5.go @@ -147,6 +147,29 @@ func (d *ESX5Driver) ToolsInstall() error { } func (d *ESX5Driver) Verify() error { + // Ensure that NetworkMapper is nil, since the mapping of device<->network + // is handled by ESX and thus can't be performed by packer unless we + // query things. + + // FIXME: If we want to expose the network devices to the user, then we can + // probably use esxcli to enumerate the portgroup and switchId + d.base.NetworkMapper = nil + + // Be safe/friendly and overwrite the rest of the utility functions with + // log functions despite the fact that these shouldn't be called anyways. + d.base.DhcpLeasesPath = func(device string) string { + log.Printf("Unexpected error, ESX5 driver attempted to call DhcpLeasesPath(%#v)\n", device) + return "" + } + d.base.DhcpConfPath = func(device string) string { + log.Printf("Unexpected error, ESX5 driver attempted to call DhcpConfPath(%#v)\n", device) + return "" + } + d.base.VmnetnatConfPath = func(device string) string { + log.Printf("Unexpected error, ESX5 driver attempted to call VmnetnatConfPath(%#v)\n", device) + return "" + } + checks := []func() error{ d.connect, d.checkSystemVersion, diff --git a/builder/vmware/iso/step_create_vmx.go b/builder/vmware/iso/step_create_vmx.go index ffff9d999..c231cfe8a 100644 --- a/builder/vmware/iso/step_create_vmx.go +++ b/builder/vmware/iso/step_create_vmx.go @@ -462,26 +462,41 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist network := config.Network driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver() - // read netmap config - netmap, err := driver.NetworkMapper() - if err != nil { - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt - } + // check to see if the driver implements a network mapper for mapping + // the network-type to its device-name. + if driver.NetworkMapper != nil { - // try and convert the specified network to a device - device, err := netmap.NameIntoDevice(network) + // read network map configuration into a NetworkNameMapper. + netmap, err := driver.NetworkMapper() + if err != nil { + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } - // success. so we know that it's an actual network type inside netmap.conf - if err == nil { - templateData.Network_Type = network - templateData.Network_Device = device - // we were unable to find the type, so assume it's a custom network device. + // try and convert the specified network to a device. + device, err := netmap.NameIntoDevice(network) + + // success. so we know that it's an actual network type inside netmap.conf + if err == nil { + templateData.Network_Type = network + templateData.Network_Device = device + + // otherwise, we were unable to find the type, so assume its a custom device. + } else { + templateData.Network_Type = "custom" + templateData.Network_Device = network + } + + // if NetworkMapper is nil, then we're using something like ESX, so fall + // back to the previous logic of using "nat" despite it not mattering to ESX. } else { - templateData.Network_Type = "custom" + templateData.Network_Type = "nat" templateData.Network_Device = network + + network = "nat" } + // store the network so that we can later figure out what ip address to bind to state.Put("vmnetwork", network)