Merge pull request #7066 from arizvisa/vmware-temporary-devices

Add a "temporaryDevices" key to the statebag for the VMware builder
This commit is contained in:
Megan Marsh 2018-12-04 10:34:37 -08:00 committed by GitHub
commit 152f6fed8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 23 deletions

View File

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"log"
"regexp"
"strings"
"github.com/hashicorp/packer/helper/multistep"
@ -37,40 +36,85 @@ func (s StepCleanVMX) Run(_ context.Context, state multistep.StateBag) multistep
return multistep.ActionHalt
}
// Delete the floppy0 entries so the floppy is no longer mounted
ui.Message("Unmounting floppy from VMX...")
for k := range vmxData {
if strings.HasPrefix(k, "floppy0.") {
log.Printf("Deleting key: %s", k)
delete(vmxData, k)
// Grab our list of devices added during the build out of the statebag
for _, device := range state.Get("temporaryDevices").([]string) {
// Instead of doing this in one pass which would be more efficient,
// we do it per device-type so that the logic appears to be the same
// as the prior implementation.
// Walk through all the devices that were temporarily added and figure
// out which type it is in order to figure out how to disable it.
// Right now only floppy, cdrom devices, ethernet, and devices that use
// ".present" are supported.
if strings.HasPrefix(device, "floppy") {
// We can identify a floppy device because it begins with "floppy"
ui.Message(fmt.Sprintf("Unmounting %s from VMX...", device))
// Delete the floppy%d entries so the floppy is no longer mounted
for k := range vmxData {
if strings.HasPrefix(k, fmt.Sprintf("%s.", device)) {
log.Printf("Deleting key for floppy device: %s", k)
delete(vmxData, k)
}
}
vmxData[fmt.Sprintf("%s.present", device)] = "FALSE"
} else if strings.HasPrefix(vmxData[fmt.Sprintf("%s.devicetype", device)], "cdrom-") {
// We can identify something is a cdrom if it has a ".devicetype"
// attribute that begins with "cdrom-"
ui.Message(fmt.Sprintf("Detaching ISO from CD-ROM device %s...", device))
// Simply turn the CDROM device into a native cdrom instead of an iso
vmxData[fmt.Sprintf("%s.devicetype", device)] = "cdrom-raw"
vmxData[fmt.Sprintf("%s.filename", device)] = "auto detect"
vmxData[fmt.Sprintf("%s.clientdevice", device)] = "TRUE"
} else if strings.HasPrefix(device, "ethernet") && s.RemoveEthernetInterfaces {
// We can identify an ethernet device because it begins with "ethernet"
// Although we're supporting this, as of now it's not in use due
// to these interfaces not ever being added to the "temporaryDevices" statebag.
ui.Message(fmt.Sprintf("Removing %s interface...", device))
// Delete the ethernet%d entries so the ethernet interface is removed.
// This corresponds to the same logic defined below.
for k := range vmxData {
if strings.HasPrefix(k, fmt.Sprintf("%s.", device)) {
log.Printf("Deleting key for ethernet device: %s", k)
delete(vmxData, k)
}
}
} else {
// First check to see if we can simply disable the device
if _, ok := vmxData[fmt.Sprintf("%s.present", device)]; ok {
ui.Message(fmt.Sprintf("Disabling device %s of an unknown device type...", device))
vmxData[fmt.Sprintf("%s.present", device)] = "FALSE"
} else {
// Okay, so this wasn't so simple. Let's just log info about the
// device and not tamper with any of its keys
log.Printf("Refusing to remove device due to being of an unsupported type: %s\n", device)
for k := range vmxData {
if strings.HasPrefix(k, fmt.Sprintf("%s.", device)) {
log.Printf("Leaving unsupported device key: %s\n", k)
}
}
}
}
}
vmxData["floppy0.present"] = "FALSE"
devRe := regexp.MustCompile(`^(ide|sata)\d:\d\.`)
for k, v := range vmxData {
ide := devRe.FindString(k)
if ide == "" || v != "cdrom-image" {
continue
}
ui.Message("Detaching ISO from CD-ROM device...")
vmxData[ide+"devicetype"] = "cdrom-raw"
vmxData[ide+"filename"] = "auto detect"
vmxData[ide+"clientdevice"] = "TRUE"
}
// Disable the VNC server if necessary
if s.VNCEnabled {
ui.Message("Disabling VNC server...")
vmxData["remotedisplay.vnc.enabled"] = "FALSE"
}
// Disable any ethernet devices if necessary
if s.RemoveEthernetInterfaces {
ui.Message("Removing Ethernet Interfaces...")
for k := range vmxData {
if strings.HasPrefix(k, "ethernet") {
log.Printf("Deleting key: %s", k)
log.Printf("Deleting key for ethernet device: %s", k)
delete(vmxData, k)
}
}

View File

@ -40,8 +40,12 @@ func TestStepCleanVMX_floppyPath(t *testing.T) {
t.Fatalf("err: %s", err)
}
// Set the path to the temporary vmx
state.Put("vmx_path", vmxPath)
// Add the floppy device to the list of temporary build devices
state.Put("temporaryDevices", []string{"floppy0"})
// Test the run
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
@ -89,8 +93,12 @@ func TestStepCleanVMX_isoPath(t *testing.T) {
t.Fatalf("err: %s", err)
}
// Set the path to the temporary vmx
state.Put("vmx_path", vmxPath)
// Add the cdrom device to the list of temporary build devices
state.Put("temporaryDevices", []string{"ide0:0"})
// Test the run
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
@ -141,8 +149,12 @@ func TestStepCleanVMX_ethernet(t *testing.T) {
t.Fatalf("err: %s", err)
}
// Set the path to the temporary vmx
state.Put("vmx_path", vmxPath)
// TODO: Add the ethernet devices to the list of temporary build devices
// state.Put("temporaryDevices", []string{"ethernet0", "ethernet1"})
// Test the run
if action := step.Run(context.Background(), state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)

View File

@ -65,13 +65,22 @@ func (s *StepConfigureVMX) Run(_ context.Context, state multistep.StateBag) mult
// Set a floppy disk, but only if we should
if !s.SkipFloppy {
// Grab list of temporary builder devices so we can append the floppy to it
tmpBuildDevices := state.Get("temporaryDevices").([]string)
// Set a floppy disk if we have one
if floppyPathRaw, ok := state.GetOk("floppy_path"); ok {
log.Println("Floppy path present, setting in VMX")
vmxData["floppy0.present"] = "TRUE"
vmxData["floppy0.filetype"] = "file"
vmxData["floppy0.filename"] = floppyPathRaw.(string)
// Add it to our list of build devices to later remove
tmpBuildDevices = append(tmpBuildDevices, "floppy0")
}
// Build the list back in our statebag
state.Put("temporaryDevices", tmpBuildDevices)
}
// If the build is taking place on a remote ESX server, the displayName

View File

@ -15,5 +15,6 @@ func testState(t *testing.T) multistep.StateBag {
Reader: new(bytes.Buffer),
Writer: new(bytes.Buffer),
})
state.Put("temporaryDevices", []string{})
return state
}

View File

@ -65,6 +65,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
state.Put("ui", ui)
state.Put("sshConfig", &b.config.SSHConfig)
state.Put("driverConfig", &b.config.DriverConfig)
state.Put("temporaryDevices", []string{}) // Devices (in .vmx) created by packer during building
steps := []multistep.Step{
&vmwcommon.StepPrepareTools{

View File

@ -243,6 +243,13 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
return multistep.ActionHalt
}
/// Now that we figured out the CDROM device to add, store it
/// to the list of temporary build devices in our statebag
tmpBuildDevices := state.Get("temporaryDevices").([]string)
tmpCdromDevice := fmt.Sprintf("%s0:%s", templateData.CDROMType, templateData.CDROMType_PrimarySecondary)
tmpBuildDevices = append(tmpBuildDevices, tmpCdromDevice)
state.Put("temporaryDevices", tmpBuildDevices)
/// Assign the network adapter type into the template if one was specified.
network_adapter := strings.ToLower(config.HWConfig.NetworkAdapterType)
if network_adapter != "" {

View File

@ -67,6 +67,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
state.Put("ui", ui)
state.Put("sshConfig", &b.config.SSHConfig)
state.Put("driverConfig", &b.config.DriverConfig)
state.Put("temporaryDevices", []string{}) // Devices (in .vmx) created by packer during building
// Build the steps.
steps := []multistep.Step{