Merge pull request #7019 from arizvisa/vmware.cpu-memory
Add configuration options to vmware builder to specify cpu count and memory size
This commit is contained in:
commit
e539133d8c
|
@ -0,0 +1,290 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type HWConfig struct {
|
||||
|
||||
// cpu information
|
||||
CpuCount int `mapstructure:"cpus"`
|
||||
MemorySize int `mapstructure:"memory"`
|
||||
|
||||
// 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 number of cpus was specified (cpus < 0): %d", c.CpuCount))
|
||||
}
|
||||
|
||||
if c.MemorySize < 0 {
|
||||
errs = append(errs, fmt.Errorf("An invalid amount of memory was specified (memory < 0): %d", c.MemorySize))
|
||||
}
|
||||
|
||||
// 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 errs
|
||||
}
|
||||
|
||||
/* 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)
|
||||
}
|
||||
}
|
|
@ -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 < 0 {
|
||||
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")
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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 := ¶llelPortFile{filename: filepath.FromSlash(formatOptions)}
|
||||
return ¶llelUnion{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 ¶llelUnion{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 ¶llelUnion{parallelType: res, auto: res}, nil
|
||||
|
||||
case "NONE":
|
||||
return ¶llelUnion{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)
|
||||
|
@ -390,8 +172,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 +244,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 +296,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 +315,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 +346,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 +359,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
|
||||
|
@ -626,8 +410,22 @@ func (s *stepCreateVMX) Run(_ context.Context, state multistep.StateBag) multist
|
|||
s.tempDir = vmxDir
|
||||
}
|
||||
|
||||
/// Now to handle options that will modify the template
|
||||
vmxData := vmwcommon.ParseVMX(vmxContents)
|
||||
|
||||
// Set the number of cpus if it was specified
|
||||
if config.HWConfig.CpuCount > 0 {
|
||||
vmxData["numvcpus"] = strconv.Itoa(config.HWConfig.CpuCount)
|
||||
}
|
||||
|
||||
// Apply the memory size that was specified
|
||||
if config.HWConfig.MemorySize > 0 {
|
||||
vmxData["memsize"] = strconv.Itoa(config.HWConfig.MemorySize)
|
||||
}
|
||||
|
||||
/// Write the vmxData to the vmxPath
|
||||
vmxPath := filepath.Join(vmxDir, config.VMName+".vmx")
|
||||
if err := vmwcommon.WriteVMX(vmxPath, vmwcommon.ParseVMX(vmxContents)); err != nil {
|
||||
if err := vmwcommon.WriteVMX(vmxPath, vmxData); err != nil {
|
||||
err := fmt.Errorf("Error creating VMX file: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
|
@ -650,49 +448,51 @@ func (s *stepCreateVMX) Cleanup(multistep.StateBag) {
|
|||
// do so by specifying in the builder configuration.
|
||||
const DefaultVMXTemplate = `
|
||||
.encoding = "UTF-8"
|
||||
|
||||
displayName = "{{ .Name }}"
|
||||
|
||||
// Hardware
|
||||
numvcpus = "{{ .CpuCount }}"
|
||||
memsize = "{{ .MemorySize }}"
|
||||
|
||||
config.version = "8"
|
||||
virtualHW.productCompatibility = "hosted"
|
||||
virtualHW.version = "{{ .Version }}"
|
||||
|
||||
// Bootup
|
||||
nvram = "{{ .Name }}.nvram"
|
||||
|
||||
floppy0.present = "FALSE"
|
||||
bios.bootOrder = "hdd,cdrom"
|
||||
bios.hddOrder = "{{ .HDD_BootOrder }}"
|
||||
checkpoint.vmState = ""
|
||||
cleanShutdown = "TRUE"
|
||||
config.version = "8"
|
||||
displayName = "{{ .Name }}"
|
||||
ehci.pciSlotNumber = "34"
|
||||
ehci.present = "TRUE"
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.bsdName = "en0"
|
||||
ethernet0.connectionType = "{{ .Network_Type }}"
|
||||
ethernet0.vnet = "{{ .Network_Device }}"
|
||||
ethernet0.displayName = "Ethernet"
|
||||
ethernet0.linkStatePropagation.enable = "FALSE"
|
||||
ethernet0.pciSlotNumber = "33"
|
||||
ethernet0.present = "TRUE"
|
||||
ethernet0.virtualDev = "{{ .Network_Adapter }}"
|
||||
ethernet0.wakeOnPcktRcv = "FALSE"
|
||||
|
||||
// Configuration
|
||||
extendedConfigFile = "{{ .Name }}.vmxf"
|
||||
floppy0.present = "FALSE"
|
||||
guestOS = "{{ .GuestOS }}"
|
||||
gui.fullScreenAtPowerOn = "FALSE"
|
||||
gui.viewModeAtPowerOn = "windowed"
|
||||
hgfs.linkRootShare = "TRUE"
|
||||
hgfs.mapRootShare = "TRUE"
|
||||
|
||||
scsi0.present = "{{ .SCSI_Present }}"
|
||||
scsi0.virtualDev = "{{ .SCSI_diskAdapterType }}"
|
||||
scsi0.pciSlotNumber = "16"
|
||||
scsi0:0.redo = ""
|
||||
sata0.present = "{{ .SATA_Present }}"
|
||||
nvme0.present = "{{ .NVME_Present }}"
|
||||
|
||||
{{ .DiskType }}0:0.present = "TRUE"
|
||||
{{ .DiskType }}0:0.fileName = "{{ .DiskName }}.vmdk"
|
||||
|
||||
{{ .CDROMType }}0:{{ .CDROMType_PrimarySecondary }}.present = "TRUE"
|
||||
{{ .CDROMType }}0:{{ .CDROMType_PrimarySecondary }}.fileName = "{{ .ISOPath }}"
|
||||
{{ .CDROMType }}0:{{ .CDROMType_PrimarySecondary }}.deviceType = "cdrom-image"
|
||||
|
||||
isolation.tools.hgfs.disable = "FALSE"
|
||||
memsize = "512"
|
||||
nvram = "{{ .Name }}.nvram"
|
||||
proxyApps.publishToHost = "FALSE"
|
||||
replay.filename = ""
|
||||
replay.supported = "FALSE"
|
||||
|
||||
checkpoint.vmState = ""
|
||||
vmotion.checkpointFBSize = "65536000"
|
||||
|
||||
// Power control
|
||||
cleanShutdown = "TRUE"
|
||||
powerType.powerOff = "soft"
|
||||
powerType.powerOn = "soft"
|
||||
powerType.reset = "soft"
|
||||
powerType.suspend = "soft"
|
||||
|
||||
// Tools
|
||||
guestOS = "{{ .GuestOS }}"
|
||||
tools.syncTime = "TRUE"
|
||||
tools.upgrade.policy = "upgradeAtPowerCycle"
|
||||
|
||||
// Bus
|
||||
pciBridge0.pciSlotNumber = "17"
|
||||
pciBridge0.present = "TRUE"
|
||||
pciBridge4.functions = "8"
|
||||
|
@ -711,13 +511,40 @@ pciBridge7.functions = "8"
|
|||
pciBridge7.pciSlotNumber = "24"
|
||||
pciBridge7.present = "TRUE"
|
||||
pciBridge7.virtualDev = "pcieRootPort"
|
||||
powerType.powerOff = "soft"
|
||||
powerType.powerOn = "soft"
|
||||
powerType.reset = "soft"
|
||||
powerType.suspend = "soft"
|
||||
proxyApps.publishToHost = "FALSE"
|
||||
replay.filename = ""
|
||||
replay.supported = "FALSE"
|
||||
|
||||
ehci.present = "TRUE"
|
||||
ehci.pciSlotNumber = "34"
|
||||
|
||||
vmci0.present = "TRUE"
|
||||
vmci0.id = "1861462627"
|
||||
vmci0.pciSlotNumber = "35"
|
||||
|
||||
// Network Adapter
|
||||
ethernet0.addressType = "generated"
|
||||
ethernet0.bsdName = "en0"
|
||||
ethernet0.connectionType = "{{ .Network_Type }}"
|
||||
ethernet0.vnet = "{{ .Network_Device }}"
|
||||
ethernet0.displayName = "Ethernet"
|
||||
ethernet0.linkStatePropagation.enable = "FALSE"
|
||||
ethernet0.pciSlotNumber = "33"
|
||||
ethernet0.present = "TRUE"
|
||||
ethernet0.virtualDev = "{{ .Network_Adapter }}"
|
||||
ethernet0.wakeOnPcktRcv = "FALSE"
|
||||
|
||||
// Hard disks
|
||||
scsi0.present = "{{ .SCSI_Present }}"
|
||||
scsi0.virtualDev = "{{ .SCSI_diskAdapterType }}"
|
||||
scsi0.pciSlotNumber = "16"
|
||||
scsi0:0.redo = ""
|
||||
sata0.present = "{{ .SATA_Present }}"
|
||||
nvme0.present = "{{ .NVME_Present }}"
|
||||
|
||||
{{ .DiskType }}0:0.present = "TRUE"
|
||||
{{ .DiskType }}0:0.fileName = "{{ .DiskName }}.vmdk"
|
||||
|
||||
{{ .CDROMType }}0:{{ .CDROMType_PrimarySecondary }}.present = "TRUE"
|
||||
{{ .CDROMType }}0:{{ .CDROMType_PrimarySecondary }}.fileName = "{{ .ISOPath }}"
|
||||
{{ .CDROMType }}0:{{ .CDROMType_PrimarySecondary }}.deviceType = "cdrom-image"
|
||||
|
||||
// Sound
|
||||
sound.startConnected = "{{ .Sound_Present }}"
|
||||
|
@ -725,9 +552,6 @@ sound.present = "{{ .Sound_Present }}"
|
|||
sound.fileName = "-1"
|
||||
sound.autodetect = "TRUE"
|
||||
|
||||
tools.syncTime = "TRUE"
|
||||
tools.upgrade.policy = "upgradeAtPowerCycle"
|
||||
|
||||
// USB
|
||||
usb.pciSlotNumber = "32"
|
||||
usb.present = "{{ .Usb_Present }}"
|
||||
|
@ -748,13 +572,6 @@ parallel0.startConnected = "{{ .Parallel_Present }}"
|
|||
parallel0.fileName = "{{ .Parallel_Filename }}"
|
||||
parallel0.autodetect = "{{ .Parallel_Auto }}"
|
||||
parallel0.bidirectional = "{{ .Parallel_Bidirectional }}"
|
||||
|
||||
virtualHW.productCompatibility = "hosted"
|
||||
virtualHW.version = "{{ .Version }}"
|
||||
vmci0.id = "1861462627"
|
||||
vmci0.pciSlotNumber = "35"
|
||||
vmci0.present = "TRUE"
|
||||
vmotion.checkpointFBSize = "65536000"
|
||||
`
|
||||
|
||||
const DefaultAdditionalDiskTemplate = `
|
||||
|
|
|
@ -98,6 +98,8 @@ builder.
|
|||
five seconds and one minute 30 seconds, respectively. If this isn't
|
||||
specified, the default is `10s` or 10 seconds.
|
||||
|
||||
- `cpus` (number) - The number of cpus to use when building the VM.
|
||||
|
||||
- `cdrom_adapter_type` (string) - The adapter type (or bus) that will be used
|
||||
by the cdrom device. This is chosen by default based on the disk adapter
|
||||
type. VMware tends to lean towards `ide` for the cdrom device unless
|
||||
|
@ -221,6 +223,9 @@ builder.
|
|||
URLs must point to the same file (same checksum). By default this is empty
|
||||
and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified.
|
||||
|
||||
- `memory` (number) - The amount of memory to use when building the VM
|
||||
in megabytes.
|
||||
|
||||
- `network` (string) - This is the network type that the virtual machine will
|
||||
be created with. This can be one of the generic values that map to a device
|
||||
such as `hostonly`, `nat`, or `bridged`. If the network is not one of these
|
||||
|
@ -371,7 +376,8 @@ builder.
|
|||
given are valid. If you set this flag to `true`, Packer will skip this
|
||||
validation. Default: `false`.
|
||||
|
||||
- `sound` (boolean) - Enable VMware's virtual soundcard device for the VM.
|
||||
- `sound` (boolean) - Specify whether to enable VMware's virtual soundcard
|
||||
device when building the VM. Defaults to `false`.
|
||||
|
||||
- `tools_upload_flavor` (string) - The flavor of the VMware Tools ISO to
|
||||
upload into the VM. Valid values are `darwin`, `linux`, and `windows`. By
|
||||
|
@ -385,9 +391,10 @@ builder.
|
|||
By default the upload path is set to `{{.Flavor}}.iso`. This setting is not
|
||||
used when `remote_type` is `esx5`.
|
||||
|
||||
- `usb` (boolean) - Enable VMware's USB bus for the guest VM. To enable usage
|
||||
of the XHCI bus for USB 3 (5 Gbit/s), one can use the `vmx_data` option to
|
||||
enable it by specifying `true` for the `usb_xhci.present` property.
|
||||
- `usb` (boolean) - Enable VMware's USB bus when building the guest VM.
|
||||
Defaults to `false`. To enable usage of the XHCI bus for USB 3 (5 Gbit/s),
|
||||
one can use the `vmx_data` option to enable it by specifying `true` for
|
||||
the `usb_xhci.present` property.
|
||||
|
||||
- `version` (string) - The [vmx hardware
|
||||
version](http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1003746)
|
||||
|
@ -403,7 +410,7 @@ builder.
|
|||
|
||||
- `vmx_data` (object of key/value strings) - Arbitrary key/values to enter
|
||||
into the virtual machine VMX file. This is for advanced users who want to
|
||||
set properties such as memory, CPU, etc.
|
||||
set properties that aren't yet supported by the builder.
|
||||
|
||||
- `vmx_data_post` (object of key/value strings) - Identical to `vmx_data`,
|
||||
except that it is run after the virtual machine is shutdown, and before the
|
||||
|
|
Loading…
Reference in New Issue