QM Sendkey Automation – QEMU

Manche VMs lassen sich nicht per SSH oder API konfigurieren – etwa Firewall-Appliances, Router-VMs oder Installer ohne Netzwerk. Hier hilft qm sendkey: simulierte Tastatureingaben direkt an die VM-Konsole.

Grundlagen

# Einzelne Taste senden
qm sendkey <vmid> <key>

# Beispiele
qm sendkey 100 a
qm sendkey 100 kp_enter
qm sendkey 100 ctrl-alt-delete

Der Befehl sendet Tastenanschläge an die VM-Konsole, als würde jemand physisch an der Tastatur tippen.

Verfügbare Tasten

Buchstaben und Zahlen

qm sendkey 100 a        # Buchstabe a
qm sendkey 100 5        # Ziffer 5
qm sendkey 100 shift-a  # Großbuchstabe A

Sonderzeichen

qm sendkey 100 dot      # Punkt (.)
qm sendkey 100 minus    # Minus (-)
qm sendkey 100 slash    # Slash (/)
qm sendkey 100 shift-2  # @ (auf deutscher Tastatur)

Steuerzeichen

qm sendkey 100 kp_enter     # Enter (Keypad)
qm sendkey 100 ret          # Return
qm sendkey 100 tab          # Tab
qm sendkey 100 esc          # Escape
qm sendkey 100 backspace    # Backspace
qm sendkey 100 delete       # Delete

Tastenkombinationen

qm sendkey 100 ctrl-alt-delete

Praktisches Beispiel: IP-Adresse eingeben

# 192.168.100.1 eingeben
qm sendkey 100 1
qm sendkey 100 9
qm sendkey 100 2
qm sendkey 100 dot
qm sendkey 100 1
qm sendkey 100 6
qm sendkey 100 8
qm sendkey 100 dot
qm sendkey 100 1
qm sendkey 100 0
qm sendkey 100 0
qm sendkey 100 dot
qm sendkey 100 1
qm sendkey 100 kp_enter

Kritische Herausforderungen

1. Timing ist alles

Die VM braucht Zeit zum Verarbeiten. Ohne Pausen können Eingaben verloren gehen:

# FALSCH - zu schnell
qm sendkey 100 r
qm sendkey 100 o
qm sendkey 100 o
qm sendkey 100 t

# RICHTIG - mit Pausen
qm sendkey 100 r
sleep 0.5
qm sendkey 100 o
sleep 0.5
qm sendkey 100 o
sleep 0.5
qm sendkey 100 t

Bei Menüwechseln oder Boot-Vorgängen längere Pausen einbauen:

qm start 100
sleep 30  # Boot-Zeit abwarten
qm sendkey 100 kp_enter

2. Tastatur-Layout beachten

qm sendkey verwendet US-Tastatur-Layout. Deutsche Sonderzeichen sind problematisch:

# @ auf US-Layout
qm sendkey 100 shift-2  # ergibt @

3. Keine Fehlerprüfung möglich

Man sieht nicht, ob die Eingabe ankam oder was auf dem Bildschirm steht:

# Blindflug - Script weiß nicht, ob Eingabe erfolgreich war
qm sendkey 100 r
qm sendkey 100 o
qm sendkey 100 o
qm sendkey 100 t
qm sendkey 100 kp_enter

# Fehler werden nicht erkannt

Workaround: Feste Wartezeiten und deterministisches Verhalten der VM voraussetzen.

4. Mehrstellige Zahlen dynamisch eingeben

Statische Eingaben sind einfach. Dynamische Werte erfordern Logik:

# Zahl in Ziffern zerlegen
send_number() {
    local num=$1
    local vmid=$2
    
    if [ $num -ge 100 ]; then
        # Dreistellig: 123 → 1, 2, 3
        local d1=$((num / 100))
        local d2=$(((num % 100) / 10))
        local d3=$((num % 10))
        qm sendkey $vmid $d1
        qm sendkey $vmid $d2
        qm sendkey $vmid $d3
    elif [ $num -ge 10 ]; then
        # Zweistellig: 42 → 4, 2
        local d1=$((num / 10))
        local d2=$((num % 10))
        qm sendkey $vmid $d1
        qm sendkey $vmid $d2
    else
        # Einstellig
        qm sendkey $vmid $num
    fi
}

# Verwendung (100 ist die VM-ID)
send_number 192 100
qm sendkey 100 dot
send_number 168 100

5. Enter vs. Return vs. KP_Enter

Verschiedene VMs reagieren unterschiedlich:

qm sendkey 100 kp_enter  # Keypad Enter (meist sicherer)
qm sendkey 100 ret       # Return-Taste
qm sendkey 100 enter     # Alias für ret

Empfehlung: kp_enter verwenden – funktioniert in den meisten Fällen.

Anwendungsfälle

1. BIOS/UEFI-Konfiguration


# Boot-Reihenfolge ändern
sleep 2
qm sendkey 100 right
qm sendkey 100 down
qm sendkey 100 kp_enter

2. Installer ohne Netzwerk

# Debian-Installer durchklicken
qm sendkey 100 kp_enter  # Sprache wählen
sleep 1
qm sendkey 100 kp_enter  # Land wählen
sleep 1
qm sendkey 100 kp_enter  # Tastatur wählen

3. Firewall-/Router-Konfiguration

# pfSense/OPNsense initial setup
qm sendkey 100 1         # Interface assignment
qm sendkey 100 kp_enter
qm sendkey 100 2         # IP konfigurieren
qm sendkey 100 kp_enter
# IP eingeben...

4. Grub-Menü steuern

# Kernel-Option wählen
qm sendkey 100 down
qm sendkey 100 down
qm sendkey 100 kp_enter

Best Practices

1. Konsistente Wartezeiten

BOOT_WAIT=30
MENU_WAIT=2
INPUT_WAIT=0.5

sleep $BOOT_WAIT
qm sendkey 100 1
sleep $INPUT_WAIT

2. Dry-Run implementieren

send_key() {
    local vmid=$1
    local key=$2
    if [ "$DRY_RUN" = true ]; then
        echo "[DRY] qm sendkey $vmid $key"
    else
        qm sendkey $vmid $key
    fi
}

3. Logging

log_keystroke() {
    echo "$(date +%H:%M:%S) - VM $1: $2" >> keystroke.log
    qm sendkey "$1" "$2"
}

Debugging

Problem: Eingaben kommen nicht an

# Längere Pausen testen
sleep 1  # statt 0.5

Problem: Falsche Zeichen

# Tastatur-Layout in VM prüfen
# US-Layout erzwingen

Problem: VM reagiert nicht

# Konsole manuell öffnen und beobachten
# NoVNC-Console in Proxmox Web-UI

Limitationen

  • Keine Rückmeldung über Erfolg/Misserfolg
  • Abhängig von exaktem Timing
  • Tastatur-Layout-Probleme
  • Nicht geeignet für komplexe interaktive Eingaben
  • Keine Fehlerbehandlung möglich

Mein Eindruck

qm sendkey ist ein mächtiges Werkzeug für Automation in Fällen, wo SSH/API nicht verfügbar ist. Der Schlüssel zum Erfolg: deterministisches VM-Verhalten, robuste Wartezeiten und gründliches Testing. Nicht elegant, aber effektiv.

Comments

No comments yet. Why don’t you start the discussion?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert