|
|
|
|
@ -2,6 +2,7 @@ package proxmox
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
"unicode"
|
|
|
|
|
|
|
|
|
|
@ -10,23 +11,33 @@ import (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type proxmoxDriver struct {
|
|
|
|
|
client commandTyper
|
|
|
|
|
vmRef *proxmox.VmRef
|
|
|
|
|
specialMap map[string]string
|
|
|
|
|
runeMap map[rune]string
|
|
|
|
|
interval time.Duration
|
|
|
|
|
client commandTyper
|
|
|
|
|
vmRef *proxmox.VmRef
|
|
|
|
|
specialMap map[string]string
|
|
|
|
|
runeMap map[rune]string
|
|
|
|
|
interval time.Duration
|
|
|
|
|
specialBuffer []string
|
|
|
|
|
normalBuffer []string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewProxmoxDriver(c commandTyper, vmRef *proxmox.VmRef, interval time.Duration) *proxmoxDriver {
|
|
|
|
|
// Mappings for packer shorthand to qemu qkeycodes
|
|
|
|
|
sMap := map[string]string{
|
|
|
|
|
"spacebar": "spc",
|
|
|
|
|
"bs": "backspace",
|
|
|
|
|
"del": "delete",
|
|
|
|
|
"return": "ret",
|
|
|
|
|
"enter": "ret",
|
|
|
|
|
"pageUp": "pgup",
|
|
|
|
|
"pageDown": "pgdn",
|
|
|
|
|
"spacebar": "spc",
|
|
|
|
|
"bs": "backspace",
|
|
|
|
|
"del": "delete",
|
|
|
|
|
"return": "ret",
|
|
|
|
|
"enter": "ret",
|
|
|
|
|
"pageUp": "pgup",
|
|
|
|
|
"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
|
|
|
|
|
// 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 {
|
|
|
|
|
if special, ok := p.runeMap[key]; ok {
|
|
|
|
|
return p.send(special)
|
|
|
|
|
switch action.String() {
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
keys = replacement
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return p.send(keys)
|
|
|
|
|
switch action.String() {
|
|
|
|
|
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 {
|
|
|
|
|
err := p.client.Sendkey(p.vmRef, keys)
|
|
|
|
|
func (p *proxmoxDriver) send(key string) error {
|
|
|
|
|
keys := append(p.specialBuffer, p.normalBuffer...)
|
|
|
|
|
keys = append(keys, key)
|
|
|
|
|
keyEventString := bufferToKeyEvent(keys)
|
|
|
|
|
err := p.client.Sendkey(p.vmRef, keyEventString)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
time.Sleep(p.interval)
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|