Commit 6373529a authored by Ross Smith II's avatar Ross Smith II

Merge pull request #946 from jhelwig/vboxmanage-before-export

Add ability to run vboxmanage commands just before exporting [GH-664]
parents bb8d0a5e 38e880a1
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
}
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)
}
}
...@@ -27,16 +27,17 @@ type Builder struct { ...@@ -27,16 +27,17 @@ type Builder struct {
} }
type config struct { type config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
vboxcommon.ExportConfig `mapstructure:",squash"` vboxcommon.ExportConfig `mapstructure:",squash"`
vboxcommon.ExportOpts `mapstructure:",squash"` vboxcommon.ExportOpts `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"` vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"` vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.RunConfig `mapstructure:",squash"` vboxcommon.RunConfig `mapstructure:",squash"`
vboxcommon.ShutdownConfig `mapstructure:",squash"` vboxcommon.ShutdownConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"` vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"` vboxcommon.VBoxManageConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"` vboxcommon.VBoxManagePostConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"`
BootCommand []string `mapstructure:"boot_command"` BootCommand []string `mapstructure:"boot_command"`
DiskSize uint `mapstructure:"disk_size"` DiskSize uint `mapstructure:"disk_size"`
...@@ -82,6 +83,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { ...@@ -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.ShutdownConfig.Prepare(b.config.tpl)...)
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)...) 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)...) errs = packer.MultiErrorAppend(errs, b.config.VBoxVersionConfig.Prepare(b.config.tpl)...)
warnings := make([]string, 0) warnings := make([]string, 0)
...@@ -318,6 +320,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -318,6 +320,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Timeout: b.config.ShutdownTimeout, Timeout: b.config.ShutdownTimeout,
}, },
new(vboxcommon.StepRemoveDevices), new(vboxcommon.StepRemoveDevices),
&vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManagePost,
Tpl: b.config.tpl,
},
&vboxcommon.StepExport{ &vboxcommon.StepExport{
Format: b.config.Format, Format: b.config.Format,
OutputDir: b.config.OutputDir, OutputDir: b.config.OutputDir,
......
...@@ -94,6 +94,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -94,6 +94,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Timeout: b.config.ShutdownTimeout, Timeout: b.config.ShutdownTimeout,
}, },
new(vboxcommon.StepRemoveDevices), new(vboxcommon.StepRemoveDevices),
&vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManagePost,
Tpl: b.config.tpl,
},
&vboxcommon.StepExport{ &vboxcommon.StepExport{
Format: b.config.Format, Format: b.config.Format,
OutputDir: b.config.OutputDir, OutputDir: b.config.OutputDir,
......
...@@ -11,16 +11,17 @@ import ( ...@@ -11,16 +11,17 @@ import (
// Config is the configuration structure for the builder. // Config is the configuration structure for the builder.
type Config struct { type Config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
vboxcommon.ExportConfig `mapstructure:",squash"` vboxcommon.ExportConfig `mapstructure:",squash"`
vboxcommon.ExportOpts `mapstructure:",squash"` vboxcommon.ExportOpts `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"` vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"` vboxcommon.OutputConfig `mapstructure:",squash"`
vboxcommon.RunConfig `mapstructure:",squash"` vboxcommon.RunConfig `mapstructure:",squash"`
vboxcommon.SSHConfig `mapstructure:",squash"` vboxcommon.SSHConfig `mapstructure:",squash"`
vboxcommon.ShutdownConfig `mapstructure:",squash"` vboxcommon.ShutdownConfig `mapstructure:",squash"`
vboxcommon.VBoxManageConfig `mapstructure:",squash"` vboxcommon.VBoxManageConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"` vboxcommon.VBoxManagePostConfig `mapstructure:",squash"`
vboxcommon.VBoxVersionConfig `mapstructure:",squash"`
SourcePath string `mapstructure:"source_path"` SourcePath string `mapstructure:"source_path"`
VMName string `mapstructure:"vm_name"` VMName string `mapstructure:"vm_name"`
...@@ -57,6 +58,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { ...@@ -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.ShutdownConfig.Prepare(c.tpl)...)
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)...) 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)...) errs = packer.MultiErrorAppend(errs, c.VBoxVersionConfig.Prepare(c.tpl)...)
templates := map[string]*string{ templates := map[string]*string{
......
...@@ -201,6 +201,10 @@ Optional: ...@@ -201,6 +201,10 @@ Optional:
where the `Name` variable is replaced with the VM name. More details on how where the `Name` variable is replaced with the VM name. More details on how
to use `VBoxManage` are below. 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 * `virtualbox_version_file` (string) - The path within the virtual machine
to upload a file that contains the VirtualBox version that was used to to upload a file that contains the VirtualBox version that was used to
create the machine. This information can be useful for provisioning. create the machine. This information can be useful for provisioning.
......
...@@ -136,6 +136,10 @@ Optional: ...@@ -136,6 +136,10 @@ Optional:
where the `Name` variable is replaced with the VM name. More details on how where the `Name` variable is replaced with the VM name. More details on how
to use `VBoxManage` are below. 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 * `virtualbox_version_file` (string) - The path within the virtual machine
to upload a file that contains the VirtualBox version that was used to to upload a file that contains the VirtualBox version that was used to
create the machine. This information can be useful for provisioning. create the machine. This information can be useful for provisioning.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment