diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 0bace9659..6e1354ae3 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -44,15 +44,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack return nil, fmt.Errorf("Failed creating Qemu driver: %s", err) } - steprun := &stepRun{} - if !b.config.DiskImage { - steprun.BootDrive = "once=d" - steprun.Message = "Starting VM, booting from CD-ROM" - } else { - steprun.BootDrive = "c" - steprun.Message = "Starting VM, booting disk image" - } - steps := []multistep.Step{} if !b.config.ISOSkipCache { steps = append(steps, &common.StepDownload{ @@ -102,7 +93,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack steps = append(steps, new(stepConfigureVNC), - steprun, + &stepRun{ + DiskImage: b.config.DiskImage, + }, &stepConfigureQMP{ QMPSocketPath: b.config.QMPSocketPath, }, diff --git a/builder/qemu/step_run.go b/builder/qemu/step_run.go index f7d277b4e..3943667c5 100644 --- a/builder/qemu/step_run.go +++ b/builder/qemu/step_run.go @@ -15,8 +15,7 @@ import ( // stepRun runs the virtual machine type stepRun struct { - BootDrive string - Message string + DiskImage bool } type qemuArgsTemplateData struct { @@ -32,9 +31,17 @@ func (s *stepRun) Run(ctx context.Context, state multistep.StateBag) multistep.S driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) - ui.Say(s.Message) + // Run command is different depending whether we're booting from an + // installation CD or a pre-baked image + bootDrive := "once=d" + message := "Starting VM, booting from CD-ROM" + if !s.DiskImage { + bootDrive = "c" + message = "Starting VM, booting disk image" + } + ui.Say(message) - command, err := getCommandArgs(s.BootDrive, state) + command, err := getCommandArgs(bootDrive, state) if err != nil { err := fmt.Errorf("Error processing QemuArgs: %s", err) ui.Error(err.Error()) diff --git a/builder/qemu/step_run_test.go b/builder/qemu/step_run_test.go index 7cbe27d08..426665a5d 100644 --- a/builder/qemu/step_run_test.go +++ b/builder/qemu/step_run_test.go @@ -1,6 +1,7 @@ package qemu import ( + "fmt" "testing" "github.com/hashicorp/packer/helper/multistep" @@ -8,20 +9,138 @@ import ( "github.com/stretchr/testify/assert" ) -func getTestConfig() *Config { - return &Config{} +func runTestState(t *testing.T, config *Config) multistep.StateBag { + state := new(multistep.BasicStateBag) + + state.Put("ui", packer.TestUi(t)) + state.Put("config", config) + + d := new(DriverMock) + d.VersionResult = "3.0.0" + state.Put("driver", d) + + state.Put("commHostPort", 5000) + state.Put("floppy_path", "fake_floppy_path") + state.Put("http_ip", "127.0.0.1") + state.Put("http_port", 1234) + state.Put("iso_path", "/path/to/test.iso") + state.Put("qemu_disk_paths", []string{}) + state.Put("vnc_port", 5905) + state.Put("vnc_password", "fake_vnc_password") + + return state } func Test_getCommandArgs(t *testing.T) { - state := new(multistep.BasicStateBag) - state.Put("vnc_port", 5905) - state.Put("iso_path", "/path/to/test.iso") - state.Put("ui", packer.TestUi(t)) - state.Put("config", &Config{}) + state := runTestState(t, &Config{}) + + args, err := getCommandArgs("", state) + if err != nil { + t.Fatalf("should not have an error getting args. Error: %s", err) + } + + expected := []string{ + "-display", "gtk", + "-m", "0M", + "-boot", "", + "-fda", "fake_floppy_path", + "-name", "", + "-netdev", "user,id=user.0,hostfwd=tcp::5000-:0", + "-vnc", ":5905", + "-machine", "type=,accel=", + "-device", ",netdev=user.0", + "-drive", "file=/path/to/test.iso,index=0,media=cdrom", + } + + assert.ElementsMatch(t, args, expected, "unexpected generated args") +} + +func Test_CDFilesPath(t *testing.T) { + // cd_path is set and DiskImage is false + state := runTestState(t, &Config{}) + state.Put("cd_path", "fake_cd_path.iso") args, err := getCommandArgs("", state) if err != nil { - t.Fatalf("should not have an error getting args") + t.Fatalf("should not have an error getting args. Error: %s", err) } - assert.Equal(t, args, []string{"partyargs"}, "should party 100 percent of the time") + + expected := []string{ + "-display", "gtk", + "-m", "0M", + "-boot", "", + "-fda", "fake_floppy_path", + "-name", "", + "-netdev", "user,id=user.0,hostfwd=tcp::5000-:0", + "-vnc", ":5905", + "-machine", "type=,accel=", + "-device", ",netdev=user.0", + "-drive", "file=/path/to/test.iso,index=0,media=cdrom", + "-drive", "file=fake_cd_path.iso,index=1,media=cdrom ", + } + + // cd_path is set and DiskImage is true + config := &Config{ + DiskImage: true, + DiskInterface: "virtio-scsi", + } + state = runTestState(t, config) + state.Put("cd_path", "fake_cd_path.iso") + + args, err = getCommandArgs("c", state) + if err != nil { + t.Fatalf("should not have an error getting args. Error: %s", err) + } + + expected = []string{ + "-display", "gtk", + "-m", "0M", + "-boot", "c", + "-fda", "fake_floppy_path", + "-name", "", + "-netdev", "user,id=user.0,hostfwd=tcp::5000-:0", + "-vnc", ":5905", + "-machine", "type=,accel=", + "-device", ",netdev=user.0", + "-device", "virtio-scsi-pci,id=scsi0", + "-device", "scsi-hd,bus=scsi0.0,drive=drive0", + "-drive", "if=none,file=,id=drive0,cache=,discard=,format=,detect-zeroes=", + "-drive", "file=fake_cd_path.iso,index=0,media=cdrom", + } + + assert.ElementsMatch(t, args, expected, fmt.Sprintf("unexpected generated args: %#v", args)) +} + +func Test_OptionalConfigOptionsGetSet(t *testing.T) { + c := &Config{ + VNCUsePassword: true, + QMPEnable: true, + QMPSocketPath: "qmp_path", + VMName: "MyFancyName", + MachineType: "pc", + Accelerator: "hvf", + } + + state := runTestState(t, c) + + args, err := getCommandArgs("once=d", state) + if err != nil { + t.Fatalf("should not have an error getting args. Error: %s", err) + } + + expected := []string{ + "-display", "gtk", + "-m", "0M", + "-boot", "once=d", + "-fda", "fake_floppy_path", + "-name", "MyFancyName", + "-netdev", "user,id=user.0,hostfwd=tcp::5000-:0", + "-vnc", ":5905,password", + "-machine", "type=pc,accel=hvf", + "-device", ",netdev=user.0", + "-drive", "file=/path/to/test.iso,index=0,media=cdrom", + "-qmp", "unix:qmp_path,server,nowait", + } + + assert.ElementsMatch(t, args, expected, "password flag should be set, and d drive should be set.") }