Moved common hardware config options used by the vmware-iso builder into common/hw_config and added options for the CpuCount and MemorySize.

This commit is contained in:
Ali Rizvi-Santiago 2018-11-17 01:23:28 -06:00
parent 4e73c85e22
commit cd45248eaa
4 changed files with 661 additions and 274 deletions

View File

@ -0,0 +1,298 @@
package common
import (
"fmt"
"path/filepath"
"runtime"
"strings"
"github.com/hashicorp/packer/template/interpolate"
)
type HWConfig struct {
// cpu information
CpuCount int `mapstructure:"cpu_count"`
MemorySize int `mapstructure:"memory_size"`
// network type and adapter
Network string `mapstructure:"network"`
NetworkAdapterType string `mapstructure:"network_adapter_type"`
// device presence
Sound bool `mapstructure:"sound"`
USB bool `mapstructure:"usb"`
// communication ports
Serial string `mapstructure:"serial"`
Parallel string `mapstructure:"parallel"`
}
func (c *HWConfig) Prepare(ctx *interpolate.Context) []error {
var errs []error
// Hardware and cpu options
if c.CpuCount < 0 {
errs = append(errs, fmt.Errorf("An invalid cpu_count was specified (cpu_count < 0): %d", c.CpuCount))
c.CpuCount = 0
}
if c.CpuCount == 0 {
c.CpuCount = 1
}
if c.MemorySize < 0 {
errs = append(errs, fmt.Errorf("An invalid memory_size was specified (memory_size < 0): %d", c.MemorySize))
c.MemorySize = 0
}
if c.MemorySize == 0 {
c.MemorySize = 512
}
// Peripherals
if !c.Sound {
c.Sound = false
}
if !c.USB {
c.USB = false
}
if c.Parallel == "" {
c.Parallel = "none"
}
if c.Serial == "" {
c.Serial = "none"
}
return nil
}
/* parallel port */
type ParallelUnion struct {
Union interface{}
File *ParallelPortFile
Device *ParallelPortDevice
Auto *ParallelPortAuto
}
type ParallelPortFile struct {
Filename string
}
type ParallelPortDevice struct {
Bidirectional string
Devicename string
}
type ParallelPortAuto struct {
Bidirectional string
}
func (c *HWConfig) HasParallel() bool {
return c.Parallel != ""
}
func (c *HWConfig) ReadParallel() (*ParallelUnion, error) {
input := strings.SplitN(c.Parallel, ":", 2)
if len(input) < 1 {
return nil, fmt.Errorf("Unexpected format for parallel port: %s", c.Parallel)
}
var formatType, formatOptions string
formatType = input[0]
if len(input) == 2 {
formatOptions = input[1]
} else {
formatOptions = ""
}
switch strings.ToUpper(formatType) {
case "FILE":
res := &ParallelPortFile{Filename: filepath.FromSlash(formatOptions)}
return &ParallelUnion{Union: 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", c.Parallel)
}
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 direction %s specified for parallel port: %s", strings.ToUpper(comp[1]), c.Parallel)
}
}
return &ParallelUnion{Union: 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 direction %s specified for parallel port: %s", strings.ToUpper(formatOptions), c.Parallel)
}
return &ParallelUnion{Union: res, Auto: res}, nil
case "NONE":
return &ParallelUnion{Union: nil}, nil
}
return nil, fmt.Errorf("Unexpected format for parallel port: %s", c.Parallel)
}
/* serial conversions */
type SerialConfigPipe struct {
Filename string
Endpoint string
Host string
Yield string
}
type SerialConfigFile struct {
Filename string
Yield string
}
type SerialConfigDevice struct {
Devicename string
Yield string
}
type SerialConfigAuto struct {
Devicename string
Yield string
}
type SerialUnion struct {
Union interface{}
Pipe *SerialConfigPipe
File *SerialConfigFile
Device *SerialConfigDevice
Auto *SerialConfigAuto
}
func (c *HWConfig) HasSerial() bool {
return c.Serial != ""
}
func (c *HWConfig) ReadSerial() (*SerialUnion, error) {
var defaultSerialPort string
if runtime.GOOS == "windows" {
defaultSerialPort = "COM1"
} else {
defaultSerialPort = "/dev/ttyS0"
}
input := strings.SplitN(c.Serial, ":", 2)
if len(input) < 1 {
return nil, fmt.Errorf("Unexpected format for serial port: %s", c.Serial)
}
var formatType, formatOptions string
formatType = input[0]
if len(input) == 2 {
formatOptions = input[1]
} else {
formatOptions = ""
}
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", c.Serial)
}
if res := strings.ToLower(comp[1]); res != "client" && res != "server" {
return nil, fmt.Errorf("Unexpected format for endpoint in serial port pipe: %s -> %s", c.Serial, res)
}
if res := strings.ToLower(comp[2]); res != "app" && res != "vm" {
return nil, fmt.Errorf("Unexpected format for host in serial port pipe: %s -> %s", c.Serial, res)
}
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 yield in serial port pipe: %s -> %s", c.Serial, res.Yield)
}
return &SerialUnion{Union: 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", c.Serial)
}
res := &SerialConfigFile{Yield: "FALSE"}
res.Filename = filepath.FromSlash(comp[0])
res.Yield = map[bool]string{true: strings.ToUpper(comp[1]), false: "FALSE"}[len(comp) > 1]
if res.Yield != "TRUE" && res.Yield != "FALSE" {
return nil, fmt.Errorf("Unexpected format for yield in serial port file: %s -> %s", c.Serial, res.Yield)
}
return &SerialUnion{Union: 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", c.Serial)
}
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 yield in serial port device: %s -> %s", c.Serial, res.Yield)
}
return &SerialUnion{Union: res, Device: res}, nil
case "AUTO":
res := new(SerialConfigAuto)
res.Devicename = defaultSerialPort
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 yield in serial port auto: %s -> %s", c.Serial, res.Yield)
}
return &SerialUnion{Union: res, Auto: res}, nil
case "NONE":
return &SerialUnion{Union: nil}, nil
default:
return nil, fmt.Errorf("Unknown serial type %s: %s", strings.ToUpper(formatType), c.Serial)
}
}

