Commit 9eb32e5d authored by Matt Behrens's avatar Matt Behrens

implement `iso_interface` setting

Adds a new configuration option, `iso_interface`, that can be set to
`sata` to mount the ISO on the SATA controller.  Required for OS X.
parent 8e3559a0
...@@ -41,11 +41,20 @@ func (s *StepRemoveDevices) Run(state multistep.StateBag) multistep.StepAction { ...@@ -41,11 +41,20 @@ func (s *StepRemoveDevices) Run(state multistep.StateBag) multistep.StepAction {
} }
if _, ok := state.GetOk("attachedIso"); ok { if _, ok := state.GetOk("attachedIso"); ok {
controllerName := "IDE Controller"
port := "0"
device := "1"
if _, ok := state.GetOk("attachedIsoOnSata"); ok {
controllerName = "SATA Controller"
port = "1"
device = "0"
}
command := []string{ command := []string{
"storageattach", vmName, "storageattach", vmName,
"--storagectl", "IDE Controller", "--storagectl", controllerName,
"--port", "0", "--port", port,
"--device", "1", "--device", device,
"--medium", "none", "--medium", "none",
} }
......
...@@ -57,6 +57,33 @@ func TestStepRemoveDevices_attachedIso(t *testing.T) { ...@@ -57,6 +57,33 @@ func TestStepRemoveDevices_attachedIso(t *testing.T) {
} }
} }
func TestStepRemoveDevices_attachedIsoOnSata(t *testing.T) {
state := testState(t)
step := new(StepRemoveDevices)
state.Put("attachedIso", true)
state.Put("attachedIsoOnSata", true)
state.Put("vmName", "foo")
driver := state.Get("driver").(*DriverMock)
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
// Test that ISO was removed
if len(driver.VBoxManageCalls) != 1 {
t.Fatalf("bad: %#v", driver.VBoxManageCalls)
}
if driver.VBoxManageCalls[0][3] != "SATA Controller" {
t.Fatalf("bad: %#v", driver.VBoxManageCalls)
}
}
func TestStepRemoveDevices_floppyPath(t *testing.T) { func TestStepRemoveDevices_floppyPath(t *testing.T) {
state := testState(t) state := testState(t)
step := new(StepRemoveDevices) step := new(StepRemoveDevices)
......
...@@ -44,6 +44,7 @@ type config struct { ...@@ -44,6 +44,7 @@ type config struct {
HTTPPortMax uint `mapstructure:"http_port_max"` HTTPPortMax uint `mapstructure:"http_port_max"`
ISOChecksum string `mapstructure:"iso_checksum"` ISOChecksum string `mapstructure:"iso_checksum"`
ISOChecksumType string `mapstructure:"iso_checksum_type"` ISOChecksumType string `mapstructure:"iso_checksum_type"`
ISOInterface string `mapstructure:"iso_interface"`
ISOUrls []string `mapstructure:"iso_urls"` ISOUrls []string `mapstructure:"iso_urls"`
VMName string `mapstructure:"vm_name"` VMName string `mapstructure:"vm_name"`
...@@ -107,6 +108,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { ...@@ -107,6 +108,10 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
b.config.HTTPPortMax = 9000 b.config.HTTPPortMax = 9000
} }
if b.config.ISOInterface == "" {
b.config.ISOInterface = "ide"
}
if b.config.VMName == "" { if b.config.VMName == "" {
b.config.VMName = fmt.Sprintf("packer-%s", b.config.PackerBuildName) b.config.VMName = fmt.Sprintf("packer-%s", b.config.PackerBuildName)
} }
...@@ -120,6 +125,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { ...@@ -120,6 +125,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
"http_directory": &b.config.HTTPDir, "http_directory": &b.config.HTTPDir,
"iso_checksum": &b.config.ISOChecksum, "iso_checksum": &b.config.ISOChecksum,
"iso_checksum_type": &b.config.ISOChecksumType, "iso_checksum_type": &b.config.ISOChecksumType,
"iso_interface": &b.config.ISOInterface,
"iso_url": &b.config.RawSingleISOUrl, "iso_url": &b.config.RawSingleISOUrl,
"vm_name": &b.config.VMName, "vm_name": &b.config.VMName,
} }
...@@ -192,6 +198,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { ...@@ -192,6 +198,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
} }
} }
if b.config.ISOInterface != "ide" && b.config.ISOInterface != "sata" {
errs = packer.MultiErrorAppend(
errs, errors.New("iso_interface can only be ide or sata"))
}
if b.config.RawSingleISOUrl == "" && len(b.config.ISOUrls) == 0 { if b.config.RawSingleISOUrl == "" && len(b.config.ISOUrls) == 0 {
errs = packer.MultiErrorAppend( errs = packer.MultiErrorAppend(
errs, errors.New("One of iso_url or iso_urls must be specified.")) errs, errors.New("One of iso_url or iso_urls must be specified."))
......
...@@ -401,6 +401,47 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) { ...@@ -401,6 +401,47 @@ func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
} }
} }
func TestBuilderPrepare_ISOInterface(t *testing.T) {
var b Builder
config := testConfig()
// Test a default boot_wait
delete(config, "iso_interface")
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.ISOInterface != "ide" {
t.Fatalf("bad: %s", b.config.ISOInterface)
}
// Test with a bad
config["iso_interface"] = "fake"
b = Builder{}
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
config["iso_interface"] = "sata"
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_ISOUrl(t *testing.T) { func TestBuilderPrepare_ISOUrl(t *testing.T) {
var b Builder var b Builder
config := testConfig() config := testConfig()
......
...@@ -17,17 +17,27 @@ type stepAttachISO struct { ...@@ -17,17 +17,27 @@ type stepAttachISO struct {
} }
func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction { func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*config)
driver := state.Get("driver").(vboxcommon.Driver) driver := state.Get("driver").(vboxcommon.Driver)
isoPath := state.Get("iso_path").(string) isoPath := state.Get("iso_path").(string)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string) vmName := state.Get("vmName").(string)
controllerName := "IDE Controller"
port := "0"
device := "1"
if config.ISOInterface == "sata" {
controllerName = "SATA Controller"
port = "1"
device = "0"
}
// Attach the disk to the controller // Attach the disk to the controller
command := []string{ command := []string{
"storageattach", vmName, "storageattach", vmName,
"--storagectl", "IDE Controller", "--storagectl", controllerName,
"--port", "0", "--port", port,
"--device", "1", "--device", device,
"--type", "dvddrive", "--type", "dvddrive",
"--medium", isoPath, "--medium", isoPath,
} }
...@@ -43,6 +53,9 @@ func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction { ...@@ -43,6 +53,9 @@ func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction {
// Set some state so we know to remove // Set some state so we know to remove
state.Put("attachedIso", true) state.Put("attachedIso", true)
if controllerName == "SATA Controller" {
state.Put("attachedIsoOnSata", true)
}
return multistep.ActionContinue return multistep.ActionContinue
} }
...@@ -52,14 +65,24 @@ func (s *stepAttachISO) Cleanup(state multistep.StateBag) { ...@@ -52,14 +65,24 @@ func (s *stepAttachISO) Cleanup(state multistep.StateBag) {
return return
} }
config := state.Get("config").(*config)
driver := state.Get("driver").(vboxcommon.Driver) driver := state.Get("driver").(vboxcommon.Driver)
vmName := state.Get("vmName").(string) vmName := state.Get("vmName").(string)
controllerName := "IDE Controller"
port := "0"
device := "1"
if config.ISOInterface == "sata" {
controllerName = "SATA Controller"
port = "1"
device = "0"
}
command := []string{ command := []string{
"storageattach", vmName, "storageattach", vmName,
"--storagectl", "IDE Controller", "--storagectl", controllerName,
"--port", "0", "--port", port,
"--device", "1", "--device", device,
"--medium", "none", "--medium", "none",
} }
......
...@@ -43,8 +43,7 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { ...@@ -43,8 +43,7 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction {
// Add the IDE controller so we can later attach the disk. // Add the IDE controller so we can later attach the disk.
// When the hard disk controller is not IDE, this device is still used // When the hard disk controller is not IDE, this device is still used
// by VirtualBox to deliver the guest extensions. // by VirtualBox to deliver the guest extensions.
controllerName := "IDE Controller" err = driver.VBoxManage("storagectl", vmName, "--name", "IDE Controller", "--add", "ide")
err = driver.VBoxManage("storagectl", vmName, "--name", controllerName, "--add", "ide")
if err != nil { if err != nil {
err := fmt.Errorf("Error creating disk controller: %s", err) err := fmt.Errorf("Error creating disk controller: %s", err)
state.Put("error", err) state.Put("error", err)
...@@ -55,9 +54,8 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { ...@@ -55,9 +54,8 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction {
// Add a SATA controller if we were asked to use SATA. We still attach // Add a SATA controller if we were asked to use SATA. We still attach
// the IDE controller above because some other things (disks) require // the IDE controller above because some other things (disks) require
// that. // that.
if config.HardDriveInterface == "sata" { if config.HardDriveInterface == "sata" || config.ISOInterface == "sata" {
controllerName = "SATA Controller" if err := driver.CreateSATAController(vmName, "SATA Controller"); err != nil {
if err := driver.CreateSATAController(vmName, controllerName); err != nil {
err := fmt.Errorf("Error creating disk controller: %s", err) err := fmt.Errorf("Error creating disk controller: %s", err)
state.Put("error", err) state.Put("error", err)
ui.Error(err.Error()) ui.Error(err.Error())
...@@ -66,6 +64,11 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { ...@@ -66,6 +64,11 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction {
} }
// Attach the disk to the controller // Attach the disk to the controller
controllerName := "IDE Controller"
if config.HardDriveInterface == "sata" {
controllerName = "SATA Controller"
}
command = []string{ command = []string{
"storageattach", vmName, "storageattach", vmName,
"--storagectl", controllerName, "--storagectl", controllerName,
......
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