Commit 026bcd33 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

builder/virtualbox: StepRun common

parent fbd20dff
package common
import (
"fmt"
"github.com/mitchellh/packer/packer"
"time"
)
type RunConfig struct {
Headless bool `mapstructure:"headless"`
RawBootWait string `mapstructure:"boot_wait"`
BootWait time.Duration ``
}
func (c *RunConfig) Prepare(t *packer.ConfigTemplate) []error {
if c.RawBootWait == "" {
c.RawBootWait = "10s"
}
templates := map[string]*string{
"boot_wait": &c.RawBootWait,
}
errs := make([]error, 0)
for n, ptr := range templates {
var err error
*ptr, err = t.Process(*ptr, nil)
if err != nil {
errs = append(errs, fmt.Errorf("Error processing %s: %s", n, err))
}
}
var err error
c.BootWait, err = time.ParseDuration(c.RawBootWait)
if err != nil {
errs = append(errs, fmt.Errorf("Failed parsing boot_wait: %s", err))
}
return errs
}
package common
import (
"testing"
)
func TestRunConfigPrepare_BootWait(t *testing.T) {
var c *RunConfig
var errs []error
// Test a default boot_wait
c = new(RunConfig)
errs = c.Prepare(testConfigTemplate(t))
if len(errs) > 0 {
t.Fatalf("should not have error: %s", errs)
}
if c.RawBootWait != "10s" {
t.Fatalf("bad value: %s", c.RawBootWait)
}
// Test with a bad boot_wait
c = new(RunConfig)
c.RawBootWait = "this is not good"
errs = c.Prepare(testConfigTemplate(t))
if len(errs) == 0 {
t.Fatalf("bad: %#v", errs)
}
// Test with a good one
c = new(RunConfig)
c.RawBootWait = "5s"
errs = c.Prepare(testConfigTemplate(t))
if len(errs) > 0 {
t.Fatalf("should not have error: %s", errs)
}
}
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"
"time" "time"
) )
...@@ -11,21 +10,26 @@ import ( ...@@ -11,21 +10,26 @@ import (
// This step starts the virtual machine. // This step starts the virtual machine.
// //
// Uses: // Uses:
// driver Driver
// ui packer.Ui
// vmName string
// //
// Produces: // Produces:
type stepRun struct { type StepRun struct {
BootWait time.Duration
Headless bool
vmName string vmName string
} }
func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction { func (s *StepRun) 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)
ui.Say("Starting the virtual machine...") ui.Say("Starting the virtual machine...")
guiArgument := "gui" guiArgument := "gui"
if config.Headless == true { if s.Headless == true {
ui.Message("WARNING: The VM will be started in headless mode, as configured.\n" + ui.Message("WARNING: The VM will be started in headless mode, as configured.\n" +
"In headless mode, errors during the boot sequence or OS setup\n" + "In headless mode, errors during the boot sequence or OS setup\n" +
"won't be easily visible. Use at your own discretion.") "won't be easily visible. Use at your own discretion.")
...@@ -41,9 +45,9 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction { ...@@ -41,9 +45,9 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction {
s.vmName = vmName s.vmName = vmName
if int64(config.bootWait) > 0 { if int64(s.BootWait) > 0 {
ui.Say(fmt.Sprintf("Waiting %s for boot...", config.bootWait)) ui.Say(fmt.Sprintf("Waiting %s for boot...", s.BootWait))
wait := time.After(config.bootWait) wait := time.After(s.BootWait)
WAITLOOP: WAITLOOP:
for { for {
select { select {
...@@ -60,12 +64,12 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction { ...@@ -60,12 +64,12 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue return multistep.ActionContinue
} }
func (s *stepRun) Cleanup(state multistep.StateBag) { func (s *StepRun) Cleanup(state multistep.StateBag) {
if s.vmName == "" { if s.vmName == "" {
return return
} }
driver := state.Get("driver").(vboxcommon.Driver) driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
if running, _ := driver.IsRunning(s.vmName); running { if running, _ := driver.IsRunning(s.vmName); running {
......
...@@ -9,7 +9,6 @@ import ( ...@@ -9,7 +9,6 @@ import (
"github.com/mitchellh/packer/packer" "github.com/mitchellh/packer/packer"
"log" "log"
"strings" "strings"
"time"
) )
const BuilderId = "mitchellh.virtualbox" const BuilderId = "mitchellh.virtualbox"
...@@ -31,6 +30,7 @@ type config struct { ...@@ -31,6 +30,7 @@ type config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"` vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"` vboxcommon.OutputConfig `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"`
...@@ -44,7 +44,6 @@ type config struct { ...@@ -44,7 +44,6 @@ type config struct {
GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"` GuestAdditionsSHA256 string `mapstructure:"guest_additions_sha256"`
GuestOSType string `mapstructure:"guest_os_type"` GuestOSType string `mapstructure:"guest_os_type"`
HardDriveInterface string `mapstructure:"hard_drive_interface"` HardDriveInterface string `mapstructure:"hard_drive_interface"`
Headless bool `mapstructure:"headless"`
HTTPDir string `mapstructure:"http_directory"` HTTPDir string `mapstructure:"http_directory"`
HTTPPortMin uint `mapstructure:"http_port_min"` HTTPPortMin uint `mapstructure:"http_port_min"`
HTTPPortMax uint `mapstructure:"http_port_max"` HTTPPortMax uint `mapstructure:"http_port_max"`
...@@ -54,11 +53,9 @@ type config struct { ...@@ -54,11 +53,9 @@ type config struct {
VBoxVersionFile string `mapstructure:"virtualbox_version_file"` VBoxVersionFile string `mapstructure:"virtualbox_version_file"`
VMName string `mapstructure:"vm_name"` VMName string `mapstructure:"vm_name"`
RawBootWait string `mapstructure:"boot_wait"`
RawSingleISOUrl string `mapstructure:"iso_url"` RawSingleISOUrl string `mapstructure:"iso_url"`
bootWait time.Duration `` tpl *packer.ConfigTemplate
tpl *packer.ConfigTemplate
} }
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
...@@ -78,6 +75,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { ...@@ -78,6 +75,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(b.config.tpl)...) errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(b.config.tpl)...)
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.RunConfig.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)...)
warnings := make([]string, 0) warnings := make([]string, 0)
...@@ -110,10 +108,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { ...@@ -110,10 +108,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.HTTPPortMax = 9000 b.config.HTTPPortMax = 9000
} }
if b.config.RawBootWait == "" {
b.config.RawBootWait = "10s"
}
if b.config.VBoxVersionFile == "" { if b.config.VBoxVersionFile == "" {
b.config.VBoxVersionFile = ".vbox_version" b.config.VBoxVersionFile = ".vbox_version"
} }
...@@ -139,7 +133,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { ...@@ -139,7 +133,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
"virtualbox_version_file": &b.config.VBoxVersionFile, "virtualbox_version_file": &b.config.VBoxVersionFile,
"vm_name": &b.config.VMName, "vm_name": &b.config.VMName,
"format": &b.config.Format, "format": &b.config.Format,
"boot_wait": &b.config.RawBootWait,
} }
for n, ptr := range templates { for n, ptr := range templates {
...@@ -254,12 +247,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { ...@@ -254,12 +247,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.GuestAdditionsSHA256 = strings.ToLower(b.config.GuestAdditionsSHA256) b.config.GuestAdditionsSHA256 = strings.ToLower(b.config.GuestAdditionsSHA256)
} }
b.config.bootWait, err = time.ParseDuration(b.config.RawBootWait)
if err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Failed parsing boot_wait: %s", err))
}
// Warnings // Warnings
if b.config.ShutdownCommand == "" { if b.config.ShutdownCommand == "" {
warnings = append(warnings, warnings = append(warnings,
...@@ -312,7 +299,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -312,7 +299,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&vboxcommon.StepVBoxManage{ &vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManage, Commands: b.config.VBoxManage,
}, },
new(stepRun), &vboxcommon.StepRun{
BootWait: b.config.BootWait,
Headless: b.config.Headless,
},
new(stepTypeBootCommand), new(stepTypeBootCommand),
&common.StepConnectSSH{ &common.StepConnectSSH{
SSHAddress: vboxcommon.SSHAddress, SSHAddress: vboxcommon.SSHAddress,
......
...@@ -54,46 +54,6 @@ func TestBuilderPrepare_Defaults(t *testing.T) { ...@@ -54,46 +54,6 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
} }
} }
func TestBuilderPrepare_BootWait(t *testing.T) {
var b Builder
config := testConfig()
// Test a default boot_wait
delete(config, "boot_wait")
warns, err := b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err != nil {
t.Fatalf("err: %s", err)
}
if b.config.RawBootWait != "10s" {
t.Fatalf("bad value: %s", b.config.RawBootWait)
}
// Test with a bad boot_wait
config["boot_wait"] = "this is not good"
warns, err = b.Prepare(config)
if len(warns) > 0 {
t.Fatalf("bad: %#v", warns)
}
if err == nil {
t.Fatal("should have error")
}
// Test with a good one
config["boot_wait"] = "5s"
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)
}
}
func TestBuilderPrepare_DiskSize(t *testing.T) { func TestBuilderPrepare_DiskSize(t *testing.T) {
var b Builder var b Builder
config := testConfig() config := testConfig()
......
...@@ -62,9 +62,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -62,9 +62,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&vboxcommon.StepVBoxManage{ &vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManage, Commands: b.config.VBoxManage,
}, },
/* &vboxcommon.StepRun{
new(stepRun), BootWait: b.config.BootWait,
*/ Headless: b.config.Headless,
},
&common.StepConnectSSH{ &common.StepConnectSSH{
SSHAddress: vboxcommon.SSHAddress, SSHAddress: vboxcommon.SSHAddress,
SSHConfig: vboxcommon.SSHConfigFunc(b.config.SSHConfig), SSHConfig: vboxcommon.SSHConfigFunc(b.config.SSHConfig),
......
...@@ -11,6 +11,7 @@ type Config struct { ...@@ -11,6 +11,7 @@ type Config struct {
common.PackerConfig `mapstructure:",squash"` common.PackerConfig `mapstructure:",squash"`
vboxcommon.FloppyConfig `mapstructure:",squash"` vboxcommon.FloppyConfig `mapstructure:",squash"`
vboxcommon.OutputConfig `mapstructure:",squash"` vboxcommon.OutputConfig `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"`
...@@ -35,6 +36,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { ...@@ -35,6 +36,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
errs := common.CheckUnusedConfig(md) errs := common.CheckUnusedConfig(md)
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.RunConfig.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)...)
......
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