go fmt on builder/vmware/*

This commit is contained in:
Ali Rizvi-Santiago 2017-02-27 15:34:53 -06:00
parent 0d6cf7fac4
commit 884af69da1
8 changed files with 1075 additions and 833 deletions

View File

@ -1,19 +1,19 @@
package common
import (
"errors"
"bytes"
"errors"
"fmt"
"io/ioutil"
"log"
"net"
"os"
"os/exec"
"io/ioutil"
"regexp"
"runtime"
"strconv"
"strings"
"time"
"net"
"github.com/hashicorp/packer/helper/multistep"
)
@ -214,23 +214,27 @@ func compareVersions(versionFound string, versionWanted string, product string)
/// helper functions that read configuration information from a file
// read the network<->device configuration out of the specified path
func ReadNetmapConfig(path string) (NetworkMap,error) {
fd,err := os.Open(path)
if err != nil { return nil, err }
func ReadNetmapConfig(path string) (NetworkMap, error) {
fd, err := os.Open(path)
if err != nil {
return nil, err
}
defer fd.Close()
return ReadNetworkMap(fd)
}
// read the dhcp configuration out of the specified path
func ReadDhcpConfig(path string) (DhcpConfiguration,error) {
fd,err := os.Open(path)
if err != nil { return nil, err }
func ReadDhcpConfig(path string) (DhcpConfiguration, error) {
fd, err := os.Open(path)
if err != nil {
return nil, err
}
defer fd.Close()
return ReadDhcpConfiguration(fd)
}
// read the VMX configuration from the specified path
func readVMXConfig(path string) (map[string]string,error) {
func readVMXConfig(path string) (map[string]string, error) {
f, err := os.Open(path)
if err != nil {
return map[string]string{}, err
@ -245,7 +249,7 @@ func readVMXConfig(path string) (map[string]string,error) {
}
// read the connection type out of a vmx configuration
func readCustomDeviceName(vmxData map[string]string) (string,error) {
func readCustomDeviceName(vmxData map[string]string) (string, error) {
connectionType, ok := vmxData["ethernet0.connectiontype"]
if !ok || connectionType != "custom" {
@ -266,18 +270,20 @@ type VmwareDriver struct {
/// A driver must overload these in order to point to the correct
/// files so that the address detection (ip and ethernet) machinery
/// works.
DhcpLeasesPath func(string) string
DhcpConfPath func(string) string
DhcpLeasesPath func(string) string
DhcpConfPath func(string) string
VmnetnatConfPath func(string) string
NetmapConfPath func() string
NetmapConfPath func() string
}
func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string,error) {
func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string, error) {
vmxPath := state.Get("vmx_path").(string)
log.Println("Lookup up IP information...")
vmxData, err := readVMXConfig(vmxPath)
if err != nil { return "", err }
if err != nil {
return "", err
}
var ok bool
macAddress := ""
@ -287,40 +293,50 @@ func (d *VmwareDriver) GuestAddress(state multistep.StateBag) (string,error) {
}
}
res,err := net.ParseMAC(macAddress)
if err != nil { return "", err }
res, err := net.ParseMAC(macAddress)
if err != nil {
return "", err
}
return res.String(),nil
return res.String(), nil
}
func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string,error) {
func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string, error) {
// read netmap config
pathNetmap := d.NetmapConfPath()
if _, err := os.Stat(pathNetmap); err != nil {
return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap)
}
netmap,err := ReadNetmapConfig(pathNetmap)
if err != nil { return "",err }
netmap, err := ReadNetmapConfig(pathNetmap)
if err != nil {
return "", err
}
// convert the stashed network to a device
network := state.Get("vmnetwork").(string)
device,err := netmap.NameIntoDevice(network)
device, err := netmap.NameIntoDevice(network)
// we were unable to find the device, maybe it's a custom one...
// so, check to see if it's in the .vmx configuration
if err != nil || network == "custom" {
vmxPath := state.Get("vmx_path").(string)
vmxData, err := readVMXConfig(vmxPath)
if err != nil { return "", err }
if err != nil {
return "", err
}
device, err = readCustomDeviceName(vmxData)
if err != nil { return "", err }
if err != nil {
return "", err
}
}
// figure out our MAC address for looking up the guest address
MACAddress,err := d.GuestAddress(state)
if err != nil { return "", err }
MACAddress, err := d.GuestAddress(state)
if err != nil {
return "", err
}
// figure out the correct dhcp leases
dhcpLeasesPath := d.DhcpLeasesPath(device)
@ -382,29 +398,35 @@ func (d *VmwareDriver) GuestIP(state multistep.StateBag) (string,error) {
return curIp, nil
}
func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) {
func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string, error) {
// parse network<->device mapping
pathNetmap := d.NetmapConfPath()
if _, err := os.Stat(pathNetmap); err != nil {
return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap)
}
netmap,err := ReadNetmapConfig(pathNetmap)
if err != nil { return "",err }
netmap, err := ReadNetmapConfig(pathNetmap)
if err != nil {
return "", err
}
// convert network to name
network := state.Get("vmnetwork").(string)
device,err := netmap.NameIntoDevice(network)
device, err := netmap.NameIntoDevice(network)
// we were unable to find the device, maybe it's a custom one...
// so, check to see if it's in the .vmx configuration
if err != nil || network == "custom" {
vmxPath := state.Get("vmx_path").(string)
vmxData, err := readVMXConfig(vmxPath)
if err != nil { return "", err }
if err != nil {
return "", err
}
device, err = readCustomDeviceName(vmxData)
if err != nil { return "", err }
if err != nil {
return "", err
}
}
// parse dhcpd configuration
@ -413,54 +435,68 @@ func (d *VmwareDriver) HostAddress(state multistep.StateBag) (string,error) {
return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig)
}
config,err := ReadDhcpConfig(pathDhcpConfig)
if err != nil { return "",err }
config, err := ReadDhcpConfig(pathDhcpConfig)
if err != nil {
return "", err
}
// find the entry configured in the dhcpd
interfaceConfig,err := config.HostByName(device)
if err != nil { return "", err }
interfaceConfig, err := config.HostByName(device)
if err != nil {
return "", err
}
// finally grab the hardware address
address,err := interfaceConfig.Hardware()
if err == nil { return address.String(), nil }
address, err := interfaceConfig.Hardware()
if err == nil {
return address.String(), nil
}
// we didn't find it, so search through our interfaces for the device name
interfaceList,err := net.Interfaces()
if err == nil { return "", err }
interfaceList, err := net.Interfaces()
if err == nil {
return "", err
}
names := make([]string, 0)
for _,intf := range interfaceList {
if strings.HasSuffix( strings.ToLower(intf.Name), device ) {
return intf.HardwareAddr.String(),nil
for _, intf := range interfaceList {
if strings.HasSuffix(strings.ToLower(intf.Name), device) {
return intf.HardwareAddr.String(), nil
}
names = append(names, intf.Name)
}
return "",fmt.Errorf("Unable to find device %s : %v", device, names)
return "", fmt.Errorf("Unable to find device %s : %v", device, names)
}
func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) {
func (d *VmwareDriver) HostIP(state multistep.StateBag) (string, error) {
// parse network<->device mapping
pathNetmap := d.NetmapConfPath()
if _, err := os.Stat(pathNetmap); err != nil {
return "", fmt.Errorf("Could not find netmap conf file: %s", pathNetmap)
}
netmap,err := ReadNetmapConfig(pathNetmap)
if err != nil { return "",err }
netmap, err := ReadNetmapConfig(pathNetmap)
if err != nil {
return "", err
}
// convert network to name
network := state.Get("vmnetwork").(string)
device,err := netmap.NameIntoDevice(network)
device, err := netmap.NameIntoDevice(network)
// we were unable to find the device, maybe it's a custom one...
// so, check to see if it's in the .vmx configuration
if err != nil || network == "custom" {
vmxPath := state.Get("vmx_path").(string)
vmxData, err := readVMXConfig(vmxPath)
if err != nil { return "", err }
if err != nil {
return "", err
}
device, err = readCustomDeviceName(vmxData)
if err != nil { return "", err }
if err != nil {
return "", err
}
}
// parse dhcpd configuration
@ -468,15 +504,21 @@ func (d *VmwareDriver) HostIP(state multistep.StateBag) (string,error) {
if _, err := os.Stat(pathDhcpConfig); err != nil {
return "", fmt.Errorf("Could not find vmnetdhcp conf file: %s", pathDhcpConfig)
}
config,err := ReadDhcpConfig(pathDhcpConfig)
if err != nil { return "",err }
config, err := ReadDhcpConfig(pathDhcpConfig)
if err != nil {
return "", err
}
// find the entry configured in the dhcpd
interfaceConfig,err := config.HostByName(device)
if err != nil { return "", err }
interfaceConfig, err := config.HostByName(device)
if err != nil {
return "", err
}
address,err := interfaceConfig.IP4()
if err != nil { return "", err }
address, err := interfaceConfig.IP4()
if err != nil {
return "", err
}
return address.String(),nil
return address.String(), nil
}

View File

@ -83,7 +83,7 @@ type DriverMock struct {
VmnetnatConfPathCalled bool
VmnetnatConfPathResult string
NetmapConfPathCalled bool
NetmapConfPathResult string

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@ import (
"fmt"
"log"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"path/filepath"
)
func playerFindVdiskManager() (string, error) {

View File

@ -33,4 +33,3 @@ func (d *Workstation10Driver) Verify() error {
return workstationVerifyVersion(VMWARE_WS_VERSION)
}

View File

@ -39,38 +39,35 @@ type Config struct {
vmwcommon.VMXConfig `mapstructure:",squash"`
// disk drives
AdditionalDiskSize []uint `mapstructure:"disk_additional_size"`
DiskName string `mapstructure:"vmdk_name"`
DiskSize uint `mapstructure:"disk_size"`
DiskTypeId string `mapstructure:"disk_type_id"`
Format string `mapstructure:"format"`
AdditionalDiskSize []uint `mapstructure:"disk_additional_size"`
DiskName string `mapstructure:"vmdk_name"`
DiskSize uint `mapstructure:"disk_size"`
DiskTypeId string `mapstructure:"disk_type_id"`
Format string `mapstructure:"format"`
// platform information
GuestOSType string `mapstructure:"guest_os_type"`
Version string `mapstructure:"version"`
VMName string `mapstructure:"vm_name"`
GuestOSType string `mapstructure:"guest_os_type"`
Version string `mapstructure:"version"`
VMName string `mapstructure:"vm_name"`
// Network type
Network string `mapstructure:"network"`
Network string `mapstructure:"network"`
// device presence
Sound bool `mapstructure:"sound"`
USB bool `mapstructure:"usb"`
Sound bool `mapstructure:"sound"`
USB bool `mapstructure:"usb"`
// communication ports
Serial string `mapstructure:"serial"`
Parallel string `mapstructure:"parallel"`
Serial string `mapstructure:"serial"`
Parallel string `mapstructure:"parallel"`
// booting a guest
BootCommand []string `mapstructure:"boot_command"`
KeepRegistered bool `mapstructure:"keep_registered"`
OVFToolOptions []string `mapstructure:"ovftool_options"`
SkipCompaction bool `mapstructure:"skip_compaction"`
SkipExport bool `mapstructure:"skip_export"`
VMName string `mapstructure:"vm_name"`
VMXDiskTemplatePath string `mapstructure:"vmx_disk_template_path"`
VMXTemplatePath string `mapstructure:"vmx_template_path"`
Version string `mapstructure:"version"`
// remote vsphere
RemoteType string `mapstructure:"remote_type"`

View File

@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
@ -21,24 +22,24 @@ type vmxTemplateData struct {
ISOPath string
Version string
Network_Type string
Network_Device string
Network_Type string
Network_Device string
Sound_Present string
Usb_Present string
Usb_Present string
Serial_Present string
Serial_Type string
Serial_Present string
Serial_Type string
Serial_Endpoint string
Serial_Host string
Serial_Yield string
Serial_Host string
Serial_Yield string
Serial_Filename string
Serial_Auto string
Serial_Auto string
Parallel_Present string
Parallel_Present string
Parallel_Bidirectional string
Parallel_Filename string
Parallel_Auto string
Parallel_Filename string
Parallel_Auto string
}
type additionalDiskTemplateData struct {
@ -63,34 +64,34 @@ type stepCreateVMX struct {
type serialConfigPipe struct {
filename string
endpoint string
host string
yield string
host string
yield string
}
type serialConfigFile struct {
filename string
yield string
yield string
}
type serialConfigDevice struct {
devicename string
yield string
yield string
}
type serialConfigAuto struct {
devicename string
yield string
yield string
}
type serialUnion struct {
serialType interface{}
pipe *serialConfigPipe
file *serialConfigFile
device *serialConfigDevice
auto *serialConfigAuto
pipe *serialConfigPipe
file *serialConfigFile
device *serialConfigDevice
auto *serialConfigAuto
}
func unformat_serial(config string) (*serialUnion,error) {
func unformat_serial(config string) (*serialUnion, error) {
var defaultSerialPort string
if runtime.GOOS == "windows" {
defaultSerialPort = "COM1"
@ -100,7 +101,7 @@ func unformat_serial(config string) (*serialUnion,error) {
input := strings.SplitN(config, ":", 2)
if len(input) < 1 {
return nil,fmt.Errorf("Unexpected format for serial port: %s", config)
return nil, fmt.Errorf("Unexpected format for serial port: %s", config)
}
var formatType, formatOptions string
@ -112,116 +113,116 @@ func unformat_serial(config string) (*serialUnion,error) {
}
switch strings.ToUpper(formatType) {
case "PIPE":
comp := strings.Split(formatOptions, ",")
if len(comp) < 3 || len(comp) > 4 {
return nil,fmt.Errorf("Unexpected format for serial port : pipe : %s", config)
}
if res := strings.ToLower(comp[1]); res != "client" && res != "server" {
return nil,fmt.Errorf("Unexpected format for serial port : pipe : endpoint : %s : %s", res, config)
}
if res := strings.ToLower(comp[2]); res != "app" && res != "vm" {
return nil,fmt.Errorf("Unexpected format for serial port : pipe : host : %s : %s", res, config)
}
res := &serialConfigPipe{
filename : comp[0],
endpoint : comp[1],
host : map[string]string{"app":"TRUE","vm":"FALSE"}[strings.ToLower(comp[2])],
yield : "FALSE",
}
if len(comp) == 4 {
res.yield = strings.ToUpper(comp[3])
}
if res.yield != "TRUE" && res.yield != "FALSE" {
return nil,fmt.Errorf("Unexpected format for serial port : pipe : yield : %s : %s", res.yield, config)
}
return &serialUnion{serialType:res, pipe:res},nil
case "PIPE":
comp := strings.Split(formatOptions, ",")
if len(comp) < 3 || len(comp) > 4 {
return nil, fmt.Errorf("Unexpected format for serial port : pipe : %s", config)
}
if res := strings.ToLower(comp[1]); res != "client" && res != "server" {
return nil, fmt.Errorf("Unexpected format for serial port : pipe : endpoint : %s : %s", res, config)
}
if res := strings.ToLower(comp[2]); res != "app" && res != "vm" {
return nil, fmt.Errorf("Unexpected format for serial port : pipe : host : %s : %s", res, config)
}
res := &serialConfigPipe{
filename: comp[0],
endpoint: comp[1],
host: map[string]string{"app": "TRUE", "vm": "FALSE"}[strings.ToLower(comp[2])],
yield: "FALSE",
}
if len(comp) == 4 {
res.yield = strings.ToUpper(comp[3])
}
if res.yield != "TRUE" && res.yield != "FALSE" {
return nil, fmt.Errorf("Unexpected format for serial port : pipe : yield : %s : %s", res.yield, config)
}
return &serialUnion{serialType: res, pipe: res}, nil
case "FILE":
comp := strings.Split(formatOptions, ",")
if len(comp) > 2 {
return nil,fmt.Errorf("Unexpected format for serial port : file : %s", config)
}
case "FILE":
comp := strings.Split(formatOptions, ",")
if len(comp) > 2 {
return nil, fmt.Errorf("Unexpected format for serial port : file : %s", config)
}
res := &serialConfigFile{ yield : "FALSE" }
res := &serialConfigFile{yield: "FALSE"}
res.filename = filepath.FromSlash(comp[0])
res.filename = filepath.FromSlash(comp[0])
res.yield = map[bool]string{true:strings.ToUpper(comp[0]), false:"FALSE"}[len(comp) > 1]
if res.yield != "TRUE" && res.yield != "FALSE" {
return nil,fmt.Errorf("Unexpected format for serial port : file : yield : %s : %s", res.yield, config)
}
res.yield = map[bool]string{true: strings.ToUpper(comp[0]), false: "FALSE"}[len(comp) > 1]
if res.yield != "TRUE" && res.yield != "FALSE" {
return nil, fmt.Errorf("Unexpected format for serial port : file : yield : %s : %s", res.yield, config)
}
return &serialUnion{serialType:res, file:res},nil
return &serialUnion{serialType: res, file: res}, nil
case "DEVICE":
comp := strings.Split(formatOptions, ",")
if len(comp) > 2 {
return nil,fmt.Errorf("Unexpected format for serial port : device : %s", config)
}
case "DEVICE":
comp := strings.Split(formatOptions, ",")
if len(comp) > 2 {
return nil, fmt.Errorf("Unexpected format for serial port : device : %s", config)
}
res := new(serialConfigDevice)
res := new(serialConfigDevice)
if len(comp) == 2 {
res.devicename = map[bool]string{true:filepath.FromSlash(comp[0]), false:defaultSerialPort}[len(comp[0]) > 0]
res.yield = strings.ToUpper(comp[1])
} else if len(comp) == 1 {
res.devicename = map[bool]string{true:filepath.FromSlash(comp[0]), false:defaultSerialPort}[len(comp[0]) > 0]
res.yield = "FALSE"
} else if len(comp) == 0 {
res.devicename = defaultSerialPort
res.yield = "FALSE"
}
if res.yield != "TRUE" && res.yield != "FALSE" {
return nil,fmt.Errorf("Unexpected format for serial port : device : yield : %s : %s", res.yield, config)
}
return &serialUnion{serialType:res, device:res},nil
case "AUTO":
res := new(serialConfigAuto)
if len(comp) == 2 {
res.devicename = map[bool]string{true: filepath.FromSlash(comp[0]), false: defaultSerialPort}[len(comp[0]) > 0]
res.yield = strings.ToUpper(comp[1])
} else if len(comp) == 1 {
res.devicename = map[bool]string{true: filepath.FromSlash(comp[0]), false: defaultSerialPort}[len(comp[0]) > 0]
res.yield = "FALSE"
} else if len(comp) == 0 {
res.devicename = defaultSerialPort
res.yield = "FALSE"
}
if len(formatOptions) > 0 {
res.yield = strings.ToUpper(formatOptions)
} else {
res.yield = "FALSE"
}
if res.yield != "TRUE" && res.yield != "FALSE" {
return nil, fmt.Errorf("Unexpected format for serial port : device : yield : %s : %s", res.yield, config)
}
if res.yield != "TRUE" && res.yield != "FALSE" {
return nil,fmt.Errorf("Unexpected format for serial port : auto : yield : %s : %s", res.yield, config)
}
return &serialUnion{serialType: res, device: res}, nil
return &serialUnion{serialType:res, auto:res},nil
case "AUTO":
res := new(serialConfigAuto)
res.devicename = defaultSerialPort
default:
return nil,fmt.Errorf("Unknown serial type : %s : %s", strings.ToUpper(formatType), config)
if len(formatOptions) > 0 {
res.yield = strings.ToUpper(formatOptions)
} else {
res.yield = "FALSE"
}
if res.yield != "TRUE" && res.yield != "FALSE" {
return nil, fmt.Errorf("Unexpected format for serial port : auto : yield : %s : %s", res.yield, config)
}
return &serialUnion{serialType: res, auto: res}, nil
default:
return nil, fmt.Errorf("Unknown serial type : %s : %s", strings.ToUpper(formatType), config)
}
}
/* parallel port */
type parallelUnion struct {
parallelType interface{}
file *parallelPortFile
device *parallelPortDevice
auto *parallelPortAuto
file *parallelPortFile
device *parallelPortDevice
auto *parallelPortAuto
}
type parallelPortFile struct {
filename string
}
type parallelPortDevice struct {
bidirectional string
devicename string
devicename string
}
type parallelPortAuto struct {
bidirectional string
}
func unformat_parallel(config string) (*parallelUnion,error) {
func unformat_parallel(config string) (*parallelUnion, error) {
input := strings.SplitN(config, ":", 2)
if len(input) < 1 {
return nil,fmt.Errorf("Unexpected format for parallel port: %s", config)
return nil, fmt.Errorf("Unexpected format for parallel port: %s", config)
}
var formatType, formatOptions string
@ -233,39 +234,44 @@ func unformat_parallel(config string) (*parallelUnion,error) {
}
switch strings.ToUpper(formatType) {
case "FILE":
res := &parallelPortFile{ filename: filepath.FromSlash(formatOptions) }
return &parallelUnion{ parallelType:res, file: res},nil
case "DEVICE":
comp := strings.Split(formatOptions, ",")
if len(comp) < 1 || len(comp) > 2 {
return nil,fmt.Errorf("Unexpected format for parallel port: %s", config)
case "FILE":
res := &parallelPortFile{filename: filepath.FromSlash(formatOptions)}
return &parallelUnion{parallelType: res, file: res}, nil
case "DEVICE":
comp := strings.Split(formatOptions, ",")
if len(comp) < 1 || len(comp) > 2 {
return nil, fmt.Errorf("Unexpected format for parallel port: %s", config)
}
res := new(parallelPortDevice)
res.bidirectional = "FALSE"
res.devicename = filepath.FromSlash(comp[0])
if len(comp) > 1 {
switch strings.ToUpper(comp[1]) {
case "BI":
res.bidirectional = "TRUE"
case "UNI":
res.bidirectional = "FALSE"
default:
return nil, fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(comp[0]), config)
}
res := new(parallelPortDevice)
res.bidirectional = "FALSE"
res.devicename = strings.ToUpper(comp[0])
if len(comp) > 1 {
switch strings.ToUpper(comp[1]) {
case "BI": res.bidirectional = "TRUE"
case "UNI": res.bidirectional = "FALSE"
default:
return nil,fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(comp[0]), config)
}
}
return &parallelUnion{ parallelType:res, device:res },nil
}
return &parallelUnion{parallelType: res, device: res}, nil
case "AUTO":
res := new(parallelPortAuto)
switch strings.ToUpper(formatOptions) {
case "": fallthrough
case "UNI": res.bidirectional = "FALSE"
case "BI": res.bidirectional = "TRUE"
default:
return nil,fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(formatOptions), config)
}
return &parallelUnion{ parallelType:res, auto:res },nil
case "AUTO":
res := new(parallelPortAuto)
switch strings.ToUpper(formatOptions) {
case "":
fallthrough
case "UNI":
res.bidirectional = "FALSE"
case "BI":
res.bidirectional = "TRUE"
default:
return nil, fmt.Errorf("Unknown parallel port direction : %s : %s", strings.ToUpper(formatOptions), config)
}
return &parallelUnion{parallelType: res, auto: res}, nil
}
return nil,fmt.Errorf("Unexpected format for parallel port: %s", config)
return nil, fmt.Errorf("Unexpected format for parallel port: %s", config)
}
/* regular steps */
@ -348,11 +354,11 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
Version: config.Version,
ISOPath: isoPath,
Sound_Present: map[bool]string{true:"TRUE",false:"FALSE"}[bool(config.Sound)],
Usb_Present: map[bool]string{true:"TRUE",false:"FALSE"}[bool(config.USB)],
Sound_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.Sound)],
Usb_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.USB)],
Serial_Present: "FALSE",
Parallel_Present: "FALSE",
Serial_Present: "FALSE",
Parallel_Present: "FALSE",
}
/// Check the network type that the user specified
@ -367,7 +373,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
ui.Error(err.Error())
return multistep.ActionHalt
}
netmap,res := vmwcommon.ReadNetmapConfig(pathNetmap)
netmap, res := vmwcommon.ReadNetmapConfig(pathNetmap)
if res != nil {
err := fmt.Errorf("Unable to read netmap conf file: %s: %v", pathNetmap, res)
state.Put("error", err)
@ -376,13 +382,13 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
}
// try and convert the specified network to a device
device,err := netmap.NameIntoDevice(network)
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
// we were unable to find the type, so assume it's a custom network device.
// we were unable to find the type, so assume it's a custom network device.
} else {
templateData.Network_Type = "custom"
templateData.Network_Device = network
@ -392,7 +398,7 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
/// check if serial port has been configured
if config.Serial != "" {
serial,err := unformat_serial(config.Serial)
serial, err := unformat_serial(config.Serial)
if err != nil {
err := fmt.Errorf("Error procesing VMX template: %s", err)
state.Put("error", err)
@ -408,35 +414,35 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
templateData.Serial_Auto = "FALSE"
switch serial.serialType.(type) {
case *serialConfigPipe:
templateData.Serial_Type = "pipe"
templateData.Serial_Endpoint = serial.pipe.endpoint
templateData.Serial_Host = serial.pipe.host
templateData.Serial_Yield = serial.pipe.yield
templateData.Serial_Filename = filepath.FromSlash(serial.pipe.filename)
case *serialConfigFile:
templateData.Serial_Type = "file"
templateData.Serial_Filename = filepath.FromSlash(serial.file.filename)
case *serialConfigDevice:
templateData.Serial_Type = "device"
templateData.Serial_Filename = filepath.FromSlash(serial.device.devicename)
case *serialConfigAuto:
templateData.Serial_Type = "device"
templateData.Serial_Filename = filepath.FromSlash(serial.auto.devicename)
templateData.Serial_Yield = serial.auto.yield
templateData.Serial_Auto = "TRUE"
case *serialConfigPipe:
templateData.Serial_Type = "pipe"
templateData.Serial_Endpoint = serial.pipe.endpoint
templateData.Serial_Host = serial.pipe.host
templateData.Serial_Yield = serial.pipe.yield
templateData.Serial_Filename = filepath.FromSlash(serial.pipe.filename)
case *serialConfigFile:
templateData.Serial_Type = "file"
templateData.Serial_Filename = filepath.FromSlash(serial.file.filename)
case *serialConfigDevice:
templateData.Serial_Type = "device"
templateData.Serial_Filename = filepath.FromSlash(serial.device.devicename)
case *serialConfigAuto:
templateData.Serial_Type = "device"
templateData.Serial_Filename = filepath.FromSlash(serial.auto.devicename)
templateData.Serial_Yield = serial.auto.yield
templateData.Serial_Auto = "TRUE"
default:
err := fmt.Errorf("Error procesing VMX template: %v", serial)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
default:
err := fmt.Errorf("Error procesing VMX template: %v", serial)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}
/// check if parallel port has been configured
if config.Parallel != "" {
parallel,err := unformat_parallel(config.Parallel)
parallel, err := unformat_parallel(config.Parallel)
if err != nil {
err := fmt.Errorf("Error procesing VMX template: %s", err)
state.Put("error", err)
@ -446,22 +452,22 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
templateData.Parallel_Auto = "FALSE"
switch parallel.parallelType.(type) {
case *parallelPortFile:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Filename = filepath.FromSlash(parallel.file.filename)
case *parallelPortDevice:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Bidirectional = parallel.device.bidirectional
templateData.Parallel_Filename = filepath.FromSlash(parallel.device.devicename)
case *parallelPortAuto:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Auto = "TRUE"
templateData.Parallel_Bidirectional = parallel.auto.bidirectional
default:
err := fmt.Errorf("Error procesing VMX template: %v", parallel)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
case *parallelPortFile:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Filename = filepath.FromSlash(parallel.file.filename)
case *parallelPortDevice:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Bidirectional = parallel.device.bidirectional
templateData.Parallel_Filename = filepath.FromSlash(parallel.device.devicename)
case *parallelPortAuto:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Auto = "TRUE"
templateData.Parallel_Bidirectional = parallel.auto.bidirectional
default:
err := fmt.Errorf("Error procesing VMX template: %v", parallel)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}

View File

@ -1,37 +1,37 @@
package iso
import (
"bytes"
"fmt"
"os"
"path/filepath"
"strings"
"io/ioutil"
"math"
"math/rand"
"strconv"
"io/ioutil"
"bytes"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"testing"
"github.com/mitchellh/packer/packer"
"github.com/mitchellh/packer/template"
"github.com/mitchellh/packer/provisioner/shell"
"github.com/mitchellh/packer/template"
"testing"
)
var vmxTestBuilderConfig = map[string]string{
"type": `"vmware-iso"`,
"iso_url": `"https://archive.org/download/ut-ttylinux-i686-12.6/ut-ttylinux-i686-12.6.iso"`,
"type": `"vmware-iso"`,
"iso_url": `"https://archive.org/download/ut-ttylinux-i686-12.6/ut-ttylinux-i686-12.6.iso"`,
"iso_checksum_type": `"md5"`,
"iso_checksum": `"43c1feeae55a44c6ef694b8eb18408a6"`,
"ssh_username": `"root"`,
"ssh_password": `"password"`,
"ssh_wait_timeout": `"45s"`,
"boot_command": `["<enter><wait5><wait10>","root<enter><wait>password<enter><wait>","udhcpc<enter><wait>"]`,
"shutdown_command": `"/sbin/shutdown -h; exit 0"`,
"iso_checksum": `"43c1feeae55a44c6ef694b8eb18408a6"`,
"ssh_username": `"root"`,
"ssh_password": `"password"`,
"ssh_wait_timeout": `"45s"`,
"boot_command": `["<enter><wait5><wait10>","root<enter><wait>password<enter><wait>","udhcpc<enter><wait>"]`,
"shutdown_command": `"/sbin/shutdown -h; exit 0"`,
}
var vmxTestProvisionerConfig = map[string]string{
"type": `"shell"`,
"type": `"shell"`,
"inline": `["echo hola mundo"]`,
}
@ -40,24 +40,26 @@ const vmxTestTemplate string = `{"builders":[{%s}],"provisioners":[{%s}]}`
func tmpnam(prefix string) string {
var path string
var err error
const length = 16
dir := os.TempDir()
max := int(math.Pow(2, float64(length)))
n,err := rand.Intn(max),nil
for path = filepath.Join(dir, prefix + strconv.Itoa(n)); err == nil; _,err = os.Stat(path) {
n, err := rand.Intn(max), nil
for path = filepath.Join(dir, prefix+strconv.Itoa(n)); err == nil; _, err = os.Stat(path) {
n = rand.Intn(max)
path = filepath.Join(dir, prefix + strconv.Itoa(n))
path = filepath.Join(dir, prefix+strconv.Itoa(n))
}
return path
}
func createFloppyOutput(prefix string) (string,string,error) {
func createFloppyOutput(prefix string) (string, string, error) {
output := tmpnam(prefix)
f,err := os.Create(output)
if err != nil { return "","",fmt.Errorf("Unable to create empty %s: %s", output, err) }
f, err := os.Create(output)
if err != nil {
return "", "", fmt.Errorf("Unable to create empty %s: %s", output, err)
}
f.Close()
vmxData := []string{
@ -69,18 +71,24 @@ func createFloppyOutput(prefix string) (string,string,error) {
}
outputFile := strings.Replace(output, "\\", "\\\\", -1)
vmxString := fmt.Sprintf("{" + strings.Join(vmxData, ",") + "}", outputFile)
return output,vmxString,nil
vmxString := fmt.Sprintf("{"+strings.Join(vmxData, ",")+"}", outputFile)
return output, vmxString, nil
}
func readFloppyOutput(path string) (string,error) {
f,err := os.Open(path)
if err != nil { return "",fmt.Errorf("Unable to open file %s", path) }
func readFloppyOutput(path string) (string, error) {
f, err := os.Open(path)
if err != nil {
return "", fmt.Errorf("Unable to open file %s", path)
}
defer f.Close()
data,err := ioutil.ReadAll(f)
if err != nil { return "",fmt.Errorf("Unable to read file: %s", err) }
if len(data) == 0 { return "", nil }
return string(data[:bytes.IndexByte(data,0)]),nil
data, err := ioutil.ReadAll(f)
if err != nil {
return "", fmt.Errorf("Unable to read file: %s", err)
}
if len(data) == 0 {
return "", nil
}
return string(data[:bytes.IndexByte(data, 0)]), nil
}
func setupVMwareBuild(t *testing.T, builderConfig map[string]string, provisionerConfig map[string]string) error {
@ -88,72 +96,84 @@ func setupVMwareBuild(t *testing.T, builderConfig map[string]string, provisioner
// create builder config and update with user-supplied options
cfgBuilder := map[string]string{}
for k,v := range vmxTestBuilderConfig { cfgBuilder[k] = v }
for k,v := range builderConfig { cfgBuilder[k] = v }
for k, v := range vmxTestBuilderConfig {
cfgBuilder[k] = v
}
for k, v := range builderConfig {
cfgBuilder[k] = v
}
// convert our builder config into a single sprintfable string
builderLines := []string{}
for k,v := range cfgBuilder {
for k, v := range cfgBuilder {
builderLines = append(builderLines, fmt.Sprintf(`"%s":%s`, k, v))
}
// create provisioner config and update with user-supplied options
cfgProvisioner := map[string]string{}
for k,v := range vmxTestProvisionerConfig { cfgProvisioner[k] = v }
for k,v := range provisionerConfig { cfgProvisioner[k] = v }
for k, v := range vmxTestProvisionerConfig {
cfgProvisioner[k] = v
}
for k, v := range provisionerConfig {
cfgProvisioner[k] = v
}
// convert our provisioner config into a single sprintfable string
provisionerLines := []string{}
for k,v := range cfgProvisioner {
for k, v := range cfgProvisioner {
provisionerLines = append(provisionerLines, fmt.Sprintf(`"%s":%s`, k, v))
}
// and now parse them into a template
configString := fmt.Sprintf(vmxTestTemplate, strings.Join(builderLines,`,`), strings.Join(provisionerLines,`,`))
configString := fmt.Sprintf(vmxTestTemplate, strings.Join(builderLines, `,`), strings.Join(provisionerLines, `,`))
tpl,err := template.Parse(strings.NewReader(configString))
tpl, err := template.Parse(strings.NewReader(configString))
if err != nil {
t.Fatalf("Unable to parse test config: %s", err)
}
// create our config to test the vmware-iso builder
components := packer.ComponentFinder{
Builder: func(n string) (packer.Builder,error) {
return &Builder{},nil
Builder: func(n string) (packer.Builder, error) {
return &Builder{}, nil
},
Hook: func(n string) (packer.Hook,error) {
return &packer.DispatchHook{},nil
Hook: func(n string) (packer.Hook, error) {
return &packer.DispatchHook{}, nil
},
PostProcessor: func(n string) (packer.PostProcessor,error) {
return &packer.MockPostProcessor{},nil
PostProcessor: func(n string) (packer.PostProcessor, error) {
return &packer.MockPostProcessor{}, nil
},
Provisioner: func(n string) (packer.Provisioner,error) {
return &shell.Provisioner{},nil
Provisioner: func(n string) (packer.Provisioner, error) {
return &shell.Provisioner{}, nil
},
}
config := packer.CoreConfig{
Template: tpl,
Template: tpl,
Components: components,
}
// create a core using our template
core,err := packer.NewCore(&config)
if err != nil { t.Fatalf("Unable to create core: %s", err) }
core, err := packer.NewCore(&config)
if err != nil {
t.Fatalf("Unable to create core: %s", err)
}
// now we can prepare our build
b,err := core.Build("vmware-iso")
if err != nil { t.Fatalf("Unable to create build: %s", err) }
b, err := core.Build("vmware-iso")
if err != nil {
t.Fatalf("Unable to create build: %s", err)
}
warn,err := b.Prepare()
warn, err := b.Prepare()
if len(warn) > 0 {
for _,w := range warn {
for _, w := range warn {
t.Logf("Configuration warning: %s", w)
}
}
// and then finally build it
cache := &packer.FileCache{CacheDir: os.TempDir()}
artifacts,err := b.Run(ui, cache)
artifacts, err := b.Run(ui, cache)
if err != nil {
t.Fatalf("Failed to build artifact: %s", err)
}
@ -166,7 +186,7 @@ func setupVMwareBuild(t *testing.T, builderConfig map[string]string, provisioner
// otherwise some number of errors happened
t.Logf("Unexpected number of artifacts returned: %d", len(artifacts))
errors := make([]error, 0)
for _,artifact := range artifacts {
for _, artifact := range artifacts {
if err := artifact.Destroy(); err != nil {
errors = append(errors, err)
}
@ -186,9 +206,11 @@ func TestStepCreateVmx_SerialFile(t *testing.T) {
}
error := setupVMwareBuild(t, serialConfig, map[string]string{})
if error != nil { t.Errorf("Unable to read file: %s", error) }
if error != nil {
t.Errorf("Unable to read file: %s", error)
}
f,err := os.Stat(tmpfile)
f, err := os.Stat(tmpfile)
if err != nil {
t.Errorf("VMware builder did not create a file for serial port: %s", err)
}
@ -216,19 +238,29 @@ func TestStepCreateVmx_SerialPort(t *testing.T) {
}
// where to write output
output,vmxData,err := createFloppyOutput("SerialPortOutput.")
if err != nil { t.Fatalf("Error creating output: %s", err) }
defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }()
output, vmxData, err := createFloppyOutput("SerialPortOutput.")
if err != nil {
t.Fatalf("Error creating output: %s", err)
}
defer func() {
if _, err := os.Stat(output); err == nil {
os.Remove(output)
}
}()
config["vmx_data"] = vmxData
t.Logf("Preparing to write output to %s", output)
// whee
err = setupVMwareBuild(t, config, provision)
if err != nil { t.Errorf("%s", err) }
if err != nil {
t.Errorf("%s", err)
}
// check the output
data,err := readFloppyOutput(output)
if err != nil { t.Errorf("%s", err) }
data, err := readFloppyOutput(output)
if err != nil {
t.Errorf("%s", err)
}
if data != "serial8250: ttyS1 at\n" {
t.Errorf("Serial port not detected : %v", data)
@ -251,19 +283,29 @@ func TestStepCreateVmx_ParallelPort(t *testing.T) {
}
// where to write output
output,vmxData,err := createFloppyOutput("ParallelPortOutput.")
if err != nil { t.Fatalf("Error creating output: %s", err) }
defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }()
output, vmxData, err := createFloppyOutput("ParallelPortOutput.")
if err != nil {
t.Fatalf("Error creating output: %s", err)
}
defer func() {
if _, err := os.Stat(output); err == nil {
os.Remove(output)
}
}()
config["vmx_data"] = vmxData
t.Logf("Preparing to write output to %s", output)
// whee
error := setupVMwareBuild(t, config, provision)
if error != nil { t.Errorf("%s", error) }
if error != nil {
t.Errorf("%s", error)
}
// check the output
data,err := readFloppyOutput(output)
if err != nil { t.Errorf("%s", err) }
data, err := readFloppyOutput(output)
if err != nil {
t.Errorf("%s", err)
}
if data != "parport \n" {
t.Errorf("Parallel port not detected : %v", data)
@ -279,19 +321,29 @@ func TestStepCreateVmx_Usb(t *testing.T) {
}
// where to write output
output,vmxData,err := createFloppyOutput("UsbOutput.")
if err != nil { t.Fatalf("Error creating output: %s", err) }
defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }()
output, vmxData, err := createFloppyOutput("UsbOutput.")
if err != nil {
t.Fatalf("Error creating output: %s", err)
}
defer func() {
if _, err := os.Stat(output); err == nil {
os.Remove(output)
}
}()
config["vmx_data"] = vmxData
t.Logf("Preparing to write output to %s", output)
// whee
error := setupVMwareBuild(t, config, provision)
if error != nil { t.Errorf("%s", error) }
if error != nil {
t.Errorf("%s", error)
}
// check the output
data,err := readFloppyOutput(output)
if err != nil { t.Errorf("%s", err) }
data, err := readFloppyOutput(output)
if err != nil {
t.Errorf("%s", err)
}
if data != "USB hub found\n" {
t.Errorf("USB support not detected : %v", data)
@ -302,24 +354,34 @@ func TestStepCreateVmx_Sound(t *testing.T) {
config := map[string]string{
"sound": `"TRUE"`,
}
provision := map[string]string {
provision := map[string]string{
"inline": `"cat /proc/modules | egrep -o '^soundcore' > /dev/fd0"`,
}
// where to write output
output,vmxData,err := createFloppyOutput("SoundOutput.")
if err != nil { t.Fatalf("Error creating output: %s", err) }
defer func() { if _,err := os.Stat(output); err == nil { os.Remove(output) } }()
output, vmxData, err := createFloppyOutput("SoundOutput.")
if err != nil {
t.Fatalf("Error creating output: %s", err)
}
defer func() {
if _, err := os.Stat(output); err == nil {
os.Remove(output)
}
}()
config["vmx_data"] = vmxData
t.Logf("Preparing to write output to %s", output)
// whee
error := setupVMwareBuild(t, config, provision)
if error != nil { t.Errorf("Unable to read file: %s", error) }
if error != nil {
t.Errorf("Unable to read file: %s", error)
}
// check the output
data,err := readFloppyOutput(output)
if err != nil { t.Errorf("%s", err) }
data, err := readFloppyOutput(output)
if err != nil {
t.Errorf("%s", err)
}
if data != "soundcore\n" {
t.Errorf("Soundcard not detected : %v", data)