diff --git a/builder/virtualbox/builder.go b/builder/virtualbox/builder.go index 5033f6509..1bdc6c5fc 100644 --- a/builder/virtualbox/builder.go +++ b/builder/virtualbox/builder.go @@ -57,6 +57,7 @@ type config struct { bootWait time.Duration `` shutdownTimeout time.Duration `` sshWaitTimeout time.Duration `` + tpl *common.Template } func (b *Builder) Prepare(raws ...interface{}) error { @@ -65,6 +66,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) @@ -124,6 +130,53 @@ func (b *Builder) Prepare(raws ...interface{}) error { b.config.VMName = fmt.Sprintf("packer-%s", b.config.PackerBuildName) } + // Errors + templates := map[string]*string{ + "guest_additions_path": &b.config.GuestAdditionsPath, + "guest_additions_url": &b.config.GuestAdditionsURL, + "guest_additions_sha256": &b.config.GuestAdditionsSHA256, + "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, + "virtualbox_version_file": &b.config.VBoxVersionFile, + "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)) + } + } + if b.config.HTTPPortMin > b.config.HTTPPortMax { errs = packer.MultiErrorAppend( errs, errors.New("http_port_min must be less than http_port_max")) @@ -215,6 +268,15 @@ func (b *Builder) Prepare(raws ...interface{}) error { errs, fmt.Errorf("Failed parsing ssh_wait_timeout: %s", err)) } + for i, args := range b.config.VBoxManage { + for j, arg := range args { + if err := b.config.tpl.Validate(arg); err != nil { + errs = packer.MultiErrorAppend(errs, + fmt.Errorf("Error processing vboxmanage[%d][%d]: %s", i, j, err)) + } + } + } + b.driver, err = b.newDriver() if err != nil { errs = packer.MultiErrorAppend( diff --git a/builder/virtualbox/step_type_boot_command.go b/builder/virtualbox/step_type_boot_command.go index 294ad73b0..910c122fe 100644 --- a/builder/virtualbox/step_type_boot_command.go +++ b/builder/virtualbox/step_type_boot_command.go @@ -1,13 +1,11 @@ package virtualbox import ( - "bytes" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "log" "strings" - "text/template" "time" "unicode" "unicode/utf8" @@ -49,11 +47,15 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc ui.Say("Typing the boot command...") 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 + } - for _, code := range scancodes(buf.String()) { + for _, code := range scancodes(command) { if code == "wait" { time.Sleep(1 * time.Second) continue diff --git a/builder/virtualbox/step_upload_guest_additions.go b/builder/virtualbox/step_upload_guest_additions.go index 81b6f49fd..32d3a0587 100644 --- a/builder/virtualbox/step_upload_guest_additions.go +++ b/builder/virtualbox/step_upload_guest_additions.go @@ -1,12 +1,10 @@ package virtualbox import ( - "bytes" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "os" - "text/template" ) type guestAdditionsPathTemplate struct { @@ -39,12 +37,16 @@ func (s *stepUploadGuestAdditions) Run(state map[string]interface{}) multistep.S Version: version, } - var processedPath bytes.Buffer - t := template.Must(template.New("path").Parse(config.GuestAdditionsPath)) - t.Execute(&processedPath, tplData) + config.GuestAdditionsPath, err = config.tpl.Process(config.GuestAdditionsPath, tplData) + if err != nil { + err := fmt.Errorf("Error preparing guest additions path: %s", err) + state["error"] = err + ui.Error(err.Error()) + return multistep.ActionHalt + } ui.Say("Uploading VirtualBox guest additions ISO...") - if err := comm.Upload(processedPath.String(), f); err != nil { + if err := comm.Upload(config.GuestAdditionsPath, f); err != nil { state["error"] = fmt.Errorf("Error uploading guest additions: %s", err) return multistep.ActionHalt } diff --git a/builder/virtualbox/step_vboxmanage.go b/builder/virtualbox/step_vboxmanage.go index bc2032c60..5cd7aa56c 100644 --- a/builder/virtualbox/step_vboxmanage.go +++ b/builder/virtualbox/step_vboxmanage.go @@ -1,12 +1,10 @@ package virtualbox import ( - "bytes" "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "strings" - "text/template" ) type commandTemplate struct { @@ -40,10 +38,14 @@ func (s *stepVBoxManage) Run(state map[string]interface{}) multistep.StepAction copy(command, originalCommand) for i, arg := range command { - var buf bytes.Buffer - t := template.Must(template.New("arg").Parse(arg)) - t.Execute(&buf, tplData) - command[i] = buf.String() + var err error + command[i], err = config.tpl.Process(arg, tplData) + if err != nil { + err := fmt.Errorf("Error preparing vboxmanage command: %s", err) + state["error"] = err + ui.Error(err.Error()) + return multistep.ActionHalt + } } ui.Message(fmt.Sprintf("Executing: %s", strings.Join(command, " ")))