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

@ -28,31 +28,31 @@ type Builder struct {
}
type config struct {
common.PackerConfig `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"`
common.PackerConfig `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"`
BootCommand []string `mapstructure:"boot_command"`
DiskSize uint `mapstructure:"disk_size"`
Format string `mapstructure:"format"`
GuestAdditionsMode string `mapstructure:"guest_additions_mode"`
GuestAdditionsPath string `mapstructure:"guest_additions_path"`
GuestAdditionsURL string `mapstructure:"guest_additions_url"`
GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"`
GuestOSType string `mapstructure:"guest_os_type"`
HardDriveInterface string `mapstructure:"hard_drive_interface"`
Headless bool `mapstructure:"headless"`
HTTPDir string `mapstructure:"http_directory"`
HTTPPortMin uint `mapstructure:"http_port_min"`
HTTPPortMax uint `mapstructure:"http_port_max"`
ISOChecksum string `mapstructure:"iso_checksum"`
ISOChecksumType string `mapstructure:"iso_checksum_type"`
ISOUrls []string `mapstructure:"iso_urls"`
ShutdownCommand string `mapstructure:"shutdown_command"`
VBoxVersionFile string `mapstructure:"virtualbox_version_file"`
VBoxManage [][]string `mapstructure:"vboxmanage"`
VMName string `mapstructure:"vm_name"`
BootCommand []string `mapstructure:"boot_command"`
DiskSize uint `mapstructure:"disk_size"`
Format string `mapstructure:"format"`
GuestAdditionsMode string `mapstructure:"guest_additions_mode"`
GuestAdditionsPath string `mapstructure:"guest_additions_path"`
GuestAdditionsURL string `mapstructure:"guest_additions_url"`
GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"`
GuestOSType string `mapstructure:"guest_os_type"`
HardDriveInterface string `mapstructure:"hard_drive_interface"`
Headless bool `mapstructure:"headless"`
HTTPDir string `mapstructure:"http_directory"`
HTTPPortMin uint `mapstructure:"http_port_min"`
HTTPPortMax uint `mapstructure:"http_port_max"`
ISOChecksum string `mapstructure:"iso_checksum"`
ISOChecksumType string `mapstructure:"iso_checksum_type"`
ISOUrls []string `mapstructure:"iso_urls"`
ShutdownCommand string `mapstructure:"shutdown_command"`
VBoxVersionFile string `mapstructure:"virtualbox_version_file"`
VMName string `mapstructure:"vm_name"`
RawBootWait string `mapstructure:"boot_wait"`
RawSingleISOUrl string `mapstructure:"iso_url"`
@ -81,6 +81,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend(
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.VBoxManageConfig.Prepare(b.config.tpl)...)
warnings := make([]string, 0)
if b.config.DiskSize == 0 {
@ -115,10 +116,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.RawBootWait = "10s"
}
if b.config.VBoxManage == nil {
b.config.VBoxManage = make([][]string, 0)
}
if b.config.VBoxVersionFile == "" {
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))
}
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
if b.config.ShutdownCommand == "" {
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,
HostPortMax: b.config.SSHHostPortMax,
},
new(stepVBoxManage),
&vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManage,
},
new(stepRun),
new(stepTypeBootCommand),
&common.StepConnectSSH{

View File

@ -2,8 +2,6 @@ package iso
import (
"github.com/mitchellh/packer/packer"
"io/ioutil"
"os"
"reflect"
"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) {
var b Builder
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,
HostPortMax: b.config.SSHHostPortMax,
},
&vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManage,
},
/*
new(stepVBoxManage),
new(stepRun),
*/
&common.StepConnectSSH{
@ -71,7 +73,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
/*
new(stepUploadVersion),
new(stepUploadGuestAdditions),
new(common.StepProvision),
*/
new(common.StepProvision),
/*
new(stepShutdown),
new(stepRemoveDevices),
new(stepExport),

View File

@ -8,10 +8,11 @@ import (
// Config is the configuration structure for the builder.
type Config struct {
common.PackerConfig `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"`
common.PackerConfig `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"`
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.OutputConfig.Prepare(c.tpl, &c.PackerConfig)...)
errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...)
errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(c.tpl)...)
// Check for any errors.
if errs != nil && len(errs.Errors) > 0 {