Skip to content

Commit 1c15add

Browse files
authored
Merge pull request #6 from airplanes-live/feat/first-run-import-legacy
Wire airplanes-first-run into apl-feed import legacy-config
2 parents f82096d + 7c8c2ff commit 1c15add

5 files changed

Lines changed: 143 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ jobs:
102102
- name: Run updater rootfs smoke
103103
run: bash test/update-airplanes-rootfs-smoke.sh
104104

105+
- name: Run airplanes-first-run import call test
106+
run: bash test/test-first-run-import-call.sh
107+
105108
image-release-rootfs-smoke:
106109
name: image release rootfs smoke
107110
runs-on: ubuntu-24.04

skeleton/etc/systemd/system/airplanes-first-run.service

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ After=local-fs.target
55
Before=ssh.service
66

77
[Service]
8-
Type=simple
8+
# Type=oneshot so units with After=airplanes-first-run.service (readsb,
9+
# airplanes-feed, airplanes-mlat, dump978-fa, airplanes-978) wait for the
10+
# script to finish before they start. With the previous Type=simple they
11+
# could start as soon as ExecStart began, racing the script's apl-feed
12+
# import legacy-config call and sourcing a stale feed.env.
13+
Type=oneshot
14+
RemainAfterExit=yes
915
ExecStart=/usr/bin/airplanes-first-run
1016
WorkingDirectory=/run
1117
StandardOutput=inherit
1218
StandardError=inherit
13-
Restart=no
1419
User=root
1520

1621
[Install]

skeleton/usr/bin/airplanes-first-run

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,30 @@ if [ -f "/boot/airplanes-config.txt" ]; then
3636

3737
. /boot/airplanes-config.txt
3838

39+
# Translate the legacy boot config into the canonical /etc/airplanes/feed.env
40+
# schema that the feed daemons (airplanes-feed.sh, airplanes-mlat.sh) source
41+
# at startup. The new daemon wrappers do not read /boot/airplanes-config.txt
42+
# directly, so without this step legacy-webconfig saves would not propagate
43+
# to the running services on the next restart. Idempotent (no-op when the
44+
# legacy values already match feed.env).
45+
#
46+
# `--no-restart`: this service is Type=oneshot and the legacy services
47+
# (airplanes-feed, airplanes-mlat, dump978-fa, airplanes-978) declare
48+
# After=airplanes-first-run.service, so any systemctl restart issued
49+
# from inside the script would deadlock against the units waiting for
50+
# this script to finish. Restart ownership lives with systemd (boot
51+
# path) or with airplanes-webconfig/helpers/restart-services.sh (save
52+
# path) — both happen after this script exits.
53+
#
54+
# apl-feed is shipped by feed/update.sh and only present after the legacy
55+
# update bridge has fully run, so gate on command -v — pure-legacy boxes
56+
# (no bridge yet) skip silently.
57+
if command -v apl-feed >/dev/null 2>&1; then
58+
if ! apl-feed import legacy-config --no-restart /boot/airplanes-config.txt; then
59+
echo "airplanes-first-run: apl-feed import legacy-config failed; feed.env may be stale" >&2
60+
fi
61+
fi
62+
3963
SERVICES_978="dump978-fa airplanes-978 tar1090-978"
4064
if [ ${DUMP978} == "yes" ]; then
4165
services-handle enable "$SERVICES_978"

