diff --git a/applications/icons/windows.png b/applications/icons/windows.png new file mode 100644 index 00000000..ce7b366d Binary files /dev/null and b/applications/icons/windows.png differ diff --git a/applications/windows-vm.desktop b/applications/windows-vm.desktop new file mode 100644 index 00000000..0201ce93 --- /dev/null +++ b/applications/windows-vm.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=Windows VM +Comment=Start Windows VM via Docker and connect with RDP +Exec=uwsm app -- omarchy-launch-ms-windows +Icon=icons/windows.png +Terminal=false +Type=Application +Categories=System;Virtualization; diff --git a/bin/omarchy-launch-ms-windows b/bin/omarchy-launch-ms-windows new file mode 100755 index 00000000..534d715a --- /dev/null +++ b/bin/omarchy-launch-ms-windows @@ -0,0 +1,100 @@ +#!/bin/bash + +# Docker Compose Windows VM Launcher for Omarchy +# Starts Windows VM via Docker and connects with RDP +# When RDP closes, docker-compose will also stop + +set -e + +WINDOWS_STORAGE_DIR="$HOME/.windows" +RDP_COMMAND="rdesktop -g 1920x1200 -P -z -x l -r sound:off -u docker 127.0.0.1:3389 -p admin" +DOCKER_COMMAND="docker run -d --name windows -p 8006:8006 -p 3389:3389/tcp -p 3389:3389/udp --device=/dev/kvm --device=/dev/net/tun --cap-add NET_ADMIN -v ${WINDOWS_STORAGE_DIR}:/storage --stop-timeout 120 dockurr/windows" + +echo "Starting Windows VM..." + +# Create Windows storage directory if it doesn't exist +mkdir -p "$WINDOWS_STORAGE_DIR" + +# Check for required dependencies +for cmd in docker rdesktop nc curl; do + if ! command -v "$cmd" >/dev/null 2>&1; then + echo "Error: Required command '$cmd' not found." + echo "Please ensure Docker, rdesktop, and netcat are installed." + exit 1 + fi +done + +# Function to handle cleanup +cleanup() { + echo "Shutting down Windows VM..." + docker stop windows 2>/dev/null || true + docker rm windows 2>/dev/null || true + exit 0 +} + +# Set up signal handlers +trap cleanup SIGTERM SIGINT + +# Check if container already exists and remove it +if docker ps -a --format '{{.Names}}' | grep -q "^windows$"; then + echo "Removing existing Windows container..." + docker stop windows 2>/dev/null || true + docker rm windows 2>/dev/null || true +fi + +# Start docker container +echo "Starting Windows container..." +eval $DOCKER_COMMAND + +# Wait for container to be running +echo "Waiting for Windows container to start..." +while true; do + CONTAINER_STATUS=$(docker inspect --format='{{.State.Status}}' windows 2>/dev/null) + if [ "$CONTAINER_STATUS" = "running" ]; then + echo "Container is running!" + break + fi + echo " Container status: $CONTAINER_STATUS" + sleep 2 + + # Check if container is still running + if ! docker ps --format '{{.Names}}' | grep -q "^windows$"; then + echo "Docker container died unexpectedly" + exit 1 + fi +done + +# Check if web interface is responding (faster than waiting for RDP) +echo "Checking if Windows VM web interface is responding..." +while true; do + if curl -s --connect-timeout 5 http://127.0.0.1:8006 > /dev/null 2>&1; then + echo "Web interface is responding at http://127.0.0.1:8006" + break + fi + echo " Web interface not ready yet..." + sleep 3 +done + +# Now wait for RDP port specifically +echo "Waiting for RDP service to be ready..." +while ! nc -z 127.0.0.1 3389; do + echo " RDP port not ready yet..." + sleep 5 +done + +echo "RDP port is open, testing connection..." +# Quick RDP test with shorter timeout +timeout 5 rdesktop -g 320x240 -u docker 127.0.0.1:3389 -p admin 2>/dev/null +if [ $? -ne 0 ]; then + echo "RDP not fully ready yet, waiting 20 more seconds..." + sleep 20 +fi + +echo "Starting RDP connection..." +echo "When you close RDP, the Windows VM will automatically shut down." + +# Start RDP in foreground - when it exits, cleanup will run +$RDP_COMMAND + +# If RDP exits, cleanup +cleanup \ No newline at end of file