Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions bin/winapps
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ AUTOPAUSE="off"
AUTOPAUSE_TIME="300"
DEBUG="true"
BOOT_TIMEOUT=120
PORT_TIMEOUT=5
HIDEF="on"
RDP_FLATPAK=0
RDP_FLAGS_WINDOWS=""
Expand Down Expand Up @@ -764,6 +765,32 @@ function waCheckPortOpen() {
timeout 10 nc -z "$RDP_IP" "$RDP_PORT" &>/dev/null || waThrowExit "$EC_BAD_PORT"
}

# Name: 'waSelectPodmanRoute'
# Role: Determine how FreeRDP can reach the RDP port of the Windows container.
# Note: Depending on the podman version and network backend, the RDP port is
# reachable at the container IP from within the rootless network namespace
# (netavark bridge networking), at localhost from within the rootless
# network namespace (slirp4netns port forwarding), or at localhost from
# the host network namespace (rootlessport/pasta port publishing).
# Probe these routes in order and use the first one that works, modifying
# 'RDP_IP' and 'FREERDP_COMMAND' accordingly.
function waSelectPodmanRoute() {
local CONTAINER_IP=""
CONTAINER_IP=$(podman inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$CONTAINER_NAME" 2>/dev/null)

if [ -n "$CONTAINER_IP" ] && timeout "$PORT_TIMEOUT" podman unshare --rootless-netns nc -z "$CONTAINER_IP" "$RDP_PORT" &>/dev/null; then
dprint "RDP PORT REACHABLE AT CONTAINER IP '${CONTAINER_IP}' WITHIN ROOTLESS NETWORK NAMESPACE."
RDP_IP="$CONTAINER_IP"
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
elif timeout "$PORT_TIMEOUT" podman unshare --rootless-netns nc -z "$RDP_IP" "$RDP_PORT" &>/dev/null; then
dprint "RDP PORT REACHABLE AT '${RDP_IP}' WITHIN ROOTLESS NETWORK NAMESPACE."
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
else
dprint "RDP PORT UNREACHABLE WITHIN ROOTLESS NETWORK NAMESPACE. CONNECTING FROM HOST NETWORK NAMESPACE."
waCheckPortOpen
fi
}

# Name: 'waRunCommand'
# Role: Run the requested WinApps command.
function waRunCommand() {
Expand Down Expand Up @@ -1009,11 +1036,6 @@ if [[ ! -z "$RDP_ASKPASS" ]]; then
unset RDP_PASSWORD_ARG
fi

# If using podman backend, modify the FreeRDP command to enter a new namespace.
if [ "$WAFLAVOR" = "podman" ]; then
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
fi

if [ "$WAFLAVOR" = "docker" ] || [ "$WAFLAVOR" = "podman" ]; then
RDP_IP="$DOCKER_IP"
waCheckContainerRunning
Expand All @@ -1026,7 +1048,11 @@ else
waThrowExit "$EC_INVALID_FLAVOR"
fi

waCheckPortOpen
if [ "$WAFLAVOR" = "podman" ]; then
waSelectPodmanRoute
else
waCheckPortOpen
fi
waTimeSync
waRunCommand "$@"

Expand Down
1 change: 1 addition & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ services:
# - 3389:3389/udp
cap_add:
- NET_ADMIN # Add network permission
- NET_RAW # Required by dnsmasq for dockur's NAT networking; without it the container falls back to user-mode (passt) networking, which breaks RDP port forwarding from the host
stop_grace_period: 120s # Wait 120 seconds before sending SIGTERM when attempting to shut down the Windows VM.
restart: on-failure # Restart the Windows VM if the exit code indicates an error.
volumes:
Expand Down
54 changes: 40 additions & 14 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,32 @@ function waCheckPortOpen() {
echo -e "${DONE_TEXT}Done!${CLEAR_TEXT}"
}

# Name: 'waSelectPodmanRoute'
# Role: Determine how FreeRDP can reach the RDP port of the Windows container.
# Note: Depending on the podman version and network backend, the RDP port is
# reachable at the container IP from within the rootless network namespace
# (netavark bridge networking), at localhost from within the rootless
# network namespace (slirp4netns port forwarding), or at localhost from
# the host network namespace (rootlessport/pasta port publishing).
# Probe these routes in order and use the first one that works, modifying
# 'RDP_IP' and 'FREERDP_COMMAND' accordingly.
function waSelectPodmanRoute() {
local CONTAINER_IP=""
CONTAINER_IP=$(podman inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "WinApps" 2>/dev/null)

if [ -n "$CONTAINER_IP" ] && timeout "$PORT_TIMEOUT" podman unshare --rootless-netns nc -z "$CONTAINER_IP" "$RDP_PORT" &>/dev/null; then
echo -e "RDP port reachable at container IP '${CONTAINER_IP}' within the rootless network namespace."
RDP_IP="$CONTAINER_IP"
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
elif timeout "$PORT_TIMEOUT" podman unshare --rootless-netns nc -z "$RDP_IP" "$RDP_PORT" &>/dev/null; then
echo -e "RDP port reachable at '${RDP_IP}' within the rootless network namespace."
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
else
echo -e "RDP port unreachable within the rootless network namespace. Connecting from the host network namespace."
waCheckPortOpen
fi
}

# Name: 'waCheckRDPAccess'
# Role: Tests if Windows is accessible via RDP.
function waCheckRDPAccess() {
Expand Down Expand Up @@ -1710,11 +1736,6 @@ function waInstall() {
RDP_IP="$DOCKER_IP"
fi

# If using podman backend, modify the FreeRDP command to enter a new namespace.
if [ "$WAFLAVOR" = "podman" ]; then
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
fi

if [ "$WAFLAVOR" = "docker" ] || [ "$WAFLAVOR" = "podman" ]; then
# Check if Windows is powered on.
waCheckContainerRunning
Expand Down Expand Up @@ -1742,8 +1763,13 @@ function waInstall() {
return "$EC_INVALID_FLAVOR"
fi

# Check if the RDP port on Windows is open.
waCheckPortOpen
# Determine how FreeRDP can reach the RDP port of the Windows container.
if [ "$WAFLAVOR" = "podman" ]; then
waSelectPodmanRoute
else
# Check if the RDP port on Windows is open.
waCheckPortOpen
fi

# Test RDP access to Windows.
waCheckRDPAccess
Expand Down Expand Up @@ -1907,11 +1933,6 @@ function waAddApps() {
RDP_IP="$DOCKER_IP"
fi

# If using podman backend, modify the FreeRDP command to enter a new namespace.
if [ "$WAFLAVOR" = "podman" ]; then
FREERDP_COMMAND="podman unshare --rootless-netns ${FREERDP_COMMAND}"
fi

if [ "$WAFLAVOR" = "docker" ] || [ "$WAFLAVOR" = "podman" ]; then
# Check if Windows is powered on.
waCheckContainerRunning
Expand Down Expand Up @@ -1939,8 +1960,13 @@ function waAddApps() {
return "$EC_INVALID_FLAVOR"
fi

# Check if the RDP port on Windows is open.
waCheckPortOpen
# Determine how FreeRDP can reach the RDP port of the Windows container.
if [ "$WAFLAVOR" = "podman" ]; then
waSelectPodmanRoute
else
# Check if the RDP port on Windows is open.
waCheckPortOpen
fi

# Test RDP access to Windows.
waCheckRDPAccess
Expand Down
Loading