builder/virtualbox: add "vboxmanage" to run custom commands
This commit is contained in:
parent
53b7b3965f
commit
a3bd9ecdc3
@ -43,6 +43,7 @@ type config struct {
|
||||
SSHPort uint `mapstructure:"ssh_port"`
|
||||
SSHUser string `mapstructure:"ssh_username"`
|
||||
SSHWaitTimeout time.Duration ``
|
||||
VBoxManage [][]string `mapstructure:"vboxmanage"`
|
||||
VMName string `mapstructure:"vm_name"`
|
||||
|
||||
PackerDebug bool `mapstructure:"packer_debug"`
|
||||
@ -94,6 +95,10 @@ func (b *Builder) Prepare(raws ...interface{}) error {
|
||||
b.config.SSHPort = 22
|
||||
}
|
||||
|
||||
if b.config.VBoxManage == nil {
|
||||
b.config.VBoxManage = make([][]string, 0)
|
||||
}
|
||||
|
||||
if b.config.VMName == "" {
|
||||
b.config.VMName = "packer"
|
||||
}
|
||||
@ -204,6 +209,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||
new(stepCreateDisk),
|
||||
new(stepAttachISO),
|
||||
new(stepForwardSSH),
|
||||
new(stepVBoxManage),
|
||||
new(stepRun),
|
||||
new(stepTypeBootCommand),
|
||||
new(stepWaitForSSH),
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -279,3 +280,38 @@ func TestBuilderPrepare_SSHWaitTimeout(t *testing.T) {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_VBoxManage(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test with empty
|
||||
delete(config, "vboxmanage")
|
||||
err := b.Prepare(config)
|
||||
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{}
|
||||
err = b.Prepare(config)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
61
builder/virtualbox/step_vboxmanage.go
Normal file
61
builder/virtualbox/step_vboxmanage.go
Normal file
@ -0,0 +1,61 @@
|
||||
package virtualbox
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type commandTemplate struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
// This step executes additional VBoxManage commands as specified by the
|
||||
// template.
|
||||
//
|
||||
// Uses:
|
||||
//
|
||||
// Produces:
|
||||
type stepVBoxManage struct{}
|
||||
|
||||
func (s *stepVBoxManage) Run(state map[string]interface{}) multistep.StepAction {
|
||||
config := state["config"].(*config)
|
||||
driver := state["driver"].(Driver)
|
||||
ui := state["ui"].(packer.Ui)
|
||||
vmName := state["vmName"].(string)
|
||||
|
||||
if len(config.VBoxManage) > 0 {
|
||||
ui.Say("Executing custom VBoxManage commands...")
|
||||
}
|
||||
|
||||
tplData := &commandTemplate{
|
||||
Name: vmName,
|
||||
}
|
||||
|
||||
for _, originalCommand := range config.VBoxManage {
|
||||
command := make([]string, len(originalCommand))
|
||||
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()
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Executing: %s", strings.Join(command, " ")))
|
||||
if err := driver.VBoxManage(command...); err != nil {
|
||||
err := fmt.Errorf("Error executing command: %s", err)
|
||||
state["error"] = err
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepVBoxManage) Cleanup(state map[string]interface{}) {}
|
Loading…
x
Reference in New Issue
Block a user