diff --git a/vpn-node/Dockerfile b/vpn-node/Dockerfile index 462ff29..78c734e 100644 --- a/vpn-node/Dockerfile +++ b/vpn-node/Dockerfile @@ -29,24 +29,21 @@ RUN curl -fsSL https://apps.purevpn-tools.com/cross-platform/linux-cli/productio && bash /tmp/cli-install.sh \ && rm -f /tmp/cli-install.sh -# ── Inspect binary (visible in build log, remove once confirmed working) ────── -RUN echo "=== binary type ===" \ - && file /opt/purevpn-cli/bin/purevpn-cli /opt/purevpn-cli/purevpn-cli 2>/dev/null || true \ - && echo "=== bin/purevpn-cli header ===" \ - && head -3 /opt/purevpn-cli/bin/purevpn-cli 2>/dev/null || true - # ── Fake sudo wrapper ──────────────────────────────────────────────────────── -# The purevpn-cli pkg bootstrap uses argv[1] as the main module path when -# --install-missing-components is present (causing "Cannot find module '/--connect'"). -# Fix: move --install-missing-components to argv[1] so the bootstrap handles -# it as its own flag rather than trying to load '--connect' as a script. -# Clean env (env -i) prevents parent env vars from interfering with pkg startup. +# Unsets PKG_EXECPATH so the child's pkg bootstrap starts fresh instead of +# treating argv[1] as a Node.js module path. Depth guard stops recursion. COPY sudo-wrapper.sh /usr/local/bin/sudo RUN chmod +x /usr/local/bin/sudo # ── PATH ────────────────────────────────────────────────────────────────────── ENV PATH=/opt/purevpn-cli/bin:/opt/purevpn-cli:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +# ── Pre-install VPN components so runtime never needs sudo ─────────────────── +# Runs the binary as root during build; it calls our sudo wrapper (depth 1), +# which correctly invokes the child. Connection attempt will fail (no auth), +# but component files get written to stable paths and persist in the image. +RUN purevpn-cli --connect US --install-missing-components 2>&1 || true + # ── Location list ───────────────────────────────────────────────────────────── COPY servers.txt /etc/vpndock/servers.txt diff --git a/vpn-node/sudo-wrapper.sh b/vpn-node/sudo-wrapper.sh index fc395e3..9aab1e8 100644 --- a/vpn-node/sudo-wrapper.sh +++ b/vpn-node/sudo-wrapper.sh @@ -1,54 +1,20 @@ #!/bin/bash -# sudo-wrapper.sh -# -# purevpn-cli calls: sudo purevpn-cli --connect --install-missing-components -# -# Problem: PKG_EXECPATH inherited from the parent makes the pkg bootstrap treat -# argv[1] as a module path → "Cannot find module '/--connect'" (or '/--install...') -# regardless of arg order. -# -# Solution: -# 1. Strip --install-missing-components (not a commander.js flag; causes errors) -# 2. Unset PKG_EXECPATH only (-u) so the child's bootstrap starts fresh and -# loads the embedded main module. All other env vars (auth, session) are kept. -# 3. Depth guard prevents infinite recursion if the child also tries to sudo. +# Strip PKG_EXECPATH so the child's pkg bootstrap starts fresh. +# When PKG_EXECPATH is inherited, bootstrap treats argv[1] as a module path +# causing "Cannot find module '/--connect'" or '/--install-missing-components'. +# env -u unsets only PKG_EXECPATH; all auth/config/session vars are kept. +# Depth guard prevents infinite recursion. DEPTH="${PUREVPN_SUDO_DEPTH:-0}" if [[ "$DEPTH" -ge 2 ]]; then - echo "[sudo-wrapper] recursion depth $DEPTH — exiting 0" >&2 + echo "[sudo-wrapper] depth $DEPTH — exiting 0" >&2 exit 0 fi -NEXT_DEPTH=$(( DEPTH + 1 )) - -binary="" -has_install_flag=false -other_args=() +args=() for a in "$@"; do - case "$a" in - -E|-n|-H|--preserve-env|--non-interactive) continue ;; # sudo flags, skip - --install-missing-components) has_install_flag=true ;; # strip, don't pass - *) - if [[ -z "$binary" ]]; then - binary="$a" - else - other_args+=("$a") - fi - ;; - esac + case "$a" in -E|-n|-H) ;; *) args+=("$a") ;; esac done -if [[ -z "$binary" ]]; then - echo "[sudo-wrapper] no binary supplied" >&2 - exit 1 -fi - -if [[ "$has_install_flag" == "true" ]]; then - echo "[sudo-wrapper] stripped --install-missing-components, unset PKG_EXECPATH (depth=$NEXT_DEPTH): $binary ${other_args[*]}" >&2 - exec env -u PKG_EXECPATH PUREVPN_SUDO_DEPTH="$NEXT_DEPTH" \ - "$binary" "${other_args[@]}" -else - echo "[sudo-wrapper] passthrough (depth=$NEXT_DEPTH): $binary ${other_args[*]}" >&2 - exec env PUREVPN_SUDO_DEPTH="$NEXT_DEPTH" \ - "$binary" "${other_args[@]}" -fi +echo "[sudo-wrapper] depth=$(( DEPTH+1 )): ${args[*]}" >&2 +exec env -u PKG_EXECPATH PUREVPN_SUDO_DEPTH=$(( DEPTH+1 )) "${args[@]}"