| author | |
| committer | |
| log | 9d0f2fc212858290e79710b44c0635a28dd92c2f |
| tree | 2c2b145caa5a6cbf2405de2e97ac95686adb6dff |
| parent | e9e46972fbabdee0eb39cbd86470a5b5f5f26910 |
| signature | Signed by PGP key B5690EEEBB952194 |
2 files changed, 30 insertions(+), 1 deletions(-)
packages/ssh/src/tunnel.test.ts+9| ... | ... | @@ -108,6 +108,9 @@ describe("ssh tunnel scripts", () => { |
| 108 | 108 | assert.include(script, "exec npx --yes 't3@latest' \"$@\""); |
| 109 | 109 | assert.include(script, "exec npm exec --yes 't3@latest' -- \"$@\""); |
| 110 | 110 | assert.include(script, "could not install 't3@latest'"); |
| 111 | assert.include(script, "require_installed_t3_cli npx --yes --package 't3@latest'"); | |
| 112 | assert.include(script, "require_installed_t3_cli npm exec --yes --package 't3@latest'"); | |
| 113 | assert.include(script, "npm produced no t3 executable"); | |
| 111 | 114 | assert.include(script, 'prepend_path_if_dir "$HOME/.local/bin"'); |
| 112 | 115 | assert.include(script, `T3_NODE_ENGINE_RANGE='${TEST_NODE_ENGINE_RANGE}'`); |
| 113 | 116 | assert.include(script, "remote_node_satisfies_engine()"); |
| ... | ... | @@ -140,6 +143,10 @@ describe("ssh tunnel scripts", () => { |
| 140 | 143 | |
| 141 | 144 | assert.include(script, "exec npx --yes 't3@nightly; touch /tmp/t3-owned' \"$@\""); |
| 142 | 145 | assert.include(script, "exec npm exec --yes 't3@nightly; touch /tmp/t3-owned' -- \"$@\""); |
| 146 | assert.include( | |
| 147 | script, | |
| 148 | "require_installed_t3_cli npx --yes --package 't3@nightly; touch /tmp/t3-owned'", | |
| 149 | ); | |
| 143 | 150 | assert.notInclude(script, "exec npx --yes t3@nightly; touch /tmp/t3-owned"); |
| 144 | 151 | }); |
| 145 | 152 | |
| ... | ... | @@ -185,6 +192,8 @@ describe("ssh tunnel scripts", () => { |
| 185 | 192 | assert.notInclude(buildRemoteLaunchScript(), "server-home"); |
| 186 | 193 | assert.include(buildRemoteLaunchScript(), "Remote T3 server did not become ready"); |
| 187 | 194 | assert.include(buildRemoteLaunchScript(), 'wait_ready "60000"'); |
| 195 | assert.include(buildRemoteLaunchScript(), 'if [ -s "$LOG_FILE" ]; then'); | |
| 196 | assert.include(buildRemoteLaunchScript(), "It wrote nothing to %s"); | |
| 188 | 197 | assert.include(buildRemoteLaunchScript({ packageSpec: "t3@nightly" }), "t3@nightly"); |
| 189 | 198 | assert.include( |
| 190 | 199 | buildRemotePairingScript(target), |
packages/ssh/src/tunnel.ts+21-1| ... | ... | @@ -426,10 +426,26 @@ fi |
| 426 | 426 | if command -v t3 >/dev/null 2>&1; then |
| 427 | 427 | exec t3 "$@" |
| 428 | 428 | fi |
| 429 | # npm extracts a package before it runs the native builds of its dependencies, | |
| 430 | # so a failed build (t3 depends on node-pty, which needs a C toolchain) leaves | |
| 431 | # the npx cache without a t3 executable. \`npx --yes\` then exits 0 without | |
| 432 | # running anything at all, which the caller only ever sees as a server that | |
| 433 | # never becomes ready. Resolve the CLI once up front so that install failure is | |
| 434 | # reported here, with npm's own output on stderr. | |
| 435 | require_installed_t3_cli() { | |
| 436 | T3_CLI_PATH="$("$@" -- sh -c 'command -v t3' || true)" | |
| 437 | if [ -n "$T3_CLI_PATH" ]; then | |
| 438 | return 0 | |
| 439 | fi | |
| 440 | printf 'Remote host installed %s but npm produced no t3 executable, which usually means a native dependency (node-pty) failed to build. Install a C toolchain on the remote host (Debian/Ubuntu: build-essential, Fedora/RHEL: gcc-c++ make, macOS: xcode-select --install) and try again.\\n' @@T3_PACKAGE_SPEC@@ >&2 | |
| 441 | return 1 | |
| 442 | } | |
| 429 | 443 | if command -v npx >/dev/null 2>&1; then |
| 444 | require_installed_t3_cli npx --yes --package @@T3_PACKAGE_SPEC@@ || exit 1 | |
| 430 | 445 | exec npx --yes @@T3_PACKAGE_SPEC@@ "$@" |
| 431 | 446 | fi |
| 432 | 447 | if command -v npm >/dev/null 2>&1; then |
| 448 | require_installed_t3_cli npm exec --yes --package @@T3_PACKAGE_SPEC@@ || exit 1 | |
| 433 | 449 | exec npm exec --yes @@T3_PACKAGE_SPEC@@ -- "$@" |
| 434 | 450 | fi |
| 435 | 451 | printf 'Remote host is missing the t3 CLI and could not install @@T3_PACKAGE_SPEC@@ because node/npm/npx are unavailable on PATH. Install Node or configure a supported version manager for non-interactive shells.\\n' >&2 |
| ... | ... | @@ -581,7 +597,11 @@ if [ -z "$REMOTE_PORT" ]; then |
| 581 | 597 | printf 'managed\\n' >"$MANAGED_FILE" |
| 582 | 598 | if ! wait_ready "@@T3_READY_TIMEOUT_MS@@"; then |
| 583 | 599 | printf 'Remote T3 server did not become ready on 127.0.0.1:%s.\\n' "$REMOTE_PORT" >&2 |
| 584 | tail -n 80 "$LOG_FILE" >&2 2>/dev/null || true | |
| 600 | if [ -s "$LOG_FILE" ]; then | |
| 601 | tail -n 80 "$LOG_FILE" >&2 2>/dev/null || true | |
| 602 | else | |
| 603 | printf 'It wrote nothing to %s, so it exited before producing any output.\\n' "$LOG_FILE" >&2 | |
| 604 | fi | |
| 585 | 605 | kill "$REMOTE_PID" 2>/dev/null || true |
| 586 | 606 | wait_for_pid_exit "$REMOTE_PID" |
| 587 | 607 | rm -f "$PID_FILE" "$PORT_FILE" "$MANAGED_FILE" |