Bootcommand Fix For Proxmox Builder (#9885)
This commit is contained in:
parent
caf65781d7
commit
c032d463d3
|
@ -2,6 +2,7 @@ package proxmox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
@ -10,23 +11,33 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type proxmoxDriver struct {
|
type proxmoxDriver struct {
|
||||||
client commandTyper
|
client commandTyper
|
||||||
vmRef *proxmox.VmRef
|
vmRef *proxmox.VmRef
|
||||||
specialMap map[string]string
|
specialMap map[string]string
|
||||||
runeMap map[rune]string
|
runeMap map[rune]string
|
||||||
interval time.Duration
|
interval time.Duration
|
||||||
|
specialBuffer []string
|
||||||
|
normalBuffer []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProxmoxDriver(c commandTyper, vmRef *proxmox.VmRef, interval time.Duration) *proxmoxDriver {
|
func NewProxmoxDriver(c commandTyper, vmRef *proxmox.VmRef, interval time.Duration) *proxmoxDriver {
|
||||||
// Mappings for packer shorthand to qemu qkeycodes
|
// Mappings for packer shorthand to qemu qkeycodes
|
||||||
sMap := map[string]string{
|
sMap := map[string]string{
|
||||||
"spacebar": "spc",
|
"spacebar": "spc",
|
||||||
"bs": "backspace",
|
"bs": "backspace",
|
||||||
"del": "delete",
|
"del": "delete",
|
||||||
"return": "ret",
|
"return": "ret",
|
||||||
"enter": "ret",
|
"enter": "ret",
|
||||||
"pageUp": "pgup",
|
"pageUp": "pgup",
|
||||||
"pageDown": "pgdn",
|
"pageDown": "pgdn",
|
||||||
|
"leftshift": "shift",
|
||||||
|
"rightshift": "shift",
|
||||||
|
"leftalt": "alt",
|
||||||
|
"rightalt": "alt_r",
|
||||||
|
"leftctrl": "ctrl",
|
||||||
|
"rightctrl": "ctrl_r",
|
||||||
|
"leftsuper": "meta_l",
|
||||||
|
"rightsuper": "meta_r",
|
||||||
}
|
}
|
||||||
// Mappings for runes that need to be translated to special qkeycodes
|
// Mappings for runes that need to be translated to special qkeycodes
|
||||||
// Taken from https://github.com/qemu/qemu/blob/master/pc-bios/keymaps/en-us
|
// Taken from https://github.com/qemu/qemu/blob/master/pc-bios/keymaps/en-us
|
||||||
|
@ -78,18 +89,26 @@ func NewProxmoxDriver(c commandTyper, vmRef *proxmox.VmRef, interval time.Durati
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxmoxDriver) SendKey(key rune, action bootcommand.KeyAction) error {
|
func (p *proxmoxDriver) SendKey(key rune, action bootcommand.KeyAction) error {
|
||||||
if special, ok := p.runeMap[key]; ok {
|
switch action.String() {
|
||||||
return p.send(special)
|
case "Press":
|
||||||
|
if special, ok := p.runeMap[key]; ok {
|
||||||
|
return p.send(special)
|
||||||
|
}
|
||||||
|
var keys string
|
||||||
|
if unicode.IsUpper(key) {
|
||||||
|
keys = fmt.Sprintf("shift-%c", unicode.ToLower(key))
|
||||||
|
} else {
|
||||||
|
keys = fmt.Sprintf("%c", key)
|
||||||
|
}
|
||||||
|
return p.send(keys)
|
||||||
|
case "On":
|
||||||
|
key := fmt.Sprintf("%c", key)
|
||||||
|
p.normalBuffer = addKeyToBuffer(p.normalBuffer, key)
|
||||||
|
case "Off":
|
||||||
|
key := fmt.Sprintf("%c", key)
|
||||||
|
p.normalBuffer = removeKeyFromBuffer(p.normalBuffer, key)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
var keys string
|
|
||||||
if unicode.IsUpper(key) {
|
|
||||||
keys = fmt.Sprintf("shift-%c", unicode.ToLower(key))
|
|
||||||
} else {
|
|
||||||
keys = fmt.Sprintf("%c", key)
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.send(keys)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxmoxDriver) SendSpecial(special string, action bootcommand.KeyAction) error {
|
func (p *proxmoxDriver) SendSpecial(special string, action bootcommand.KeyAction) error {
|
||||||
|
@ -97,18 +116,48 @@ func (p *proxmoxDriver) SendSpecial(special string, action bootcommand.KeyAction
|
||||||
if replacement, ok := p.specialMap[special]; ok {
|
if replacement, ok := p.specialMap[special]; ok {
|
||||||
keys = replacement
|
keys = replacement
|
||||||
}
|
}
|
||||||
|
switch action.String() {
|
||||||
return p.send(keys)
|
case "Press":
|
||||||
|
return p.send(keys)
|
||||||
|
case "On":
|
||||||
|
p.specialBuffer = addKeyToBuffer(p.specialBuffer, keys)
|
||||||
|
case "Off":
|
||||||
|
p.specialBuffer = removeKeyFromBuffer(p.specialBuffer, keys)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxmoxDriver) send(keys string) error {
|
func (p *proxmoxDriver) send(key string) error {
|
||||||
err := p.client.Sendkey(p.vmRef, keys)
|
keys := append(p.specialBuffer, p.normalBuffer...)
|
||||||
|
keys = append(keys, key)
|
||||||
|
keyEventString := bufferToKeyEvent(keys)
|
||||||
|
err := p.client.Sendkey(p.vmRef, keyEventString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(p.interval)
|
time.Sleep(p.interval)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *proxmoxDriver) Flush() error { return nil }
|
func (p *proxmoxDriver) Flush() error { return nil }
|
||||||
|
|
||||||
|
func bufferToKeyEvent(keys []string) string {
|
||||||
|
return strings.Join(keys, "-")
|
||||||
|
}
|
||||||
|
func addKeyToBuffer(buffer []string, key string) []string {
|
||||||
|
for _, value := range buffer {
|
||||||
|
if value == key {
|
||||||
|
return buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return append(buffer, key)
|
||||||
|
}
|
||||||
|
func removeKeyFromBuffer(buffer []string, key string) []string {
|
||||||
|
for index, value := range buffer {
|
||||||
|
if value == key {
|
||||||
|
buffer[index] = buffer[len(buffer)-1]
|
||||||
|
return buffer[:len(buffer)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer
|
||||||
|
}
|
||||||
|
|
|
@ -52,6 +52,34 @@ func TestTypeBootCommand(t *testing.T) {
|
||||||
expectedKeysSent: "shift-hellospcshift-worldspc2dot0fooshift-1barshift-2baz",
|
expectedKeysSent: "shift-hellospcshift-worldspc2dot0fooshift-1barshift-2baz",
|
||||||
expectedAction: multistep.ActionContinue,
|
expectedAction: multistep.ActionContinue,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "holding and releasing keys",
|
||||||
|
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"<leftShiftOn>hello<rightAltOn>world<leftShiftOff><rightAltOff>"}}},
|
||||||
|
expectCallSendkey: true,
|
||||||
|
expectedKeysSent: "shift-hshift-eshift-lshift-lshift-oshift-alt_r-wshift-alt_r-oshift-alt_r-rshift-alt_r-lshift-alt_r-d",
|
||||||
|
expectedAction: multistep.ActionContinue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "holding multiple alphabetical keys and shift",
|
||||||
|
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"<cOn><leftShiftOn>n<leftShiftOff><cOff>"}}},
|
||||||
|
expectCallSendkey: true,
|
||||||
|
expectedKeysSent: "shift-c-n",
|
||||||
|
expectedAction: multistep.ActionContinue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "noop keystrokes",
|
||||||
|
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"<cOn><leftShiftOn><cOff><leftAltOn><leftShiftOff><leftAltOff>"}}},
|
||||||
|
expectCallSendkey: true,
|
||||||
|
expectedKeysSent: "",
|
||||||
|
expectedAction: multistep.ActionContinue,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "noop keystrokes mixed",
|
||||||
|
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{"<cOn><leftShiftOn><cOff>h<leftShiftOff>"}}},
|
||||||
|
expectCallSendkey: true,
|
||||||
|
expectedKeysSent: "shift-h",
|
||||||
|
expectedAction: multistep.ActionContinue,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "without boot command sendkey should not be called",
|
name: "without boot command sendkey should not be called",
|
||||||
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{}}},
|
builderConfig: &Config{BootConfig: bootcommand.BootConfig{BootCommand: []string{}}},
|
||||||
|
|
Loading…
Reference in New Issue