From 1a0d9e555ffd68d112e04798a23d73a69e88e454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kyle=20=F0=9F=90=86?= Date: Sun, 2 Aug 2026 10:10:05 -0400 Subject: [PATCH] Stop ssh consuming the test driver's stdin --- tests/adminaccess-bringup.nix | 7 ++++++- tests/mesh-admin-ssh.nix | 11 ++++++++--- tests/yubikey-ssh.nix | 7 ++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/tests/adminaccess-bringup.nix b/tests/adminaccess-bringup.nix index 03226d8..21a447f 100644 --- a/tests/adminaccess-bringup.nix +++ b/tests/adminaccess-bringup.nix @@ -51,8 +51,13 @@ in box.succeed("systemctl restart keep-node-admin-key-check.service") box.succeed("systemctl is-active --quiet keep-node-admin-key-check.service") + # -n matters: machine.succeed() runs its command through a shell on the VM's + # backdoor serial channel, and ssh without -n reads that channel's stdin. + # It then swallows the driver's own protocol stream, so the remote command + # completes while the driver waits forever for a completion marker that was + # already consumed. Timing-dependent, so it can pass locally and hang in CI. ssh = ( - "ssh -i /root/id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " + "ssh -n -i /root/id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " "-o BatchMode=yes -o ConnectTimeout=10" ) diff --git a/tests/mesh-admin-ssh.nix b/tests/mesh-admin-ssh.nix index a65e9d2..23b5bd2 100644 --- a/tests/mesh-admin-ssh.nix +++ b/tests/mesh-admin-ssh.nix @@ -97,8 +97,13 @@ in # The operator's private key on a 0600 path for the ssh client (the store copy is 0444). nodeA.succeed("install -m 0600 ${adminKeyFixture}/id /root/id") + # -n matters: machine.succeed() runs its command through a shell on the VM's + # backdoor serial channel, and ssh without -n reads that channel's stdin. + # It then swallows the driver's own protocol stream, so the remote command + # completes while the driver waits forever for a completion marker that was + # already consumed. Timing-dependent, so it can pass locally and hang in CI. ssh = ( - "ssh -i /root/id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " + "ssh -n -i /root/id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " "-o ConnectTimeout=10 -o BatchMode=yes" ) @@ -116,7 +121,7 @@ in # 2. The SAME SSH on nodeB's LAN/underlay address is REFUSED -- sshd is opened only on the mesh # interface, so the hostile LAN never reaches it. (ConnectTimeout bounds a dropped-packet hang.) nodeA.fail( - "ssh -i /root/id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " + "ssh -n -i /root/id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " "-o ConnectTimeout=5 -o BatchMode=yes keepadmin@${ipBUnderlay} true" ) @@ -124,7 +129,7 @@ in # throwaway keypair that is NOT in keepadmin's authorized_keys and confirm the login fails. nodeA.succeed('ssh-keygen -t ed25519 -N "" -f /root/wrong -q') nodeA.fail( - f"ssh -i /root/wrong -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " + f"ssh -n -i /root/wrong -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " f"-o ConnectTimeout=10 -o BatchMode=yes keepadmin@{meshB} true" ) diff --git a/tests/yubikey-ssh.nix b/tests/yubikey-ssh.nix index 3eb63fe..3d96fb8 100644 --- a/tests/yubikey-ssh.nix +++ b/tests/yubikey-ssh.nix @@ -78,8 +78,13 @@ in mixed.wait_for_unit("sshd.service") narrow.wait_for_unit("sshd.service") + # -n matters: machine.succeed() runs its command through a shell on the VM's + # backdoor serial channel, and ssh without -n reads that channel's stdin. + # It then swallows the driver's own protocol stream, so the remote command + # completes while the driver waits forever for a completion marker that was + # already consumed. Timing-dependent, so it can pass locally and hang in CI. ssh = ( - "ssh -i /root/id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " + "ssh -n -i /root/id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " "-o BatchMode=yes -o ConnectTimeout=10" ) for m in (strict, mixed, narrow):