feat(deploy+bench+ops): DGX vm scripts, Windows RDP launcher, bench cases, agent_chat enable script
This commit is contained in:
60
deploy/dgx/vm_launch.sh
Executable file
60
deploy/dgx/vm_launch.sh
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
# Persistent VM launch — starts swtpm first, waits for socket, then QEMU
|
||||
# VNC only, no SPICE (POC configuration)
|
||||
VMROOT=/home/aivanov/quickemu-win11-arm-lea
|
||||
SWTPM_SOCK="$VMROOT/windows-11-arm-lea.swtpm-sock"
|
||||
|
||||
/usr/bin/swtpm socket \
|
||||
--ctrl type=unixio,path="$SWTPM_SOCK" \
|
||||
--terminate \
|
||||
--tpmstate dir="$VMROOT" \
|
||||
--tpm2 &
|
||||
|
||||
# Wait for swtpm socket (up to 10s)
|
||||
for _i in $(seq 1 100); do
|
||||
if [ -S "$SWTPM_SOCK" ]; then break; fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if [ ! -S "$SWTPM_SOCK" ]; then
|
||||
echo "ERROR: swtpm socket not ready after 10s"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec /usr/bin/qemu-system-aarch64 \
|
||||
-name windows-11-arm-lea \
|
||||
-machine virt,highmem=on,pflash0=rom,pflash1=efivars,accel=kvm \
|
||||
-global kvm-pit.lost_tick_policy=discard \
|
||||
-cpu host \
|
||||
-smp cores=8,threads=1,sockets=1 \
|
||||
-m 8G \
|
||||
-device virtio-balloon \
|
||||
-pidfile "$VMROOT/windows-11-arm-lea.pid" \
|
||||
-rtc base=utc,clock=host \
|
||||
-device ramfb \
|
||||
-vga none \
|
||||
-device virtio-gpu-pci,id=video0,xres=1280,yres=800 \
|
||||
-display none \
|
||||
-vnc 127.0.0.1:2,password=on \
|
||||
-device virtio-serial-pci \
|
||||
-chardev socket,id=agent0,path="$VMROOT/windows-11-arm-lea-agent.sock",server=on,wait=off \
|
||||
-device virtserialport,chardev=agent0,name=org.qemu.guest_agent.0 \
|
||||
-device virtio-rng-pci,rng=rng0 \
|
||||
-object rng-random,id=rng0,filename=/dev/urandom \
|
||||
-device qemu-xhci,id=input \
|
||||
-device usb-kbd,bus=input.0 \
|
||||
-k fr \
|
||||
-device usb-tablet,bus=input.0 \
|
||||
-device virtio-net-pci,netdev=nic \
|
||||
-netdev user,hostname=windows-11-arm-lea,hostfwd=tcp::22220-:22,id=nic \
|
||||
-blockdev node-name=rom,driver=file,filename=/usr/share/AAVMF/AAVMF_CODE.no-secboot.fd,read-only=true \
|
||||
-blockdev node-name=efivars,driver=file,filename="$VMROOT/OVMF_VARS.fd" \
|
||||
-device virtio-scsi-pci,id=scsi0 \
|
||||
-device scsi-hd,drive=SystemDisk,bus=scsi0.0,bootindex=2 \
|
||||
-drive id=SystemDisk,if=none,format=qcow2,file="$VMROOT/disk.qcow2",discard=unmap,detect-zeroes=unmap,cache=writeback,aio=threads \
|
||||
-chardev socket,id=chrtpm,path="$SWTPM_SOCK" \
|
||||
-tpmdev emulator,id=tpm0,chardev=chrtpm \
|
||||
-device tpm-tis-device,tpmdev=tpm0 \
|
||||
-monitor unix:"$VMROOT/windows-11-arm-lea-monitor.socket",server,nowait \
|
||||
-serial unix:"$VMROOT/windows-11-arm-lea-serial.socket",server,nowait \
|
||||
2>"$VMROOT/qemu.log"
|
||||
50
deploy/dgx/vm_stop.sh
Executable file
50
deploy/dgx/vm_stop.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
# Persistent VM stop — ACPI poweroff via QEMU monitor, then SIGTERM, then SIGKILL
|
||||
# Kill swtpm after QEMU exits. Cleanup PID/sockets.
|
||||
|
||||
VMROOT=/home/aivanov/quickemu-win11-arm-lea
|
||||
MONITOR_SOCKET="$VMROOT/windows-11-arm-lea-monitor.socket"
|
||||
PIDFILE="$VMROOT/windows-11-arm-lea.pid"
|
||||
|
||||
# Step 1: Send ACPI poweroff via QEMU monitor
|
||||
if [ -S "$MONITOR_SOCKET" ]; then
|
||||
echo "system_powerdown" | socat - UNIX-CONNECT:"$MONITOR_SOCKET" - > /dev/null 2>&1
|
||||
echo "ACPI poweroff sent, waiting 30s..."
|
||||
for i in $(seq 1 30); do
|
||||
if [ ! -f "$PIDFILE" ] || ! ps -p "$(cat "$PIDFILE" 2>/dev/null)" > /dev/null 2>&1; then
|
||||
echo "QEMU exited gracefully"
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
# Step 2: SIGTERM (10s more)
|
||||
QEMU_PID=$(cat "$PIDFILE" 2>/dev/null)
|
||||
if [ -n "$QEMU_PID" ] && ps -p "$QEMU_PID" > /dev/null 2>&1; then
|
||||
echo "Still running, sending SIGTERM..."
|
||||
kill "$QEMU_PID" 2>/dev/null
|
||||
for i in $(seq 1 10); do
|
||||
if ! ps -p "$QEMU_PID" > /dev/null 2>&1; then
|
||||
echo "QEMU exited after SIGTERM"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
# Step 3: SIGKILL
|
||||
QEMU_PID=$(cat "$PIDFILE" 2>/dev/null)
|
||||
if [ -n "$QEMU_PID" ] && ps -p "$QEMU_PID" > /dev/null 2>&1; then
|
||||
echo "Still running, SIGKILL..."
|
||||
kill -9 "$QEMU_PID" 2>/dev/null
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# Step 4: Kill swtpm
|
||||
pkill -f "swtpm.*windows-11-arm-lea" 2>/dev/null
|
||||
sleep 2
|
||||
|
||||
# Step 5: Cleanup
|
||||
rm -f "$PIDFILE" "$VMROOT"/*.sock "$VMROOT"/*.socket 2>/dev/null
|
||||
echo "VM stop complete"
|
||||
44
deploy/windows-rdp-launcher/Connexion-VM-Lea.cmd
Normal file
44
deploy/windows-rdp-launcher/Connexion-VM-Lea.cmd
Normal file
@@ -0,0 +1,44 @@
|
||||
@echo off
|
||||
chcp 65001 >nul
|
||||
title Connexion VM Lea (via DGX)
|
||||
|
||||
REM ============================================================
|
||||
REM Connexion Bureau a distance a la VM Windows (Lea) du DGX.
|
||||
REM Ouvre un tunnel SSH, lance le RDP (presse-papier actif),
|
||||
REM puis referme le tunnel quand la session RDP est fermee.
|
||||
REM ============================================================
|
||||
|
||||
REM --- Parametres (ajuste si besoin) ---
|
||||
set "DGX_USER=aivanov"
|
||||
set "DGX_HOST=192.168.1.45"
|
||||
REM En deplacement (WireGuard, plus tard) : mettre DGX_HOST=10.10.0.1
|
||||
set "LOCAL_PORT=13389"
|
||||
set "RDP_FILE=%~dp0VM-Lea.rdp"
|
||||
|
||||
echo.
|
||||
echo [1/3] Ouverture du tunnel SSH vers %DGX_USER%@%DGX_HOST% ...
|
||||
echo (si un mot de passe est demande, saisis-le dans la fenetre "Tunnel")
|
||||
start "Tunnel-DGX-VMLea" ssh -o StrictHostKeyChecking=accept-new -o ExitOnForwardFailure=yes -N -L %LOCAL_PORT%:127.0.0.1:3390 %DGX_USER%@%DGX_HOST%
|
||||
|
||||
echo [2/3] Attente de l'etablissement du tunnel (max ~30s)...
|
||||
set /a tries=0
|
||||
:wait
|
||||
timeout /t 1 /nobreak >nul
|
||||
powershell -NoProfile -Command "try{(New-Object Net.Sockets.TcpClient).Connect('127.0.0.1',%LOCAL_PORT%);exit 0}catch{exit 1}" >nul 2>&1
|
||||
if not errorlevel 1 goto ready
|
||||
set /a tries+=1
|
||||
if %tries% lss 30 goto wait
|
||||
echo ! Tunnel non etabli. Verifie l'acces SSH au DGX (mot de passe / reseau).
|
||||
pause
|
||||
goto cleanup
|
||||
|
||||
:ready
|
||||
echo [3/3] Connexion Bureau a distance (localhost:%LOCAL_PORT%) ...
|
||||
mstsc "%RDP_FILE%"
|
||||
|
||||
:cleanup
|
||||
echo.
|
||||
echo Fermeture du tunnel SSH...
|
||||
taskkill /FI "WINDOWTITLE eq Tunnel-DGX-VMLea*" /T /F >nul 2>&1
|
||||
echo Termine.
|
||||
timeout /t 2 /nobreak >nul
|
||||
35
deploy/windows-rdp-launcher/LISEZMOI.txt
Normal file
35
deploy/windows-rdp-launcher/LISEZMOI.txt
Normal file
@@ -0,0 +1,35 @@
|
||||
CONNEXION BUREAU A DISTANCE - VM Lea (DGX)
|
||||
==========================================
|
||||
|
||||
CONTENU
|
||||
- Connexion-VM-Lea.cmd : le lanceur (double-clic)
|
||||
- VM-Lea.rdp : le profil de connexion RDP (presse-papier active)
|
||||
|
||||
INSTALLATION (sur ton laptop Windows)
|
||||
1. Copie les DEUX fichiers dans le MEME dossier (ex: le Bureau).
|
||||
2. (Optionnel) clic droit sur Connexion-VM-Lea.cmd > Envoyer vers > Bureau
|
||||
(creer un raccourci), pour un acces rapide.
|
||||
|
||||
UTILISATION
|
||||
- Double-clic sur "Connexion-VM-Lea.cmd".
|
||||
- Une fenetre "Tunnel" s'ouvre : si un mot de passe SSH est demande,
|
||||
saisis le mot de passe du compte aivanov du DGX.
|
||||
- Le Bureau a distance s'ouvre ensuite : saisis ton identifiant + mot de
|
||||
passe WINDOWS de la VM.
|
||||
- Copier-coller (texte ET fichiers) fonctionne dans les deux sens.
|
||||
- Ferme la fenetre RDP pour finir : le tunnel se referme automatiquement.
|
||||
|
||||
PRE-REQUIS
|
||||
- Etre sur le reseau du labo (meme WiFi) pour joindre 192.168.1.45.
|
||||
- OpenSSH client (inclus dans Windows 10/11).
|
||||
- Le Bureau a distance doit etre active dans la VM (deja fait).
|
||||
|
||||
EN DEPLACEMENT (plus tard)
|
||||
- Quand WireGuard sera en place, edite Connexion-VM-Lea.cmd et remplace
|
||||
DGX_HOST=192.168.1.45 par DGX_HOST=10.10.0.1
|
||||
- Tout le reste est identique. L'adresse RDP reste localhost:13389.
|
||||
|
||||
CONFORT (optionnel, recommande)
|
||||
- Pour ne plus saisir le mot de passe SSH a chaque fois : on signe la cle
|
||||
SSH de ton laptop avec la CA (acces par certificat). Demande-le moi et
|
||||
envoie-moi la cle publique de ton laptop.
|
||||
18
deploy/windows-rdp-launcher/VM-Lea.rdp
Normal file
18
deploy/windows-rdp-launcher/VM-Lea.rdp
Normal file
@@ -0,0 +1,18 @@
|
||||
full address:s:localhost:13389
|
||||
prompt for credentials:i:1
|
||||
redirectclipboard:i:1
|
||||
redirectdrives:i:1
|
||||
drivestoredirect:s:*
|
||||
redirectprinters:i:0
|
||||
redirectsmartcards:i:0
|
||||
audiomode:i:2
|
||||
authentication level:i:0
|
||||
negotiate security layer:i:1
|
||||
enablecredsspsupport:i:1
|
||||
screen mode id:i:2
|
||||
dynamic resolution:i:1
|
||||
desktopwidth:i:1280
|
||||
desktopheight:i:800
|
||||
session bpp:i:32
|
||||
compression:i:1
|
||||
username:s:
|
||||
32
deploy/windows-rdp-launcher/connexion-vm-lea.sh
Executable file
32
deploy/windows-rdp-launcher/connexion-vm-lea.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# RDP vers la VM Windows (Lea) du DGX, depuis ce serveur Linux (.40).
|
||||
# Ouvre un tunnel SSH (par certificat) puis lance xfreerdp.
|
||||
# Presse-papier + dossier $HOME partage. Tunnel ferme a la sortie.
|
||||
#
|
||||
# Usage:
|
||||
# ./connexion-vm-lea.sh # labo (DGX = 192.168.1.45)
|
||||
# ./connexion-vm-lea.sh 10.10.0.1 # en deplacement (via WireGuard)
|
||||
# ./connexion-vm-lea.sh 192.168.1.45 /u:MonUserWindows
|
||||
set -euo pipefail
|
||||
|
||||
DGX_HOST="${1:-192.168.1.45}"
|
||||
[ $# -gt 0 ] && shift || true
|
||||
LOCAL_PORT=13389
|
||||
CTL="$(mktemp -u /tmp/rdp-vmlea-ctl.XXXXXX)"
|
||||
|
||||
cleanup(){ ssh -S "$CTL" -O exit "aivanov@${DGX_HOST}" >/dev/null 2>&1 || true; }
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "[1/3] Tunnel SSH (cert) vers aivanov@${DGX_HOST} ..."
|
||||
ssh -o ExitOnForwardFailure=yes -fN -M -S "$CTL" -L "${LOCAL_PORT}:127.0.0.1:3390" "aivanov@${DGX_HOST}"
|
||||
|
||||
echo "[2/3] Attente du tunnel ..."
|
||||
for _i in $(seq 1 40); do
|
||||
ss -tlnp 2>/dev/null | grep -q "127.0.0.1:${LOCAL_PORT} " && break
|
||||
sleep 0.25
|
||||
done
|
||||
|
||||
echo "[3/3] Connexion RDP (localhost:${LOCAL_PORT}) — presse-papier + dossier $HOME ..."
|
||||
xfreerdp /v:localhost:${LOCAL_PORT} /cert:ignore /clipboard /dynamic-resolution /drive:home,"$HOME" "$@" || true
|
||||
|
||||
echo "Session RDP terminee, fermeture du tunnel."
|
||||
59
deploy/windows-rdp-launcher/unblock_nomachine.ps1
Normal file
59
deploy/windows-rdp-launcher/unblock_nomachine.ps1
Normal file
@@ -0,0 +1,59 @@
|
||||
# Unblock NoMachine on Windows 11 — run as Administrator
|
||||
# Adds firewall rules for port 4000 (TCP+UDP) and verifies NoMachine service
|
||||
|
||||
Write-Host "=== Unblock NoMachine ===" -ForegroundColor Cyan
|
||||
|
||||
# 1. Add firewall inbound rules for NoMachine (port 4000 TCP + UDP)
|
||||
$ruleName = "NoMachine Server (Port 4000)"
|
||||
$existing = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
|
||||
if ($existing) {
|
||||
Write-Host "Firewall rule '$ruleName' already exists — enabling it" -ForegroundColor Yellow
|
||||
Enable-NetFirewallRule -DisplayName $ruleName
|
||||
} else {
|
||||
Write-Host "Creating firewall rule '$ruleName' for port 4000 TCP+UDP" -ForegroundColor Green
|
||||
New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -Protocol TCP -LocalPort 4000 -Action Allow -Profile Any -Enabled True -Description "Allow NoMachine remote desktop connections"
|
||||
New-NetFirewallRule -DisplayName "$ruleName (UDP)" -Direction Inbound -Protocol UDP -LocalPort 4000 -Action Allow -Profile Any -Enabled True -Description "Allow NoMachine UDP discovery"
|
||||
}
|
||||
|
||||
# 2. Check NoMachine service is running
|
||||
$svc = Get-Service -Name "nxsrv" -ErrorAction SilentlyContinue
|
||||
if (-not $svc) {
|
||||
$svc = Get-Service -Name "NoMachine Server" -ErrorAction SilentlyContinue
|
||||
if (-not $svc) {
|
||||
$svc = Get-Service | Where-Object { $_.DisplayName -like "*NoMachine*" -and $_.DisplayName -like "*Server*" } | Select-Object -First 1
|
||||
}
|
||||
}
|
||||
|
||||
if ($svc) {
|
||||
Write-Host "NoMachine service: $($svc.Name) — Status: $($svc.Status)" -ForegroundColor $(if ($svc.Status -eq 'Running') {'Green'} else {'Red'})
|
||||
if ($svc.Status -ne 'Running') {
|
||||
Write-Host "Starting NoMachine service..." -ForegroundColor Yellow
|
||||
Start-Service -Name $svc.Name -ErrorAction SilentlyContinue
|
||||
$svc = Get-Service -Name $svc.Name
|
||||
Write-Host "After start: $($svc.Status)" -ForegroundColor $(if ($svc.Status -eq 'Running') {'Green'} else {'Red'})
|
||||
}
|
||||
} else {
|
||||
Write-Host "WARNING: NoMachine server service not found!" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# 3. Verify port 4000 is listening
|
||||
Write-Host ""
|
||||
Write-Host "Checking port 4000..." -ForegroundColor Cyan
|
||||
$port4000 = Get-NetTCPConnection -LocalPort 4000 -ErrorAction SilentlyContinue
|
||||
if ($port4000) {
|
||||
Write-Host "Port 4000 is LISTENING on $($port4000.LocalAddress):$($port4000.LocalPort) — State: $($port4000.State)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "WARNING: Port 4000 NOT listening — NoMachine server may not be active" -ForegroundColor Red
|
||||
Write-Host "Try: restart NoMachine from the Start Menu or Services app" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 4. Show this machine's IP for remote connection
|
||||
$ip = (Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -notlike '*Loopback*' -and $_.IPAddress -notlike '127.*' -and $_.IPAddress -match '192\.168' } | Select-Object -First 1).IPAddress
|
||||
if ($ip) {
|
||||
Write-Host ""
|
||||
Write-Host "Laptop IP on LAN: $ip" -ForegroundColor Green
|
||||
Write-Host "From workstation: connect NoMachine to $ip" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== Done ===" -ForegroundColor Cyan
|
||||
Reference in New Issue
Block a user