Add ability to run vboxmanage commands just before exporting [GH-664]

This commit is contained in:
Jacob Helwig 2014-03-12 16:14:44 -07:00
parent bb8d0a5e7a
commit 38e880a187
7 changed files with 105 additions and 20 deletions

View File

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

View File

@ -0,0 +1,37 @@
package common
import (
"reflect"
"testing"
)
func TestVBoxManagePostConfigPrepare_VBoxManage(t *testing.T) {
// Test with empty
c := new(VBoxManagePostConfig)
errs := c.Prepare(testConfigTemplate(t))
if len(errs) > 0 {
t.Fatalf("err: %#v", errs)
}
if !reflect.DeepEqual(c.VBoxManagePost, [][]string{}) {
t.Fatalf("bad: %#v", c.VBoxManagePost)
}
// Test with a good one
c = new(VBoxManagePostConfig)
c.VBoxManagePost = [][]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.VBoxManagePost, expected) {
t.Fatalf("bad: %#v", c.VBoxManagePost)
}
}

View File

@ -27,16 +27,17 @@ type Builder struct {
}
type config struct {
common.PackerConfig `mapstructure:",squash"`
vboxcommon.ExportConfig `mapstructure:",squash"`
vboxcommon.ExportOpts `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.RunConfig `mapstructure:",squash"`
vboxcommon.ShutdownConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"`
common.PackerConfig `mapstructure:",squash"`
vboxcommon.ExportConfig `mapstructure:",squash"`
vboxcommon.ExportOpts `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.RunConfig `mapstructure:",squash"`
vboxcommon.ShutdownConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"`
vboxcommon.VBoxManagePostConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"`
BootCommand []string `mapstructure:"boot_command"`
DiskSize uint `mapstructure:"disk_size"`
@ -82,6 +83,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.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)...)
errs = packer.MultiErrorAppend(errs, b.config.VBoxManagePostConfig.Prepare(b.config.tpl)...)
errs = packer.MultiErrorAppend(errs, b.config.VBoxVersionConfig.Prepare(b.config.tpl)...)
warnings := make([]string, 0)
@ -318,6 +320,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Timeout: b.config.ShutdownTimeout,
},
new(vboxcommon.StepRemoveDevices),
&vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManagePost,
Tpl: b.config.tpl,
},
&vboxcommon.StepExport{
Format: b.config.Format,
OutputDir: b.config.OutputDir,

View File

@ -94,6 +94,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Timeout: b.config.ShutdownTimeout,
},
new(vboxcommon.StepRemoveDevices),
&vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManagePost,
Tpl: b.config.tpl,
},
&vboxcommon.StepExport{
Format: b.config.Format,
OutputDir: b.config.OutputDir,

View File

@ -11,16 +11,17 @@ import (
// Config is the configuration structure for the builder.
type Config struct {
common.PackerConfig `mapstructure:",squash"`
vboxcommon.ExportConfig `mapstructure:",squash"`
vboxcommon.ExportOpts `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.RunConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.ShutdownConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"`
common.PackerConfig `mapstructure:",squash"`
vboxcommon.ExportConfig `mapstructure:",squash"`
vboxcommon.ExportOpts `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.RunConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.ShutdownConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"`
vboxcommon.VBoxManagePostConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"`
SourcePath string `mapstructure:"source_path"`
VMName string `mapstructure:"vm_name"`
@ -57,6 +58,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(c.tpl)...)
errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...)
errs = packer.MultiErrorAppend(errs, c.VBoxManageConfig.Prepare(c.tpl)...)
errs = packer.MultiErrorAppend(errs, c.VBoxManagePostConfig.Prepare(c.tpl)...)
errs = packer.MultiErrorAppend(errs, c.VBoxVersionConfig.Prepare(c.tpl)...)
templates := map[string]*string{

View File

@ -201,6 +201,10 @@ Optional:
where the `Name` variable is replaced with the VM name. More details on how
to use `VBoxManage` are below.
* `vboxmanage_post` (array of array of strings) - Identical to `vboxmanage`,
except that it is run after the virtual machine is shutdown, and before the
virtual machine is exported.
* `virtualbox_version_file` (string) - The path within the virtual machine
to upload a file that contains the VirtualBox version that was used to
create the machine. This information can be useful for provisioning.

View File

@ -136,6 +136,10 @@ Optional:
where the `Name` variable is replaced with the VM name. More details on how
to use `VBoxManage` are below.
* `vboxmanage_post` (array of array of strings) - Identical to `vboxmanage`,
except that it is run after the virtual machine is shutdown, and before the
virtual machine is exported.
* `virtualbox_version_file` (string) - The path within the virtual machine
to upload a file that contains the VirtualBox version that was used to
create the machine. This information can be useful for provisioning.