From 038787ed48780b4e8de98e7946271f8e42a2b692 Mon Sep 17 00:00:00 2001 From: Brian Ruff Date: Sun, 4 Dec 2016 11:28:18 -0700 Subject: [PATCH 1/3] Refactored to gather scan codes into groups to be sent to VirtualBox's console. --- .../common/step_type_boot_command.go | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index ab9cd5c70..0d13fffb8 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -65,7 +65,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction return multistep.ActionHalt } - for _, code := range scancodes(command) { + for _, code := range gathercodes(scancodes(command)) { if code == "wait" { time.Sleep(1 * time.Second) continue @@ -91,7 +91,9 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction pauseFn(multistep.DebugLocationAfterRun, fmt.Sprintf("boot_command[%d]: %s", i, command), state) } - if err := driver.VBoxManage("controlvm", vmName, "keyboardputscancode", code); err != nil { + args := []string{"controlvm", vmName, "keyboardputscancode"} + args = append(args, strings.Split(code, " ")...) + if err := driver.VBoxManage(args...); err != nil { err := fmt.Errorf("Error sending boot command: %s", err) state.Put("error", err) ui.Error(err.Error()) @@ -105,6 +107,27 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} +// Gather scancodes to send to console efficiently. +func gathercodes(codes []string) []string { + result := make([]string, 0, len(codes)) + begin := 0 + end := 0 + for pos, code := range codes { + if strings.HasPrefix(code, "wait") { + if pos > begin { + result = append(result, strings.Join(codes[begin:end+1], " ")) + } + result = append(result, code) + begin = pos + 1 + } + end = pos + } + if end > begin { + result = append(result, strings.Join(codes[begin:end+1], " ")) + } + return result +} + func scancodes(message string) []string { // Scancodes reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html // From aa177de54bb62c1097d152153b60658f5c954ee4 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 20 Dec 2016 17:51:47 -0800 Subject: [PATCH 2/3] add test for #4247 --- .../common/step_type_boot_command_test.go | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 builder/virtualbox/common/step_type_boot_command_test.go diff --git a/builder/virtualbox/common/step_type_boot_command_test.go b/builder/virtualbox/common/step_type_boot_command_test.go new file mode 100644 index 000000000..bfb7b1729 --- /dev/null +++ b/builder/virtualbox/common/step_type_boot_command_test.go @@ -0,0 +1,29 @@ +package common + +import ( + "reflect" + "testing" +) + +func TestStepTypeBootCommand_gather(t *testing.T) { + input := [][]string{ + {"02", "82", "wait1", "03", "83"}, + {"02", "82", "03", "83"}, + {"wait5", "wait1", "wait10"}, + {"wait5", "02", "82", "03", "83", "wait1", "wait10"}, + } + + expected := [][]string{ + {"02 82", "wait1", "03 83"}, + {"02 82 03 83"}, + {"wait5", "wait1", "wait10"}, + {"wait5", "02 82 03 83", "wait1", "wait10"}, + } + + for i, data := range input { + if !reflect.DeepEqual(gathercodes(data), expected[i]) { + t.Fatalf("%#v did not equal expected %#v", data, expected[i]) + } + } + +} From ee86dc87fde85e3fe5622e2d524852dcca09fe75 Mon Sep 17 00:00:00 2001 From: Matthew Hooker Date: Tue, 20 Dec 2016 18:10:58 -0800 Subject: [PATCH 3/3] fix broken test --- .../common/step_type_boot_command.go | 30 +++++++++---------- .../common/step_type_boot_command_test.go | 10 +++++-- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index 0d13fffb8..aa12df00f 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -108,24 +108,24 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {} // Gather scancodes to send to console efficiently. -func gathercodes(codes []string) []string { - result := make([]string, 0, len(codes)) - begin := 0 - end := 0 - for pos, code := range codes { - if strings.HasPrefix(code, "wait") { - if pos > begin { - result = append(result, strings.Join(codes[begin:end+1], " ")) - } - result = append(result, code) - begin = pos + 1 +func gathercodes(codes []string) (gathered []string) { + working := []string{} + pushWorking := func() { + if len(working) > 0 { + gathered = append(gathered, strings.Join(working, " ")) + working = []string{} } - end = pos } - if end > begin { - result = append(result, strings.Join(codes[begin:end+1], " ")) + for _, code := range codes { + if strings.HasPrefix(code, "wait") { + pushWorking() + gathered = append(gathered, code) + } else { + working = append(working, code) + } } - return result + pushWorking() + return } func scancodes(message string) []string { diff --git a/builder/virtualbox/common/step_type_boot_command_test.go b/builder/virtualbox/common/step_type_boot_command_test.go index bfb7b1729..53b33bda5 100644 --- a/builder/virtualbox/common/step_type_boot_command_test.go +++ b/builder/virtualbox/common/step_type_boot_command_test.go @@ -11,6 +11,8 @@ func TestStepTypeBootCommand_gather(t *testing.T) { {"02", "82", "03", "83"}, {"wait5", "wait1", "wait10"}, {"wait5", "02", "82", "03", "83", "wait1", "wait10"}, + {"wait1"}, + {"01"}, } expected := [][]string{ @@ -18,12 +20,14 @@ func TestStepTypeBootCommand_gather(t *testing.T) { {"02 82 03 83"}, {"wait5", "wait1", "wait10"}, {"wait5", "02 82 03 83", "wait1", "wait10"}, + {"wait1"}, + {"01"}, } for i, data := range input { - if !reflect.DeepEqual(gathercodes(data), expected[i]) { - t.Fatalf("%#v did not equal expected %#v", data, expected[i]) + gathered := gathercodes(data) + if !reflect.DeepEqual(gathered, expected[i]) { + t.Fatalf("%#v did not equal expected %#v", gathered, expected[i]) } } - }