Stable turnstone node identity for the console's cluster view

Default node_id is {hostname}_{random-per-boot}, so every boot
inserted a new services row and the console probed stale ones (409
node_id mismatch -> 'not found' node pages). Pin TURNSTONE_NODE_ID
(one upserted row) and TURNSTONE_ADVERTISE_URL to loopback — the
guest's slirp IPv6 lands in the SSRF guard's never-allowed lane.
Also drop the futile /etc/hostname baking (podman regenerates it at
boco build).
This commit is contained in:
marvin committed 2026-09-28 22:00:03 +02:00
1 parent 5560055c29
commit 653532a72a
2 files changed
+23 -1

No files matched your search

+5
View File
@@ -51,6 +51,11 @@ RUN groupadd -g ${GROUP_ID} marvin || true && \
RUN printf "marvin:100000:65536\n" > /etc/subuid && \ RUN printf "marvin:100000:65536\n" > /etc/subuid && \
printf "marvin:100000:65536\n" > /etc/subgid printf "marvin:100000:65536\n" > /etc/subgid
# NOTE: don't bake /etc/hostname or /etc/hosts here — podman regenerates
# both when boco creates the build container, so they never reach the
# qcow2. The entrypoint sets the hostname live; node identity comes from
# TURNSTONE_NODE_ID.
# SSH access for marvin (pubkey generated by scripts/build.sh) # SSH access for marvin (pubkey generated by scripts/build.sh)
COPY configs/ssh/authorized_keys /tmp/authorized_keys COPY configs/ssh/authorized_keys /tmp/authorized_keys
RUN install -o ${USER_ID} -g ${GROUP_ID} -m 700 -d /home/marvin/.ssh && \ RUN install -o ${USER_ID} -g ${GROUP_ID} -m 700 -d /home/marvin/.ssh && \
+18 -1
View File
@@ -6,6 +6,12 @@ set -euo pipefail
export HOME=/home/marvin export HOME=/home/marvin
# The boco kernel boots with hostname "(none)" (no systemd to read
# /etc/hostname) — set it live so turnstone node IDs and service URLs
# are sane (turnstone-vm_xxxx instead of (none)_xxxx). The Arch base
# has no `hostname` binary, so use the syscall via python.
python3 -c 'import socket; socket.sethostname("turnstone-vm")' || true
# sshd: host keys baked per-boot, ops channel on guest port 22 # sshd: host keys baked per-boot, ops channel on guest port 22
ssh-keygen -A ssh-keygen -A
mkdir -p /run/sshd mkdir -p /run/sshd
@@ -50,6 +56,17 @@ setpriv --reuid=marvin --regid=marvin --init-groups \
/usr/local/bin/turnstone-console --host 0.0.0.0 --port 8090 & /usr/local/bin/turnstone-console --host 0.0.0.0 --port 8090 &
echo "start-turnstone: console starting on :8090" echo "start-turnstone: console starting on :8090"
# NOTE: turnstone reads $HOME/.config/turnstone/config.toml as marvin # NOTE: turnstone reads $HOME/.config/turnstone/config.toml as marvin.
#
# Stable node identity: node_id defaults to {hostname}_{random-per-boot},
# so every boot inserts a NEW services row and the console probes stale
# ones (409 node_id mismatch → "unreachable"). Pin both:
# - TURNSTONE_NODE_ID: one registry row, upserted every boot
# - TURNSTONE_ADVERTISE_URL: loopback — the console's collector probes
# the registered URL, and the guest's slirp IPv6 (fec0::/fe80::)
# lands in the SSRF guard's never-allowed lane, which got the node
# refused outright.
export TURNSTONE_NODE_ID="${TURNSTONE_NODE_ID:-turnstone-vm-main}"
export TURNSTONE_ADVERTISE_URL="${TURNSTONE_ADVERTISE_URL:-http://127.0.0.1:8080}"
exec setpriv --reuid=marvin --regid=marvin --init-groups \ exec setpriv --reuid=marvin --regid=marvin --init-groups \
/usr/local/bin/turnstone-server --host 0.0.0.0 --port 8080 /usr/local/bin/turnstone-server --host 0.0.0.0 --port 8080