Files
computer-playbook/scripts/github/guide/host_deploy.sh
kevinveenbirkenbach ca01669fc5 fix(guide): give the host-mode replay the resolver compose mode already has
utils/roles/guide.py picks "compose" if the role ships a stack and "host"
otherwise. The compose branch runs make compose-up, which starts the coredns
service from compose.yml, so the replay resolves the deployment's own names.
The host branch runs this script, a bare container on the default bridge with
no resolver anywhere.

That only started to matter with 4986e80dd4, which threaded DOMAIN into the
README replay so it deploys under INFINITO_DOMAIN instead of inheriting
infinito.localhost. Before it, sys-svc-nss resolved *.localhost through
nss-myhostname and no DNS server was needed; after it, a stackless role asks
for infinito.test and gets nothing.

web-svc-html shows the whole chain in run 33923190220. Its guide replay logs
"Verify 'html.infinito.test' is served after the reload" with [Errno -2] Name
or service not known, sys-ctl-hlth-webserver probes every NGINX domain and
exits 1 through script.py's `return 1 if errors else 0`, systemd refuses to
start hlth-webserver, and sys-service-terminator fails the play after 25
attempts. The same run's Fider replay, a compose-mode role, answers the
identical task with real HTTP headers.

Rather than rebuild the resolver by hand, the script now brings up the very
service the compose branch uses and reads the network back off the container,
so subnet, gateway, MTU, image, Corefile and command all stay in compose.yml.
The Corefile is rendered through CoreDNSCorefileRenderer so the script does
not depend on an earlier phase having produced it. coredns declares no
depends_on, so the infinito service stays down and INFINITO_IP4 is free for
the guide container; the run's own log shows the CI phase removing
infinito-nexus-core_default seventeen seconds before the replay starts.

-v /srv is the second failure in the same class. svc-storage-nfs-server dies
with "mount.nfs4 ... reason given by server: No such file or directory" on a
host reporting Storage Driver: overlay2, because name_to_handle_at answers
EOPNOTSUPP there and the server builds no export root. A real volume under
the export path takes it off the overlay.
2026-09-08 18:46:50 +02:00

78 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Install a host role inside its pkgmgr distro container against localhost.
# Env: GUIDE_ROLE, GUIDE_RUNTIME_IMAGE, INFINITO_DISTRO,
# INFINITO_RESCUE_DIAGNOSTICS_BASE.
set -euo pipefail
: "${INFINITO_RESCUE_DIAGNOSTICS_BASE:?}"
: "${INFINITO_DISTRO:?}"
# Exception: strip the clone/cd lines because the checkout is already
# mounted; running them would clone a fresh tree and lose the CI changes.
awk '/^### Production$/{p=1} p && /^```bash$/{c=1; next} c && /^```$/{exit} c' \
"roles/${GUIDE_ROLE}/README.md" |
grep -vE '^git clone |^cd core$' >/tmp/host-deploy.sh
test -s /tmp/host-deploy.sh
# shellcheck source=/dev/null
source scripts/meta/env/load.sh
sed -i "s#<your-ssh-public-key>#ssh-ed25519 AAAA_TEST_DUMMY_KEY github-ci-dummy@infinito#" /tmp/host-deploy.sh
sed -i "s#<your-domain>#${INFINITO_DOMAIN}#" /tmp/host-deploy.sh
docker pull "${GUIDE_RUNTIME_IMAGE}"
# Exception: the pkgmgr base image ships no init of its own.
PREP="$(docker run -d --entrypoint sleep "${GUIDE_RUNTIME_IMAGE}" infinity)"
docker exec "${PREP}" sh -c '
set -e
if command -v apt-get >/dev/null 2>&1; then
APT_TIMEOUT=10m
APT_OPTS="-o Acquire::Retries=5 -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30"
timeout -k 30 "$APT_TIMEOUT" apt-get $APT_OPTS update
DEBIAN_FRONTEND=noninteractive timeout -k 30 "$APT_TIMEOUT" apt-get $APT_OPTS install -y systemd systemd-sysv libnss-myhostname
elif command -v dnf >/dev/null 2>&1; then
dnf install -y systemd
elif command -v pacman >/dev/null 2>&1; then
pacman -Sy --noconfirm --needed archlinux-keyring
pacman -Syu --noconfirm --needed systemd
rm -rf /var/cache/pacman/pkg/*
fi
grep -q myhostname /etc/nsswitch.conf || sed -i "s/^hosts:.*/& myhostname/" /etc/nsswitch.conf
[ -e /sbin/init ] || ln -sf /lib/systemd/systemd /sbin/init
'
BOOT_IMAGE="guide-boot:${GUIDE_ROLE}"
docker commit "${PREP}" "${BOOT_IMAGE}" >/dev/null
docker rm -f "${PREP}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- cleanup of a possibly already-removed container
python3 -c 'from pathlib import Path; from cli.administration.deploy.development.coredns import CoreDNSCorefileRenderer; CoreDNSCorefileRenderer(repo_root=Path(".")).render(show_preview=False)'
docker compose up -d coredns
GUIDE_NET="$(docker inspect -f '{{range $k, $v := .NetworkSettings.Networks}}{{$k}}{{end}}' "${INFINITO_RUNNER_PREFIX}-coredns")"
CID="$(docker run -d --privileged --cgroupns=host \
--network "${GUIDE_NET}" --ip "${INFINITO_IP4}" --dns "${INFINITO_DNS_IP}" \
-v /sys/fs/cgroup:/sys/fs/cgroup:rw \
--tmpfs /run --tmpfs /run/lock \
-v /srv \
-v "${PWD}:${PWD}" \
--entrypoint /sbin/init \
"${BOOT_IMAGE}")"
# shellcheck disable=SC2154
trap 'rc=$?; if [ "${rc}" -ne 0 ]; then _rescue="${INFINITO_RESCUE_DIAGNOSTICS_BASE}/${INFINITO_DISTRO}/${GUIDE_ROLE}"; INFINITO_RESCUE_DIAGNOSTICS_DIR="${_rescue}" python3 utils/diagnostics/container.py "${GUIDE_ROLE}" "guide host boot failure" || true; bash scripts/tests/deploy/utils/rescue_index.sh "${_rescue}"; fi; docker rm -f -v "${CID}" >/dev/null 2>&1 || true; docker compose down >/dev/null 2>&1 || true; docker rmi -f "${BOOT_IMAGE}" >/dev/null 2>&1 || true' EXIT # nocheck: shell-or-true -- best-effort diagnostics + teardown in the EXIT trap
for _ in $(seq 1 40); do
state="$(docker exec "${CID}" systemctl is-system-running 2>/dev/null || true)"
case "${state}" in running | degraded) break ;; esac
sleep 3
done
state="$(docker exec "${CID}" systemctl is-system-running 2>/dev/null || true)"
case "${state}" in
running | degraded) ;;
*)
echo "systemd never reached a running state (last: ${state:-unknown})" >&2
docker exec "${CID}" systemctl --no-pager status 2>/dev/null | head -n 20 >&2 || true # nocheck: shell-or-true -- diagnostics dump on the failure path
exit 1
;;
esac
docker exec "${CID}" bash -lc 'systemctl unmask systemd-logind && systemctl start systemd-logind && loginctl enable-linger root && systemctl start user@0.service'
docker exec -i -w "${PWD}" "${CID}" bash -s </tmp/host-deploy.sh