diff --git a/scripts/install-k8s.ps1 b/scripts/install-k8s.ps1 index da7809c..bbfd7cc 100644 --- a/scripts/install-k8s.ps1 +++ b/scripts/install-k8s.ps1 @@ -527,7 +527,9 @@ curl -fsSL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-contai | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \ | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list >/dev/null sudo apt-get update -qq -sudo apt-get install -y -q nvidia-container-toolkit +# needrestart on WSL Ubuntu would open a hidden prompt in this captured job and +# stall to the 180s timeout; DEBIAN_FRONTEND/NEEDRESTART_MODE keep apt non-interactive. +sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get install -y -q nvidia-container-toolkit sudo nvidia-ctk runtime configure --runtime=docker --set-as-default 2>/dev/null || true sudo nvidia-ctk runtime configure --runtime=containerd 2>/dev/null || true echo "NCT installed successfully." diff --git a/scripts/lib/setup-linux.sh b/scripts/lib/setup-linux.sh index 6af7618..47df149 100755 --- a/scripts/lib/setup-linux.sh +++ b/scripts/lib/setup-linux.sh @@ -6,7 +6,14 @@ # ── Package manager detection ──────────────────────────────────────────────── setup_pm() { - if has apt-get; then PM_UPDATE="sudo apt-get update -qq"; PM_INSTALL="sudo apt-get install -y -q -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold" + # apt note: Ubuntu 22.04+ ships needrestart, which hooks `apt-get install` and + # opens an interactive "restart services?" prompt that `-y` does NOT suppress. + # Run inside spin_cmd (stdout/stderr redirected, process backgrounded) that + # prompt is invisible and blocks reading the TTY → SIGTTIN → the install hangs + # forever ("still pulling conntrack"). DEBIAN_FRONTEND=noninteractive + + # NEEDRESTART_MODE=a make apt fully non-interactive; they are passed *through* + # `sudo env` because sudo resets the environment by default. + if has apt-get; then PM_UPDATE="sudo apt-get update -qq"; PM_INSTALL="sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a apt-get install -y -q -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold" elif has dnf; then PM_UPDATE="sudo dnf makecache -q"; PM_INSTALL="sudo dnf install -y -q" elif has yum; then PM_UPDATE="sudo yum makecache -q"; PM_INSTALL="sudo yum install -y -q" elif has zypper; then PM_UPDATE="sudo zypper refresh"; PM_INSTALL="sudo zypper install -y" @@ -77,7 +84,9 @@ install_docker_engine() { docker_script="$(mktemp)" retry 3 5 curl -fsSL $CURL_SECURE https://get.docker.com -o "$docker_script" chmod +x "$docker_script" - spin_cmd "Installing Docker…" sudo bash "$docker_script" + # Same needrestart guard as setup_pm: get.docker.com runs `apt-get install` + # internally, so under spin_cmd it can hit the same hidden prompt and hang. + spin_cmd "Installing Docker…" sudo env DEBIAN_FRONTEND=noninteractive NEEDRESTART_MODE=a bash "$docker_script" rm -f "$docker_script" fi # Enable for boot only (no --now): starting is handled below, where a start diff --git a/scripts/tests/setup-linux.bats b/scripts/tests/setup-linux.bats index d9e22c4..176ae7b 100644 --- a/scripts/tests/setup-linux.bats +++ b/scripts/tests/setup-linux.bats @@ -39,6 +39,16 @@ setup() { setup_pm [[ "$PM_INSTALL" == *"apt-get install"* ]] } +# Ubuntu 22.04+ needrestart opens a hidden "restart services?" prompt under +# spin_cmd that `-y` doesn't suppress → the install hangs. apt must be fully +# non-interactive, with the env passed through `sudo env` (sudo resets env). +@test "setup_pm: apt is non-interactive (needrestart/debconf guard)" { + PRESENT_CMDS="apt-get" + setup_pm + [[ "$PM_INSTALL" == *"DEBIAN_FRONTEND=noninteractive"* ]] + [[ "$PM_INSTALL" == *"NEEDRESTART_MODE=a"* ]] + [[ "$PM_INSTALL" == *"sudo env"* ]] +} @test "setup_pm: dnf detected" { PRESENT_CMDS="dnf" setup_pm @@ -119,6 +129,9 @@ setup() { run install_docker_engine run mock_calls [[ "$output" == *"get.docker.com"* ]] + # the convenience script runs apt-get internally → must be non-interactive too + [[ "$output" == *"DEBIAN_FRONTEND=noninteractive"* ]] + [[ "$output" == *"NEEDRESTART_MODE=a"* ]] } @test "install_docker_engine: docker already present -> no install" { PRESENT_CMDS="docker"; TEST_DISTRO=ubuntu