Loading docker-compose.yml +1 −1 Original line number Diff line number Diff line Loading @@ -12,4 +12,4 @@ services: - 3389:3389/tcp - 3389:3389/udp stop_grace_period: 2m restart: unless-stopped restart: on-failure readme.md +3 −3 Original line number Diff line number Diff line Loading @@ -39,13 +39,13 @@ services: - 3389:3389/tcp - 3389:3389/udp stop_grace_period: 2m restart: unless-stopped restart: on-failure ``` Via `docker run` ```bash docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/windows docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 dockurr/windows ``` ## FAQ Loading Loading @@ -152,7 +152,7 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/w VERSION: "https://example.com/win.iso" ``` Alternatively, you can also place a file called `custom.iso` in an empty `/storage` folder to skip the download. Alternatively, you can also rename a local file to `custom.iso` and place it in an empty `/storage` folder to skip the download. * ### How do I pass-through a disk? Loading src/entry.sh +12 −4 Original line number Diff line number Diff line Loading @@ -2,23 +2,31 @@ set -Eeuo pipefail APP="Windows" export BOOT_MODE=windows BOOT_MODE="windows" SUPPORT="https://github.com/dockur/windows" cd /run . reset.sh # Initialize system . install.sh # Get bootdisk . install.sh # Run installation . disk.sh # Initialize disks . display.sh # Initialize graphics . network.sh # Initialize network . boot.sh # Configure boot . proc.sh # Initialize processor . power.sh # Configure shutdown . config.sh # Configure arguments trap - ERR info "Booting $APP using $VERS..." [[ "$DEBUG" == [Yy1]* ]] && echo "Arguments: $ARGS" && echo [[ "$DEBUG" == [Yy1]* ]] && set -x exec qemu-system-x86_64 ${ARGS:+ $ARGS} { qemu-system-x86_64 ${ARGS:+ $ARGS} >"$QEMU_OUT" 2>"$QEMU_LOG"; rc=$?; } || : (( rc != 0 )) && error "$(<"$QEMU_LOG")" && exit 15 terminal tail -fn +0 "$QEMU_LOG" 2>/dev/null & cat "$QEMU_TERM" 2>/dev/null & wait $! || : sleep 1 && finish 0 src/install.sh +2 −15 Original line number Diff line number Diff line Loading @@ -31,14 +31,6 @@ set -Eeuo pipefail [[ "${VERSION,,}" == "win16" ]] && VERSION="win2016-eval" [[ "${VERSION,,}" == "win2016" ]] && VERSION="win2016-eval" if [[ "${VERSION,,}" == "tiny10" ]]; then VERSION="https://archive.org/download/tiny-10-23-h2/tiny10%20x64%2023h2.iso" fi if [[ "${VERSION,,}" == "tiny11" ]]; then VERSION="https://archive.org/download/tiny-11-core-x-64-beta-1/tiny11%20core%20x64%20beta%201.iso" fi CUSTOM="custom.iso" [ ! -f "$STORAGE/$CUSTOM" ] && CUSTOM="Custom.iso" Loading Loading @@ -91,14 +83,9 @@ else fi html "$MSG" TMP="$STORAGE/tmp" if [ -z "$MANUAL" ]; then MANUAL="N" [[ "${BASE,,}" == "tiny10"* ]] && MANUAL="Y" fi TMP="$STORAGE/tmp" [ -z "$MANUAL" ] && MANUAL="N" if [ -f "$STORAGE/$BASE" ]; then Loading src/power.sh 0 → 100644 +151 −0 Original line number Diff line number Diff line #!/usr/bin/env bash set -Eeuo pipefail # Configure QEMU for graceful shutdown QEMU_TERM="" QEMU_PORT=7100 QEMU_TIMEOUT=110 QEMU_PID="/run/shm/qemu.pid" QEMU_LOG="/run/shm/qemu.log" QEMU_OUT="/run/shm/qemu.out" QEMU_END="/run/shm/qemu.end" rm -f /run/shm/qemu.* touch "$QEMU_LOG" _trap() { func="$1" ; shift for sig ; do trap "$func $sig" "$sig" done } finish() { local pid local reason=$1 if [ -f "$QEMU_PID" ]; then pid=$(<"$QEMU_PID") echo && error "Forcefully terminating Windows, reason: $reason..." { kill -15 "$pid" || true; } 2>/dev/null while isAlive "$pid"; do sleep 1 # Workaround for zombie pid [ ! -f "$QEMU_PID" ] && break done fi pid="/var/run/tpm.pid" [ -f "$pid" ] && pKill "$(<"$pid")" closeNetwork sleep 1 echo && echo "❯ Shutdown completed!" exit "$reason" } terminal() { local dev="" if [ -f "$QEMU_OUT" ]; then local msg msg=$(<"$QEMU_OUT") if [ -n "$msg" ]; then if [[ "${msg,,}" != "char"* || "$msg" != *"serial0)" ]]; then echo "$msg" fi dev="${msg#*/dev/p}" dev="/dev/p${dev%% *}" fi fi if [ ! -c "$dev" ]; then dev=$(echo 'info chardev' | nc -q 1 -w 1 localhost "$QEMU_PORT" | tr -d '\000') dev="${dev#*serial0}" dev="${dev#*pty:}" dev="${dev%%$'\n'*}" dev="${dev%%$'\r'*}" fi if [ ! -c "$dev" ]; then error "Device '$dev' not found!" finish 34 && return 34 fi QEMU_TERM="$dev" return 0 } _graceful_shutdown() { local code=$? set +e if [ -f "$QEMU_END" ]; then echo && info "Received $1 while already shutting down..." return fi touch "$QEMU_END" echo && info "Received $1, sending ACPI shutdown signal..." if [ ! -f "$QEMU_PID" ]; then echo && error "QEMU PID file does not exist?" finish "$code" && return "$code" fi local pid="" pid=$(<"$QEMU_PID") if ! isAlive "$pid"; then echo && error "QEMU process does not exist?" finish "$code" && return "$code" fi # Send ACPI shutdown signal echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_PORT}" > /dev/null local cnt=0 while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do sleep 1 cnt=$((cnt+1)) ! isAlive "$pid" && break # Workaround for zombie pid [ ! -f "$QEMU_PID" ] && break info "Waiting for Windows to shutdown... ($cnt/$QEMU_TIMEOUT)" # Send ACPI shutdown signal echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_PORT}" > /dev/null done if [ "$cnt" -ge "$QEMU_TIMEOUT" ]; then echo && error "Shutdown timeout reached, aborting..." fi finish "$code" && return "$code" } SERIAL="pty" MONITOR="telnet:localhost:$QEMU_PORT,server,nowait,nodelay" MONITOR="$MONITOR -daemonize -D $QEMU_LOG -pidfile $QEMU_PID" _trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT return 0 Loading
docker-compose.yml +1 −1 Original line number Diff line number Diff line Loading @@ -12,4 +12,4 @@ services: - 3389:3389/tcp - 3389:3389/udp stop_grace_period: 2m restart: unless-stopped restart: on-failure
readme.md +3 −3 Original line number Diff line number Diff line Loading @@ -39,13 +39,13 @@ services: - 3389:3389/tcp - 3389:3389/udp stop_grace_period: 2m restart: unless-stopped restart: on-failure ``` Via `docker run` ```bash docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/windows docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 dockurr/windows ``` ## FAQ Loading Loading @@ -152,7 +152,7 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN dockurr/w VERSION: "https://example.com/win.iso" ``` Alternatively, you can also place a file called `custom.iso` in an empty `/storage` folder to skip the download. Alternatively, you can also rename a local file to `custom.iso` and place it in an empty `/storage` folder to skip the download. * ### How do I pass-through a disk? Loading
src/entry.sh +12 −4 Original line number Diff line number Diff line Loading @@ -2,23 +2,31 @@ set -Eeuo pipefail APP="Windows" export BOOT_MODE=windows BOOT_MODE="windows" SUPPORT="https://github.com/dockur/windows" cd /run . reset.sh # Initialize system . install.sh # Get bootdisk . install.sh # Run installation . disk.sh # Initialize disks . display.sh # Initialize graphics . network.sh # Initialize network . boot.sh # Configure boot . proc.sh # Initialize processor . power.sh # Configure shutdown . config.sh # Configure arguments trap - ERR info "Booting $APP using $VERS..." [[ "$DEBUG" == [Yy1]* ]] && echo "Arguments: $ARGS" && echo [[ "$DEBUG" == [Yy1]* ]] && set -x exec qemu-system-x86_64 ${ARGS:+ $ARGS} { qemu-system-x86_64 ${ARGS:+ $ARGS} >"$QEMU_OUT" 2>"$QEMU_LOG"; rc=$?; } || : (( rc != 0 )) && error "$(<"$QEMU_LOG")" && exit 15 terminal tail -fn +0 "$QEMU_LOG" 2>/dev/null & cat "$QEMU_TERM" 2>/dev/null & wait $! || : sleep 1 && finish 0
src/install.sh +2 −15 Original line number Diff line number Diff line Loading @@ -31,14 +31,6 @@ set -Eeuo pipefail [[ "${VERSION,,}" == "win16" ]] && VERSION="win2016-eval" [[ "${VERSION,,}" == "win2016" ]] && VERSION="win2016-eval" if [[ "${VERSION,,}" == "tiny10" ]]; then VERSION="https://archive.org/download/tiny-10-23-h2/tiny10%20x64%2023h2.iso" fi if [[ "${VERSION,,}" == "tiny11" ]]; then VERSION="https://archive.org/download/tiny-11-core-x-64-beta-1/tiny11%20core%20x64%20beta%201.iso" fi CUSTOM="custom.iso" [ ! -f "$STORAGE/$CUSTOM" ] && CUSTOM="Custom.iso" Loading Loading @@ -91,14 +83,9 @@ else fi html "$MSG" TMP="$STORAGE/tmp" if [ -z "$MANUAL" ]; then MANUAL="N" [[ "${BASE,,}" == "tiny10"* ]] && MANUAL="Y" fi TMP="$STORAGE/tmp" [ -z "$MANUAL" ] && MANUAL="N" if [ -f "$STORAGE/$BASE" ]; then Loading
src/power.sh 0 → 100644 +151 −0 Original line number Diff line number Diff line #!/usr/bin/env bash set -Eeuo pipefail # Configure QEMU for graceful shutdown QEMU_TERM="" QEMU_PORT=7100 QEMU_TIMEOUT=110 QEMU_PID="/run/shm/qemu.pid" QEMU_LOG="/run/shm/qemu.log" QEMU_OUT="/run/shm/qemu.out" QEMU_END="/run/shm/qemu.end" rm -f /run/shm/qemu.* touch "$QEMU_LOG" _trap() { func="$1" ; shift for sig ; do trap "$func $sig" "$sig" done } finish() { local pid local reason=$1 if [ -f "$QEMU_PID" ]; then pid=$(<"$QEMU_PID") echo && error "Forcefully terminating Windows, reason: $reason..." { kill -15 "$pid" || true; } 2>/dev/null while isAlive "$pid"; do sleep 1 # Workaround for zombie pid [ ! -f "$QEMU_PID" ] && break done fi pid="/var/run/tpm.pid" [ -f "$pid" ] && pKill "$(<"$pid")" closeNetwork sleep 1 echo && echo "❯ Shutdown completed!" exit "$reason" } terminal() { local dev="" if [ -f "$QEMU_OUT" ]; then local msg msg=$(<"$QEMU_OUT") if [ -n "$msg" ]; then if [[ "${msg,,}" != "char"* || "$msg" != *"serial0)" ]]; then echo "$msg" fi dev="${msg#*/dev/p}" dev="/dev/p${dev%% *}" fi fi if [ ! -c "$dev" ]; then dev=$(echo 'info chardev' | nc -q 1 -w 1 localhost "$QEMU_PORT" | tr -d '\000') dev="${dev#*serial0}" dev="${dev#*pty:}" dev="${dev%%$'\n'*}" dev="${dev%%$'\r'*}" fi if [ ! -c "$dev" ]; then error "Device '$dev' not found!" finish 34 && return 34 fi QEMU_TERM="$dev" return 0 } _graceful_shutdown() { local code=$? set +e if [ -f "$QEMU_END" ]; then echo && info "Received $1 while already shutting down..." return fi touch "$QEMU_END" echo && info "Received $1, sending ACPI shutdown signal..." if [ ! -f "$QEMU_PID" ]; then echo && error "QEMU PID file does not exist?" finish "$code" && return "$code" fi local pid="" pid=$(<"$QEMU_PID") if ! isAlive "$pid"; then echo && error "QEMU process does not exist?" finish "$code" && return "$code" fi # Send ACPI shutdown signal echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_PORT}" > /dev/null local cnt=0 while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do sleep 1 cnt=$((cnt+1)) ! isAlive "$pid" && break # Workaround for zombie pid [ ! -f "$QEMU_PID" ] && break info "Waiting for Windows to shutdown... ($cnt/$QEMU_TIMEOUT)" # Send ACPI shutdown signal echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_PORT}" > /dev/null done if [ "$cnt" -ge "$QEMU_TIMEOUT" ]; then echo && error "Shutdown timeout reached, aborting..." fi finish "$code" && return "$code" } SERIAL="pty" MONITOR="telnet:localhost:$QEMU_PORT,server,nowait,nodelay" MONITOR="$MONITOR -daemonize -D $QEMU_LOG -pidfile $QEMU_PID" _trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT return 0