From 75b99f7fd4ff6fdea17e3fc2c86fd35d2349c3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alonso=20David=20De=20Le=C3=B3n=20Rodarte?= <153755137+DataDave-Dev@users.noreply.github.com> Date: Sat, 15 Aug 2026 07:42:43 -0600 Subject: [PATCH] Fix Windows VM launch never opening an RDP window (#6893) * Wait for the current Windows boot before connecting RDP docker logs retains output across stop/start, so grepping the whole log matched "Windows started successfully" from an earlier boot and returned immediately, firing xfreerdp3 while the guest was still booting. Anchor the scan to the container's current StartedAt, and run it even when the container was already running, since the image restarts the guest in place on reboot. * Skip Kerberos when connecting to the Windows VM FreeRDP 3 attempts Kerberos before NTLM for NLA, and Arch's stock /etc/krb5.conf declares default_realm = ATHENA.MIT.EDU, so every launch tries to reach MIT's KDC. Off the network each attempt blocks ~23s and xfreerdp3 sits in CLOSE-WAIT without drawing a window, which reads as the VM failing to start. Point FreeRDP at a realm-less krb5 config so it falls through to NTLM, which is what the local Windows account uses anyway. * Re-read the container start time on every readiness poll A failed docker inspect left STARTED_AT empty, and docker logs drops the --since filter when it is, putting the scan back on the whole retained log and its stale success line. Sampling per poll also keeps the window on the current boot if the container restarts mid-wait. Co-Authored-By: Claude Opus 5 (1M context) --------- Co-authored-by: David Heinemeier Hansson Co-authored-by: Claude Opus 5 (1M context) --- bin/omarchy-windows-vm | 51 +++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/bin/omarchy-windows-vm b/bin/omarchy-windows-vm index a9fa8d2f..09a53702 100755 --- a/bin/omarchy-windows-vm +++ b/bin/omarchy-windows-vm @@ -297,21 +297,34 @@ launch_windows() { omarchy-notification-send -u critical "Windows VM" "Failed to start Windows VM" exit 1 fi - - echo "Waiting for Windows VM to start..." - WAIT_COUNT=0 - until docker logs omarchy-windows 2>&1 | grep -qi "windows started successfully"; do - sleep 2 - WAIT_COUNT=$((WAIT_COUNT + 1)) - if (( WAIT_COUNT > 60 )); then # 2 minutes timeout - echo "" - echo "❌ Timeout: Windows VM failed to start within 2 minutes" - echo " Check logs: docker logs omarchy-windows" - exit 1 - fi - done fi + # docker logs keeps output across stop/start and is only cleared when the + # container is removed, so an unanchored grep matches "started successfully" + # from an earlier boot and returns immediately. Anchor the scan to the current + # container start, and run it even when the container was already up: the + # image restarts the guest in place whenever Windows reboots. + windows_started() { + local started_at + started_at=$(docker inspect --format='{{.State.StartedAt}}' omarchy-windows 2>/dev/null) + # An empty --since would drop the filter and match a stale boot again + [[ -n $started_at ]] || return 1 + docker logs --since "$started_at" omarchy-windows 2>&1 | grep -qi "windows started successfully" + } + + echo "Waiting for Windows VM to start..." + WAIT_COUNT=0 + until windows_started; do + sleep 2 + WAIT_COUNT=$((WAIT_COUNT + 1)) + if (( WAIT_COUNT > 60 )); then # 2 minutes timeout + echo "" + echo "❌ Timeout: Windows VM failed to start within 2 minutes" + echo " Check logs: docker logs omarchy-windows" + exit 1 + fi + done + # Build the connection info if [[ $KEEP_ALIVE = "true" ]]; then LIFECYCLE="VM will keep running after RDP closes @@ -329,6 +342,18 @@ To stop: omarchy-windows-vm stop" "" \ "$LIFECYCLE" + # FreeRDP 3 tries Kerberos before NTLM for NLA, and krb5 ships /etc/krb5.conf + # as the MIT sample with default_realm = ATHENA.MIT.EDU. Every connect then + # goes looking for MIT's KDC: with internet up it fails fast, but off the + # network each attempt blocks ~23s and no RDP window is ever drawn. The VM + # authenticates against a local Windows account, so point FreeRDP at a + # realm-less config and let it fall straight through to NTLM. + KRB5_CONF="$(dirname "$COMPOSE_FILE")/krb5.conf" + if [[ ! -f $KRB5_CONF ]]; then + printf '[libdefaults]\n dns_lookup_kdc = false\n dns_lookup_realm = false\n' >"$KRB5_CONF" + fi + export KRB5_CONFIG="$KRB5_CONF" + # Detect display scale from Hyprland HYPR_SCALE=$(hyprctl monitors -j | jq -r '.[] | select (.focused == true) | .scale') SCALE_PERCENT=$(echo "$HYPR_SCALE" | awk '{print int($1 * 100)}')