diff --git a/builder/vmware/builder.go b/builder/vmware/builder.go index 70ce9f507..fd27d20c0 100644 --- a/builder/vmware/builder.go +++ b/builder/vmware/builder.go @@ -58,6 +58,7 @@ type config struct { bootWait time.Duration `` shutdownTimeout time.Duration `` sshWaitTimeout time.Duration `` + tpl *common.Template } func (b *Builder) Prepare(raws ...interface{}) error { @@ -66,6 +67,11 @@ func (b *Builder) Prepare(raws ...interface{}) error { return err } + b.config.tpl, err = common.NewTemplate() + if err != nil { + return err + } + // Accumulate any errors errs := common.CheckUnusedConfig(md) @@ -121,6 +127,72 @@ func (b *Builder) Prepare(raws ...interface{}) error { b.config.ToolsUploadPath = "{{ .Flavor }}.iso" } + // Errors + templates := map[string]*string{ + "disk_name": &b.config.DiskName, + "guest_os_type": &b.config.GuestOSType, + "http_directory": &b.config.HTTPDir, + "iso_checksum": &b.config.ISOChecksum, + "iso_checksum_type": &b.config.ISOChecksumType, + "iso_url": &b.config.ISOUrl, + "output_directory": &b.config.OutputDir, + "shutdown_command": &b.config.ShutdownCommand, + "ssh_password": &b.config.SSHPassword, + "ssh_username": &b.config.SSHUser, + "tools_upload_flavor": &b.config.ToolsUploadFlavor, + "vm_name": &b.config.VMName, + "boot_wait": &b.config.RawBootWait, + "shutdown_timeout": &b.config.RawShutdownTimeout, + "ssh_wait_timeout": &b.config.RawSSHWaitTimeout, + } + + for n, ptr := range templates { + var err error + *ptr, err = b.config.tpl.Process(*ptr, nil) + if err != nil { + errs = packer.MultiErrorAppend( + errs, fmt.Errorf("Error processing %s: %s", n, err)) + } + } + + for i, command := range b.config.BootCommand { + if err := b.config.tpl.Validate(command); err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Error processing boot_command[%d]: %s", i, err)) + } + } + + for i, file := range b.config.FloppyFiles { + var err error + b.config.FloppyFiles[i], err = b.config.tpl.Process(file, nil) + if err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Error processing floppy_files[%d]: %s", + i, err)) + } + } + + newVMXData := make(map[string]string) + for k, v := range b.config.VMXData { + k, err = b.config.tpl.Process(k, nil) + if err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Error processing VMX data key %s: %s", k, err)) + continue + } + + v, err = b.config.tpl.Process(v, nil) + if err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Error processing VMX data value '%s': %s", v, err)) + continue + } + + newVMXData[k] = v + } + + b.config.VMXData = newVMXData + if b.config.HTTPPortMin > b.config.HTTPPortMax { errs = packer.MultiErrorAppend( errs, errors.New("http_port_min must be less than http_port_max")) diff --git a/builder/vmware/step_type_boot_command.go b/builder/vmware/step_type_boot_command.go index 86224e5ff..e3f971f05 100644 --- a/builder/vmware/step_type_boot_command.go +++ b/builder/vmware/step_type_boot_command.go @@ -1,7 +1,6 @@ package vmware import ( - "bytes" "fmt" "github.com/mitchellh/go-vnc" "github.com/mitchellh/multistep" @@ -10,7 +9,6 @@ import ( "net" "runtime" "strings" - "text/template" "time" "unicode" "unicode/utf8" @@ -90,11 +88,15 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc ui.Say("Typing the boot command over VNC...") for _, command := range config.BootCommand { - var buf bytes.Buffer - t := template.Must(template.New("boot").Parse(command)) - t.Execute(&buf, tplData) + command, err := config.tpl.Process(command, tplData) + if err != nil { + err := fmt.Errorf("Error preparing boot command: %s", err) + state["error"] = err + ui.Error(err.Error()) + return multistep.ActionHalt + } - vncSendString(c, buf.String()) + vncSendString(c, command) } return multistep.ActionContinue diff --git a/builder/vmware/step_upload_tools.go b/builder/vmware/step_upload_tools.go index dfe4dfa39..0e0b03743 100644 --- a/builder/vmware/step_upload_tools.go +++ b/builder/vmware/step_upload_tools.go @@ -1,12 +1,10 @@ package vmware import ( - "bytes" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "os" - "text/template" ) type toolsUploadPathTemplate struct { @@ -34,11 +32,8 @@ func (*stepUploadTools) Run(state map[string]interface{}) multistep.StepAction { defer f.Close() tplData := &toolsUploadPathTemplate{Flavor: config.ToolsUploadFlavor} - var processedPath bytes.Buffer - t := template.Must(template.New("path").Parse(config.ToolsUploadPath)) - t.Execute(&processedPath, tplData) - - if err := comm.Upload(processedPath.String(), f); err != nil { + config.ToolsUploadPath, err = config.tpl.Process(config.ToolsUploadPath, tplData) + if err := comm.Upload(config.ToolsUploadPath, f); err != nil { state["error"] = fmt.Errorf("Error uploading VMware Tools: %s", err) return multistep.ActionHalt }