View File

@ -0,0 +1,319 @@
package common
import (
"strings"
"testing"
)
func testHWConfig() *HWConfig {
return &HWConfig{
CpuCount: 1,
MemorySize: 512,
Sound: true,
USB: true,
}
}
func TestHWConfigPrepare(t *testing.T) {
c := new(HWConfig)
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if c.CpuCount < 1 {
t.Errorf("bad cpu count: %d", c.CpuCount)
}
if c.MemorySize < 0 {
t.Errorf("bad memory size: %d", c.MemorySize)
}
if c.Sound {
t.Errorf("peripheral choice (sound) should be conservative: %t", c.Sound)
}
if c.USB {
t.Errorf("peripheral choice (usb) should be conservative: %t", c.USB)
}
if strings.ToUpper(c.Parallel) != "NONE" {
t.Errorf("parallel port should not be defined: %s", c.Parallel)
}
if strings.ToUpper(c.Serial) != "NONE" {
t.Errorf("serial port should not be defined: %s", c.Serial)
}
}
func TestHWConfigParallel_File(t *testing.T) {
c := new(HWConfig)
c.Parallel = "file:filename"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasParallel() {
t.Errorf("parallel port should be defined")
}
parallel, err := c.ReadParallel()
if err != nil {
t.Fatalf("Unable to read parallel port definition: %s", err)
}
switch parallel.Union.(type) {
case *ParallelPortFile:
break
default:
t.Errorf("parallel port should be a file type")
}
if parallel.File.Filename != "filename" {
t.Errorf("parallel port filename should be \"filename\": %s", parallel.File.Filename)
}
}
func TestHWConfigParallel_Device(t *testing.T) {
c := new(HWConfig)
c.Parallel = "device:devicename,uni"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasParallel() {
t.Errorf("parallel port should be defined")
}
parallel, err := c.ReadParallel()
if err != nil {
t.Fatalf("Unable to read parallel port definition: %s", err)
}
switch parallel.Union.(type) {
case *ParallelPortDevice:
break
default:
t.Errorf("parallel port should be a device type")
}
if strings.ToLower(parallel.Device.Bidirectional) != "false" {
t.Errorf("parallel port device should not be bidirectional: %s", parallel.Device.Bidirectional)
}
if parallel.Device.Devicename != "devicename" {
t.Errorf("parallel port device should be \"devicename\": %s", parallel.Device.Devicename)
}
}
func TestHWConfigParallel_Auto(t *testing.T) {
c := new(HWConfig)
c.Parallel = "auto:bi"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasParallel() {
t.Errorf("parallel port should be defined")
}
parallel, err := c.ReadParallel()
if err != nil {
t.Fatalf("Unable to read parallel port definition: %s", err)
}
switch parallel.Union.(type) {
case *ParallelPortAuto:
break
default:
t.Errorf("parallel port should be an auto type")
}
if strings.ToLower(parallel.Auto.Bidirectional) != "true" {
t.Errorf("parallel port device should be bidirectional: %s", parallel.Auto.Bidirectional)
}
}
func TestHWConfigParallel_None(t *testing.T) {
c := new(HWConfig)
c.Parallel = "none"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasParallel() {
t.Errorf("parallel port should be defined")
}
parallel, err := c.ReadParallel()
if err != nil {
t.Fatalf("Unable to read parallel port definition: %s", err)
}
if parallel.Union != nil {
t.Errorf("parallel port shouldn't exist")
}
}
func TestHWConfigSerial_File(t *testing.T) {
c := new(HWConfig)
c.Serial = "file:filename,true"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasSerial() {
t.Errorf("serial port should be defined")
}
serial, err := c.ReadSerial()
if err != nil {
t.Fatalf("Unable to read serial port definition: %s", err)
}
switch serial.Union.(type) {
case *SerialConfigFile:
break
default:
t.Errorf("serial port should be a file type")
}
if serial.File.Filename != "filename" {
t.Errorf("serial port filename should be \"filename\": %s", serial.File.Filename)
}
if strings.ToLower(serial.File.Yield) != "true" {
t.Errorf("serial port yield should be true: %s", serial.File.Yield)
}
}
func TestHWConfigSerial_Device(t *testing.T) {
c := new(HWConfig)
c.Serial = "device:devicename,true"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasSerial() {
t.Errorf("serial port should be defined")
}
serial, err := c.ReadSerial()
if err != nil {
t.Fatalf("Unable to read serial port definition: %s", err)
}
switch serial.Union.(type) {
case *SerialConfigDevice:
break
default:
t.Errorf("serial port should be a device type")
}
if serial.Device.Devicename != "devicename" {
t.Errorf("serial port device should be \"devicename\": %s", serial.Device.Devicename)
}
if strings.ToLower(serial.Device.Yield) != "true" {
t.Errorf("serial port device should yield: %s", serial.Device.Yield)
}
}
func TestHWConfigSerial_Pipe(t *testing.T) {
c := new(HWConfig)
c.Serial = "pipe:mypath,client,app,true"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasSerial() {
t.Errorf("serial port should be defined")
}
serial, err := c.ReadSerial()
if err != nil {
t.Fatalf("Unable to read serial port definition: %s", err)
}
switch serial.Union.(type) {
case *SerialConfigPipe:
break
default:
t.Errorf("serial port should be a pipe type")
}
if serial.Pipe.Filename != "mypath" {
t.Errorf("serial port pipe name should be \"mypath\": %s", serial.Pipe.Filename)
}
if strings.ToLower(serial.Pipe.Endpoint) != "client" {
t.Errorf("serial port endpoint should be \"client\": %s", serial.Pipe.Endpoint)
}
if strings.ToLower(serial.Pipe.Host) != "true" {
t.Errorf("serial port host type for app should be true: %s", serial.Pipe.Host)
}
if strings.ToLower(serial.Pipe.Yield) != "true" {
t.Errorf("serial port should yield: %s", serial.Pipe.Yield)
}
}
func TestHWConfigSerial_Auto(t *testing.T) {
c := new(HWConfig)
c.Serial = "auto:true"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasSerial() {
t.Errorf("serial port should be defined")
}
serial, err := c.ReadSerial()
if err != nil {
t.Fatalf("Unable to read serial port definition: %s", err)
}
switch serial.Union.(type) {
case *SerialConfigAuto:
break
default:
t.Errorf("serial port should be an auto type")
}
if strings.ToLower(serial.Auto.Yield) != "true" {
t.Errorf("serial port should yield: %s", serial.Auto.Yield)
}
}
func TestHWConfigSerial_None(t *testing.T) {
c := new(HWConfig)
c.Serial = "none"
if errs := c.Prepare(testConfigTemplate(t)); len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !c.HasSerial() {
t.Errorf("serial port should be defined")
}
serial, err := c.ReadSerial()
if err != nil {
t.Fatalf("Unable to read serial port definition: %s", err)
}
if serial.Union != nil {
t.Errorf("serial port shouldn't exist")
}
}