test/test-first-run-import-call.sh

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/usr/bin/env bash
2+
# Behavioral test for the apl-feed import wiring inside airplanes-first-run.
3+
# Static grep in update-airplanes-rootfs-smoke.sh covers "the line is in the
4+
# installed file"; this test covers "the script actually calls apl-feed
5+
# import legacy-config --no-restart with the right path when it runs".
6+
#
7+
# The first-run script hardcodes absolute paths (/boot, /usr/local/bin),
8+
# so we sed-rewrite a copy that uses a temporary fake root and stub every
9+
# binary the script touches through PATH. apl-feed is the assertion
10+
# target; systemctl / create-uuid.sh / fix-config.sh are silenced so the
11+
# rest of the script runs to completion without side effects.
12+
13+
set -euo pipefail
14+
15+
UPDATE_DIR="${AIRPLANES_UPDATE_DIR:-$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)}"
16+
SCRIPT_SRC="$UPDATE_DIR/skeleton/usr/bin/airplanes-first-run"
17+
18+
WORK="$(mktemp -d)"
19+
trap 'rm -rf "$WORK"' EXIT
20+
21+
ROOT="$WORK/root"
22+
STUB="$WORK/bin"
23+
APL_FEED_LOG="$WORK/apl-feed.argv"
24+
mkdir -p "$ROOT/boot" "$ROOT/usr/local/bin" "$STUB"
25+
26+
# Stub apl-feed: log one invocation per line as tab-joined argv tokens.
27+
# Tab is safe — none of the script's call sites pass an argv token that
28+
# contains a literal tab. The script's bash `if ! …; then warn` gate is
29+
# exercised on the success path here; the failure-warning path is
30+
# covered by the static smoke assertion in update-airplanes-rootfs-
31+
# smoke.sh.
32+
cat > "$STUB/apl-feed" <<APL_FEED
33+
#!/usr/bin/env bash
34+
printf '%s' "\$1" >> "$APL_FEED_LOG"
35+
shift
36+
for arg in "\$@"; do
37+
printf '\t%s' "\$arg" >> "$APL_FEED_LOG"
38+
done
39+
printf '\n' >> "$APL_FEED_LOG"
40+
exit 0
41+
APL_FEED
42+
chmod +x "$STUB/apl-feed"
43+
44+
# Silence everything else. systemctl gets called with is-enabled / is-active
45+
# / enable / disable / stop / start — all return success in this test.
46+
cat > "$STUB/systemctl" <<'SYSTEMCTL'
47+
#!/usr/bin/env bash
48+
exit 0
49+
SYSTEMCTL
50+
chmod +x "$STUB/systemctl"
51+
52+
cat > "$ROOT/usr/local/bin/create-uuid.sh" <<'CREATE_UUID'
53+
#!/usr/bin/env bash
54+
exit 0
55+
CREATE_UUID
56+
chmod +x "$ROOT/usr/local/bin/create-uuid.sh"
57+
cp "$ROOT/usr/local/bin/create-uuid.sh" "$ROOT/usr/local/bin/fix-config.sh"
58+
59+
# Seed a legacy-shaped boot config — the post-bridge migrate-config.sh form.
60+
cat > "$ROOT/boot/airplanes-config.txt" <<'BOOT_CONFIG'
61+
LATITUDE=52.5
62+
LONGITUDE=13.4
63+
ALTITUDE=120m
64+
USER=alice
65+
MLAT_USER="alice"
66+
MLAT_ENABLED=true
67+
MLAT_MARKER=yes
68+
MLAT_PRIVATE=false
69+
DUMP978=no
70+
DUMP1090=yes
71+
GRAPHS1090=yes
72+
BOOT_CONFIG
73+
74+
# Sed-rewrite absolute paths in a copy of the script. The substitutions
75+
# are narrow — only the paths this test cares about — so a future
76+
# unrelated absolute path in the script won't be silently rerouted.
77+
SCRIPT_COPY="$WORK/airplanes-first-run"
78+
sed \
79+
-e "s|/boot/airplanes-config\.txt|$ROOT/boot/airplanes-config.txt|g" \
80+
-e "s|/run/airplanes-config\.txt|$ROOT/run-airplanes-config.txt|g" \
81+
-e "s|/usr/local/bin/create-uuid\.sh|$ROOT/usr/local/bin/create-uuid.sh|g" \
82+
-e "s|/usr/local/bin/fix-config\.sh|$ROOT/usr/local/bin/fix-config.sh|g" \
83+
-e "s|/boot/firstboot\.sh|$ROOT/boot/firstboot.sh|g" \
84+
"$SCRIPT_SRC" > "$SCRIPT_COPY"
85+
chmod +x "$SCRIPT_COPY"
86+
87+
PATH="$STUB:$PATH" bash "$SCRIPT_COPY"
88+
89+
if [[ ! -s "$APL_FEED_LOG" ]]; then
90+
echo "FAIL: apl-feed was not invoked" >&2
91+
exit 1
92+
fi
93+
94+
expected_line=$'import\tlegacy-config\t--no-restart\t'"$ROOT/boot/airplanes-config.txt"
95+
if ! grep -Fxq -- "$expected_line" "$APL_FEED_LOG"; then
96+
echo "FAIL: apl-feed argv not as expected." >&2
97+
echo " expected: $expected_line" >&2
98+
echo " actual log:" >&2
99+
cat "$APL_FEED_LOG" >&2
100+
exit 1
101+
fi
102+
103+
echo "first-run import call test passed"

test/update-airplanes-rootfs-smoke.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,12 @@ assert_success_state() {
305305
local expected_package_manager="$1"
306306

307307
[[ -f "$ROOT_DIR/etc/systemd/system/airplanes-first-run.service" ]] || fail "missing first-run service"
308+
# The first-run script must translate /boot/airplanes-config.txt into
309+
# feed.env via apl-feed import legacy-config so legacy webconfig saves
310+
# propagate to the new feed daemons on next service restart.
311+
# --no-restart is required because this service is Type=oneshot and
312+
# the legacy units After= it.
313+
assert_contains "$ROOT_DIR/usr/bin/airplanes-first-run" 'apl-feed import legacy-config --no-restart /boot/airplanes-config.txt'
308314
[[ -f "$ROOT_DIR/usr/local/bin/create-uuid.sh" ]] || fail "missing create-uuid.sh"
309315
[[ -x "$ROOT_DIR/usr/bin/airplanes-feeder" ]] || fail "missing airplanes-feeder"
310316
[[ -x "$ROOT_DIR/usr/bin/airplanes-978" ]] || fail "missing airplanes-978"

0 commit comments

Comments
 (0)