builder/virtualbox: StepVBoxmanage

This commit is contained in:
Mitchell Hashimoto 2013-12-22 09:24:29 -08:00
parent 7a4ff3f2b1
commit 4bd2aa6106
7 changed files with 119 additions and 97 deletions

View File

@ -1,9 +1,8 @@
package iso package common
import ( import (
"fmt" "fmt"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
vboxcommon "github.com/mitchellh/packer/builder/virtualbox/common"
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"strings" "strings"
) )
@ -16,17 +15,22 @@ type commandTemplate struct {
// template. // template.
// //
// Uses: // Uses:
// driver Driver
// ui packer.Ui
// vmName string
// //
// Produces: // Produces:
type stepVBoxManage struct{} type StepVBoxManage struct {
Commands [][]string
Tpl *packer.ConfigTemplate
}
func (s *stepVBoxManage) Run(state multistep.StateBag) multistep.StepAction { func (s *StepVBoxManage) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*config) driver := state.Get("driver").(Driver)
driver := state.Get("driver").(vboxcommon.Driver)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string) vmName := state.Get("vmName").(string)
if len(config.VBoxManage) > 0 { if len(s.Commands) > 0 {
ui.Say("Executing custom VBoxManage commands...") ui.Say("Executing custom VBoxManage commands...")
} }
@ -34,13 +38,13 @@ func (s *stepVBoxManage) Run(state multistep.StateBag) multistep.StepAction {
Name: vmName, Name: vmName,
} }
for _, originalCommand := range config.VBoxManage { for _, originalCommand := range s.Commands {
command := make([]string, len(originalCommand)) command := make([]string, len(originalCommand))
copy(command, originalCommand) copy(command, originalCommand)
for i, arg := range command { for i, arg := range command {
var err error var err error
command[i], err = config.tpl.Process(arg, tplData) command[i], err = s.Tpl.Process(arg, tplData)
if err != nil { if err != nil {
err := fmt.Errorf("Error preparing vboxmanage command: %s", err) err := fmt.Errorf("Error preparing vboxmanage command: %s", err)
state.Put("error", err) state.Put("error", err)
@ -61,4 +65,4 @@ func (s *stepVBoxManage) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue return multistep.ActionContinue
} }
func (s *stepVBoxManage) Cleanup(state multistep.StateBag) {} func (s *StepVBoxManage) Cleanup(state multistep.StateBag) {}

View File

@ -0,0 +1,28 @@
package common
import (
"fmt"
"github.com/mitchellh/packer/packer"
)
type VBoxManageConfig struct {
VBoxManage [][]string `mapstructure:"vboxmanage"`
}
func (c *VBoxManageConfig) Prepare(t *packer.ConfigTemplate) []error {
if c.VBoxManage == nil {
c.VBoxManage = make([][]string, 0)
}
errs := make([]error, 0)
for i, args := range c.VBoxManage {
for j, arg := range args {
if err := t.Validate(arg); err != nil {
errs = append(errs,
fmt.Errorf("Error processing vboxmanage[%d][%d]: %s", i, j, err))
}
}
}
return errs
}

View File

@ -0,0 +1,37 @@
package common
import (
"reflect"
"testing"
)
func TestVBoxManageConfigPrepare_VBoxManage(t *testing.T) {
// Test with empty
c := new(VBoxManageConfig)
errs := c.Prepare(testConfigTemplate(t))
if len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !reflect.DeepEqual(c.VBoxManage, [][]string{}) {
t.Fatalf("bad: %#v", c.VBoxManage)
}
// Test with a good one
c = new(VBoxManageConfig)
c.VBoxManage = [][]string{
{"foo", "bar", "baz"},
}
errs = c.Prepare(testConfigTemplate(t))
if len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
expected := [][]string{
[]string{"foo", "bar", "baz"},
}
if !reflect.DeepEqual(c.VBoxManage, expected) {
t.Fatalf("bad: %#v", c.VBoxManage)
}
}

View File

@ -32,6 +32,7 @@ type config struct {
vboxcommon.FloppyConfig `mapstructure:",squash"` vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"` vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"` vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"`
BootCommand []string `mapstructure:"boot_command"` BootCommand []string `mapstructure:"boot_command"`
DiskSize uint `mapstructure:"disk_size"` DiskSize uint `mapstructure:"disk_size"`
@ -51,7 +52,6 @@ type config struct {
ISOUrls []string `mapstructure:"iso_urls"` ISOUrls []string `mapstructure:"iso_urls"`
ShutdownCommand string `mapstructure:"shutdown_command"` ShutdownCommand string `mapstructure:"shutdown_command"`
VBoxVersionFile string `mapstructure:"virtualbox_version_file"` VBoxVersionFile string `mapstructure:"virtualbox_version_file"`
VBoxManage [][]string `mapstructure:"vboxmanage"`
VMName string `mapstructure:"vm_name"` VMName string `mapstructure:"vm_name"`
RawBootWait string `mapstructure:"boot_wait"` RawBootWait string `mapstructure:"boot_wait"`
@ -81,6 +81,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, b.config.OutputConfig.Prepare(b.config.tpl, &b.config.PackerConfig)...) errs, b.config.OutputConfig.Prepare(b.config.tpl, &b.config.PackerConfig)...)
errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(b.config.tpl)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(b.config.tpl)...)
errs = packer.MultiErrorAppend(errs, b.config.VBoxManageConfig.Prepare(b.config.tpl)...)
warnings := make([]string, 0) warnings := make([]string, 0)
if b.config.DiskSize == 0 { if b.config.DiskSize == 0 {
@ -115,10 +116,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.RawBootWait = "10s" b.config.RawBootWait = "10s"
} }
if b.config.VBoxManage == nil {
b.config.VBoxManage = make([][]string, 0)
}
if b.config.VBoxVersionFile == "" { if b.config.VBoxVersionFile == "" {
b.config.VBoxVersionFile = ".vbox_version" b.config.VBoxVersionFile = ".vbox_version"
} }
@ -277,15 +274,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs, fmt.Errorf("Failed parsing shutdown_timeout: %s", err)) errs, fmt.Errorf("Failed parsing shutdown_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))
}
}
}
// Warnings // Warnings
if b.config.ShutdownCommand == "" { if b.config.ShutdownCommand == "" {
warnings = append(warnings, warnings = append(warnings,
@ -335,7 +323,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
HostPortMin: b.config.SSHHostPortMin, HostPortMin: b.config.SSHHostPortMin,
HostPortMax: b.config.SSHHostPortMax, HostPortMax: b.config.SSHHostPortMax,
}, },
new(stepVBoxManage), &vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManage,
},
new(stepRun), new(stepRun),
new(stepTypeBootCommand), new(stepTypeBootCommand),
&common.StepConnectSSH{ &common.StepConnectSSH{

View File

@ -2,8 +2,6 @@ package iso
import ( import (
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"io/ioutil"
"os"
"reflect" "reflect"
"testing" "testing"
) )
@ -575,47 +573,6 @@ func TestBuilderPrepare_ShutdownTimeout(t *testing.T) {
} }
} }
func TestBuilderPrepare_VBoxManage(t *testing.T) {
var b Builder
config := testConfig()
// Test with empty
delete(config, "vboxmanage")
warns, err := b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(b.config.VBoxManage, [][]string{}) {
t.Fatalf("bad: %#v", b.config.VBoxManage)
}
// Test with a good one
config["vboxmanage"] = [][]interface{}{
[]interface{}{"foo", "bar", "baz"},
}
b = Builder{}
warns, err = b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err != nil {
t.Fatalf("should not have error: %s", err)
}
expected := [][]string{
[]string{"foo", "bar", "baz"},
}
if !reflect.DeepEqual(b.config.VBoxManage, expected) {
t.Fatalf("bad: %#v", b.config.VBoxManage)
}
}
func TestBuilderPrepare_VBoxVersionFile(t *testing.T) { func TestBuilderPrepare_VBoxVersionFile(t *testing.T) {
var b Builder var b Builder
config := testConfig() config := testConfig()

View File

@ -59,8 +59,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
HostPortMin: b.config.SSHHostPortMin, HostPortMin: b.config.SSHHostPortMin,
HostPortMax: b.config.SSHHostPortMax, HostPortMax: b.config.SSHHostPortMax,
}, },
&vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManage,
},
/* /*
new(stepVBoxManage),
new(stepRun), new(stepRun),
*/ */
&common.StepConnectSSH{ &common.StepConnectSSH{
@ -71,7 +73,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
/* /*
new(stepUploadVersion), new(stepUploadVersion),
new(stepUploadGuestAdditions), new(stepUploadGuestAdditions),
*/
new(common.StepProvision), new(common.StepProvision),
/*
new(stepShutdown), new(stepShutdown),
new(stepRemoveDevices), new(stepRemoveDevices),
new(stepExport), new(stepExport),

View File

@ -12,6 +12,7 @@ type Config struct {
vboxcommon.FloppyConfig `mapstructure:",squash"` vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"` vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"` vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"`
tpl *packer.ConfigTemplate tpl *packer.ConfigTemplate
} }
@ -34,6 +35,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(c.tpl)...) errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(c.tpl)...)
errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...) errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...)
errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...) errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...)
errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(c.tpl)...)
// Check for any errors. // Check for any errors.
if errs != nil && len(errs.Errors) > 0 { if errs != nil && len(errs.Errors) > 0 {