View File

@ -21,6 +21,7 @@ type Config struct {
common.FloppyConfig `mapstructure:",squash"`
bootcommand.VNCConfig `mapstructure:",squash"`
vmwcommon.DriverConfig `mapstructure:",squash"`
vmwcommon.HWConfig `mapstructure:",squash"`
vmwcommon.OutputConfig `mapstructure:",squash"`
vmwcommon.RunConfig `mapstructure:",squash"`
vmwcommon.ShutdownConfig `mapstructure:",squash"`
@ -45,18 +46,6 @@ type Config struct {
Version string `mapstructure:"version"`
VMName string `mapstructure:"vm_name"`
// Network adapter and type
NetworkAdapterType string `mapstructure:"network_adapter_type"`
Network string `mapstructure:"network"`
// device presence
Sound bool `mapstructure:"sound"`
USB bool `mapstructure:"usb"`
// communication ports
Serial string `mapstructure:"serial"`
Parallel string `mapstructure:"parallel"`
VMXDiskTemplatePath string `mapstructure:"vmx_disk_template_path"`
VMXTemplatePath string `mapstructure:"vmx_template_path"`
@ -87,6 +76,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
warnings = append(warnings, isoWarnings...)
errs = packer.MultiErrorAppend(errs, isoErrs...)
errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.HWConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs, c.DriverConfig.Prepare(&c.ctx)...)
errs = packer.MultiErrorAppend(errs,
c.OutputConfig.Prepare(&c.ctx, &c.PackerConfig)...)
@ -160,16 +150,8 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
}
}
if c.Network == "" {
c.Network = "nat"
}
if !c.Sound {
c.Sound = false
}
if !c.USB {
c.USB = false
if c.HWConfig.Network == "" {
c.HWConfig.Network = "nat"
}
// Remote configuration validation

View File

@ -6,7 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
vmwcommon "github.com/hashicorp/packer/builder/vmware/common"
@ -21,6 +21,9 @@ type vmxTemplateData struct {
ISOPath string
Version string
CpuCount string
MemorySize string
HDD_BootOrder string
SCSI_Present string
@ -72,227 +75,6 @@ type stepCreateVMX struct {
tempDir string
}
/* serial conversions */
type serialConfigPipe struct {
filename string
endpoint string
host string
yield string
}
type serialConfigFile struct {
filename string
yield string
}
type serialConfigDevice struct {
devicename string
yield string
}
type serialConfigAuto struct {
devicename string
yield string
}
type serialUnion struct {
serialType interface{}
pipe *serialConfigPipe
file *serialConfigFile
device *serialConfigDevice
auto *serialConfigAuto
}
func unformat_serial(config string) (*serialUnion, error) {
var defaultSerialPort string
if runtime.GOOS == "windows" {
defaultSerialPort = "COM1"
} else {
defaultSerialPort = "/dev/ttyS0"
}
input := strings.SplitN(config, ":", 2)
if len(input) < 1 {
return nil, fmt.Errorf("Unexpected format for serial port: %s", config)
}
var formatType, formatOptions string
formatType = input[0]
if len(input) == 2 {
formatOptions = input[1]
} else {
formatOptions = ""
}
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 "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.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)
}
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)
}
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)
res.devicename = defaultSerialPort
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
case "NONE":
return &serialUnion{serialType: nil}, 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
}
type parallelPortFile struct {
filename string
}
type parallelPortDevice struct {
bidirectional string
devicename string
}
type parallelPortAuto struct {
bidirectional string
}
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)
}
var formatType, formatOptions string
formatType = input[0]
if len(input) == 2 {
formatOptions = input[1]
} else {
formatOptions = ""
}
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)
}
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)
}
}
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 "NONE":
return &parallelUnion{parallelType: nil}, nil
}
return nil, fmt.Errorf("Unexpected format for parallel port: %s", config)
}
/* regular steps */
func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
@ -378,6 +160,9 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
Version: config.Version,
ISOPath: isoPath,
CpuCount: strconv.Itoa(config.HWConfig.CpuCount),
MemorySize: strconv.Itoa(config.HWConfig.MemorySize),
SCSI_Present: "FALSE",
SCSI_diskAdapterType: "lsilogic",
SATA_Present: "FALSE",
@ -390,8 +175,8 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
Network_Adapter: "e1000",
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.HWConfig.Sound)],
Usb_Present: map[bool]string{true: "TRUE", false: "FALSE"}[bool(config.HWConfig.USB)],
Serial_Present: "FALSE",
Parallel_Present: "FALSE",
@ -462,13 +247,13 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
}
/// Assign the network adapter type into the template if one was specified.
network_adapter := strings.ToLower(config.NetworkAdapterType)
network_adapter := strings.ToLower(config.HWConfig.NetworkAdapterType)
if network_adapter != "" {
templateData.Network_Adapter = network_adapter
}
/// Check the network type that the user specified
network := config.Network
network := config.HWConfig.Network
driver := state.Get("driver").(vmwcommon.Driver).GetVmwareDriver()
// check to see if the driver implements a network mapper for mapping
@ -514,10 +299,11 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
state.Put("vmnetwork", network)
/// check if serial port has been configured
if config.Serial == "" {
if !config.HWConfig.HasSerial() {
templateData.Serial_Present = "FALSE"
} else {
serial, err := unformat_serial(config.Serial)
// FIXME
serial, err := config.HWConfig.ReadSerial()
if err != nil {
err := fmt.Errorf("Error processing VMX template: %s", err)
state.Put("error", err)
@ -532,23 +318,23 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
templateData.Serial_Host = ""
templateData.Serial_Auto = "FALSE"
switch serial.serialType.(type) {
case *serialConfigPipe:
switch serial.Union.(type) {
case *vmwcommon.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_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 *vmwcommon.SerialConfigFile:
templateData.Serial_Type = "file"
templateData.Serial_Filename = filepath.FromSlash(serial.file.filename)
case *serialConfigDevice:
templateData.Serial_Filename = filepath.FromSlash(serial.File.Filename)
case *vmwcommon.SerialConfigDevice:
templateData.Serial_Type = "device"
templateData.Serial_Filename = filepath.FromSlash(serial.device.devicename)
case *serialConfigAuto:
templateData.Serial_Filename = filepath.FromSlash(serial.Device.Devicename)
case *vmwcommon.SerialConfigAuto:
templateData.Serial_Type = "device"
templateData.Serial_Filename = filepath.FromSlash(serial.auto.devicename)
templateData.Serial_Yield = serial.auto.yield
templateData.Serial_Filename = filepath.FromSlash(serial.Auto.Devicename)
templateData.Serial_Yield = serial.Auto.Yield
templateData.Serial_Auto = "TRUE"
case nil:
templateData.Serial_Present = "FALSE"
@ -563,10 +349,11 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
}
/// check if parallel port has been configured
if config.Parallel == "" {
if !config.HWConfig.HasParallel() {
templateData.Parallel_Present = "FALSE"
} else {
parallel, err := unformat_parallel(config.Parallel)
// FIXME
parallel, err := config.HWConfig.ReadParallel()
if err != nil {
err := fmt.Errorf("Error processing VMX template: %s", err)
state.Put("error", err)
@ -575,18 +362,18 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
}
templateData.Parallel_Auto = "FALSE"
switch parallel.parallelType.(type) {
case *parallelPortFile:
switch parallel.Union.(type) {
case *vmwcommon.ParallelPortFile:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Filename = filepath.FromSlash(parallel.file.filename)
case *parallelPortDevice:
templateData.Parallel_Filename = filepath.FromSlash(parallel.File.Filename)
case *vmwcommon.ParallelPortDevice:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Bidirectional = parallel.device.bidirectional
templateData.Parallel_Filename = filepath.FromSlash(parallel.device.devicename)
case *parallelPortAuto:
templateData.Parallel_Bidirectional = parallel.Device.Bidirectional
templateData.Parallel_Filename = filepath.FromSlash(parallel.Device.Devicename)
case *vmwcommon.ParallelPortAuto:
templateData.Parallel_Present = "TRUE"
templateData.Parallel_Auto = "TRUE"
templateData.Parallel_Bidirectional = parallel.auto.bidirectional
templateData.Parallel_Bidirectional = parallel.Auto.Bidirectional
case nil:
templateData.Parallel_Present = "FALSE"
break
@ -654,7 +441,8 @@ const DefaultVMXTemplate = `
displayName = "{{ .Name }}"
// Hardware
memsize = "512"
numvcpus = "{{ .CpuCount }}"
memsize = "{{ .MemorySize }}"
config.version = "8"
virtualHW.productCompatibility = "hosted"