setup-lan-access: Include ~/.ssh/config even if it appears after start
Same rule as c693aa3 (ssh-lan.conf). `Include ~/.ssh/config` went into
~/.ssh-local/config only if ~/.ssh/config was readable at container start.
A file that appeared later, e.g. on a host provisioned after its first
`docker compose up`, was ignored until a restart. Entries ADDED to a file that
already existed were never affected. Measured on tor-ms22 2026-10-19,
expectations written first:
- ssh reads Included files on every connection. A Host added after the config
was generated resolved with no rerun.
- the bind mount is live: on the Mac, a created file, an atomic replace
(write + mv) and an append each showed in the container within a second.
So this fixes only the file-appears-later case. The line is now always
written. A file that exists but is unreadable is still left out (ssh would
abort every connection), now with a warning on stderr.
Generated config compared with v1.12.1's: byte-identical when ~/.ssh/config
exists at start (DEVBOX_LAN_ACCESS=jump and auto, with and without
ssh-lan.conf), and stderr is the same too. When the file is absent, the only
difference is the added Include block.
scripts/smoke-test.sh: two new checks, run here the way exec_test runs them
(sh -c). Against v1.12.1, "Included even if created after start" FAILS and
"unreadable left out" PASSES. Against this script both pass, and so do the two
ssh-lan.conf checks.
CHANGELOG Unreleased also names pi-studio v0.10.4 (c83940d), because
check-doc-drift (and so lint on main) had gone red: upstream released 0.10.3
and 0.10.4 right after v1.12.1. 0.10.4 fixes a 0.10.2 Stop regression for
macOS uid -2. Not reachable in the image: 0.10.2's own readStopProcessTable
parsed this container's live ps output (9 rows, min uid 1000). Control: a
macOS-style -2 row throws. The lockfile packages are unchanged, and 0.10.4
loads into pi 1.3.0 with the same 4 studio_* tools, rc 0.
check-doc-drift rc 0, lint-shell rc 0, shellcheck warnings 0 before and after.
This commit is contained in:
@@ -11,6 +11,45 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **pi-studio `v0.10.2` → `v0.10.4`** (`c83940d`, `-studio` tags only). Two
|
||||||
|
upstream patch releases on 2026-10-19. 0.10.3: IPython prints a value once
|
||||||
|
(`Out[5]: …`), not twice, and after a Quick send the cursor returns to the
|
||||||
|
input box. 0.10.4: Stop works again on a Mac that has a process running as
|
||||||
|
`nobody`. That was a 0.10.2 regression: macOS lists that uid as `-2`, and the
|
||||||
|
0.10.2 parser refused to stop anything. **It does not affect the image**:
|
||||||
|
inside the container, `ps` shows only the container's own processes, and none
|
||||||
|
has a negative uid. Measured 2026-10-19 on tor-ms22. 0.10.2's own
|
||||||
|
`readStopProcessTable` parsed the live process table (9 rows, min uid 1000).
|
||||||
|
Control: a macOS-style `-2` row made it throw "Could not parse process
|
||||||
|
ownership data". Dependencies unchanged: `package-lock.json` packages are
|
||||||
|
identical to 0.10.1's, and `ws` is still the only runtime dependency. Loaded
|
||||||
|
into pi `1.3.0` with `pi --no-extensions -e <clone>/index.ts -p`, it registers
|
||||||
|
the same four `studio_*` tools, rc 0.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **`~/.ssh/config` is Included even if it appears after the container
|
||||||
|
started.** Same rule as the `ssh-lan.conf` fix in v1.12.1. `setup-lan-access.sh`
|
||||||
|
wrote `Include ~/.ssh/config` into `~/.ssh-local/config` only if
|
||||||
|
`~/.ssh/config` was readable at container start, so a file that appeared
|
||||||
|
later (a host provisioned after its first `docker compose up`) was ignored
|
||||||
|
until a restart. Entries *added* to a file that already existed were never
|
||||||
|
affected: ssh reads Included files on every connection, and the bind mount is
|
||||||
|
live. Measured 2026-10-19 on tor-ms22: on the Mac, a newly created file, an
|
||||||
|
atomic replace (write + `mv`, as editors do) and an append each showed up in
|
||||||
|
the container within a second. The line is now written whether or not the
|
||||||
|
file exists. A file that exists but is unreadable is still left out, with a
|
||||||
|
warning on stderr, because ssh would abort every connection. When the file
|
||||||
|
exists at start the generated config is byte-identical to v1.12.1's (checked
|
||||||
|
with and without `ssh-lan.conf`). When it is absent, the only difference is
|
||||||
|
the added Include block. `scripts/smoke-test.sh` gains two checks, Included
|
||||||
|
when created after start and left out when unreadable. Against the v1.12.1
|
||||||
|
script the first fails and the second passes; against this one both pass.
|
||||||
|
|
||||||
## v1.12.1 — 2026-10-19
|
## v1.12.1 — 2026-10-19
|
||||||
|
|
||||||
Patch release. Headline: **`ssh-lan.conf` is Included even if it is created
|
Patch release. Headline: **`ssh-lan.conf` is Included even if it is created
|
||||||
|
|||||||
@@ -196,8 +196,17 @@ EOF
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Same rule as ssh-lan.conf above: Included even when ~/.ssh/config does not
|
||||||
|
# exist yet, so a file that appears after container start (a host provisioned
|
||||||
|
# after its first `docker compose up`) is read on the next ssh. Entries added to
|
||||||
|
# a file that already existed were always picked up: ssh reads Includes on every
|
||||||
|
# connection and the mount is live. Through v1.12.1 the line was written only if
|
||||||
|
# the file was readable at start. Only a file that EXISTS but cannot be read is
|
||||||
|
# left out, because ssh would then abort every connection, git included.
|
||||||
INCLUDE_BLOCK=""
|
INCLUDE_BLOCK=""
|
||||||
if [ -r "${HOME}/.ssh/config" ]; then
|
if [ -e "${HOME}/.ssh/config" ] && [ ! -r "${HOME}/.ssh/config" ]; then
|
||||||
|
echo "setup-lan-access: ${HOME}/.ssh/config exists but is not readable, so it is not Included (ssh would refuse every connection). Fix its permissions, then rerun this script or restart the container." >&2
|
||||||
|
else
|
||||||
INCLUDE_BLOCK=$(cat <<'EOF'
|
INCLUDE_BLOCK=$(cat <<'EOF'
|
||||||
|
|
||||||
# Your own target hosts. Scope reset to match-all so this Include applies to
|
# Your own target hosts. Scope reset to match-all so this Include applies to
|
||||||
|
|||||||
@@ -719,6 +719,28 @@ exec_test "unreadable ssh-lan.conf left out (ssh would abort)" '
|
|||||||
! grep -q "ssh-lan.conf$" $T/.ssh-local/config &&
|
! grep -q "ssh-lan.conf$" $T/.ssh-local/config &&
|
||||||
HOME=$T ssh -F $T/.ssh-local/config -G lanpeer >/dev/null 2>&1
|
HOME=$T ssh -F $T/.ssh-local/config -G lanpeer >/dev/null 2>&1
|
||||||
r=$?; rm -rf $T; exit $r'
|
r=$?; rm -rf $T; exit $r'
|
||||||
|
# ~/.ssh/config gets the same rule as ssh-lan.conf above: Included whether or
|
||||||
|
# not it exists at container start, except when it exists but cannot be read.
|
||||||
|
# Entries added to a file that already existed at start were always picked up
|
||||||
|
# (ssh reads Includes on every connection, and the mount is live). This covers
|
||||||
|
# only a file that appears after start, e.g. a host provisioned after its first
|
||||||
|
# `docker compose up`. Through v1.12.1 that file was ignored until a restart.
|
||||||
|
exec_test "~/.ssh/config Included even if created after start" '
|
||||||
|
T=$(mktemp -d) &&
|
||||||
|
HOME=$T DEVBOX_LAN_ACCESS=jump bash /usr/local/lib/pi-devbox/setup-lan-access.sh >/dev/null 2>&1 &&
|
||||||
|
grep -qx "Include ~/.ssh/config" $T/.ssh-local/config &&
|
||||||
|
HOME=$T ssh -F $T/.ssh-local/config -G ownpeer 2>/dev/null | grep -qx "hostname ownpeer" &&
|
||||||
|
mkdir -p $T/.ssh && printf "Host ownpeer\n HostName 10.8.8.8\n" > $T/.ssh/config &&
|
||||||
|
chmod 600 $T/.ssh/config &&
|
||||||
|
HOME=$T ssh -F $T/.ssh-local/config -G ownpeer 2>/dev/null | grep -qx "hostname 10.8.8.8"
|
||||||
|
r=$?; rm -rf $T; exit $r'
|
||||||
|
exec_test "unreadable ~/.ssh/config left out (ssh would abort)" '
|
||||||
|
T=$(mktemp -d) && mkdir -p $T/.ssh && printf "Host x\n" > $T/.ssh/config &&
|
||||||
|
chmod 000 $T/.ssh/config &&
|
||||||
|
HOME=$T DEVBOX_LAN_ACCESS=jump bash /usr/local/lib/pi-devbox/setup-lan-access.sh >/dev/null 2>&1 &&
|
||||||
|
! grep -qx "Include ~/.ssh/config" $T/.ssh-local/config &&
|
||||||
|
HOME=$T ssh -F $T/.ssh-local/config -G ownpeer >/dev/null 2>&1
|
||||||
|
r=$?; chmod 600 $T/.ssh/config; rm -rf $T; exit $r'
|
||||||
# The vendored mempalace snapshot is refreshed MANUALLY per release (see
|
# The vendored mempalace snapshot is refreshed MANUALLY per release (see
|
||||||
# rootfs/usr/local/share/pi-devbox/skills/VENDORED.md). Through v1.8.4 it also
|
# rootfs/usr/local/share/pi-devbox/skills/VENDORED.md). Through v1.8.4 it also
|
||||||
# silently SHADOWED the live skillset copy, so staleness was invisible — and the
|
# silently SHADOWED the live skillset copy, so staleness was invisible — and the
|
||||||
|
|||||||
Reference in New Issue
Block a user