From aefb947fa94d9065a29c5354739353263474b6d4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 5 Jun 2013 17:32:57 -0700 Subject: [PATCH] builder/vmware: Support , send proper keycodes --- builder/vmware/step_type_boot_command.go | 36 ++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/builder/vmware/step_type_boot_command.go b/builder/vmware/step_type_boot_command.go index 0a9ec3086..b4bba8cc4 100644 --- a/builder/vmware/step_type_boot_command.go +++ b/builder/vmware/step_type_boot_command.go @@ -1,6 +1,7 @@ package vmware import ( + "bytes" "fmt" "github.com/mitchellh/go-vnc" "github.com/mitchellh/multistep" @@ -8,6 +9,7 @@ import ( "log" "net" "strings" + "text/template" "time" "unicode" "unicode/utf8" @@ -15,10 +17,17 @@ import ( const KeyLeftShift uint32 = 0xFFE1 +type bootCommandTemplateData struct { + HTTPIP string + HTTPPort int + Name string +} + // This step "types" the boot command into the VM over VNC. // // Uses: // config *config +// http_port int // ui packer.Ui // vnc_port uint // @@ -28,6 +37,7 @@ type stepTypeBootCommand struct{} func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAction { config := state["config"].(*config) + httpPort := state["http_port"].(int) ui := state["ui"].(packer.Ui) vncPort := state["vnc_port"].(uint) @@ -46,10 +56,21 @@ func (s *stepTypeBootCommand) Run(state map[string]interface{}) multistep.StepAc } defer c.Close() - log.Printf("Connecting to VNC desktop: %s", c.DesktopName) + log.Printf("Connected to VNC desktop: %s", c.DesktopName) + + tplData := &bootCommandTemplateData{ + "127.0.0.1", + httpPort, + config.VMName, + } + ui.Say("Typing the boot command over VNC...") for _, command := range config.BootCommand { - vncSendString(c, command) + var buf bytes.Buffer + t := template.Must(template.New("boot").Parse(command)) + t.Execute(&buf, tplData) + + vncSendString(c, buf.String()) } return multistep.ActionContinue @@ -63,11 +84,20 @@ func vncSendString(c *vnc.ClientConn, original string) { special[""] = 0xFF0D special[""] = 0xFF1B + shiftedChars := "~!@#$%^&*()_+{}|:\"<>?" + // TODO(mitchellh): Ripe for optimizations of some point, perhaps. for len(original) > 0 { var keyCode uint32 keyShift := false + if strings.HasPrefix(original, "") { + log.Printf("Special code '' found, sleeping one second") + time.Sleep(1 * time.Second) + original = original[len(""):] + continue + } + for specialCode, specialValue := range special { if strings.HasPrefix(original, specialCode) { log.Printf("Special code '%s' found, replacing with: %d", specialCode, specialValue) @@ -81,7 +111,7 @@ func vncSendString(c *vnc.ClientConn, original string) { r, size := utf8.DecodeRuneInString(original) original = original[size:] keyCode = uint32(r) - keyShift = unicode.IsUpper(r) + keyShift = unicode.IsUpper(r) || strings.ContainsRune(shiftedChars, r) log.Printf("Sending char '%c', code %d, shift %v", r, keyCode, keyShift) }