Skip to content

Commit 1cd86ad

Browse files
authored
chore(migrations): drop migrate_altitude_to_bare_metres (#104)
The defensive converter in _config_sync_build_payload already runs every outbound ALTITUDE value through altitude_to_bare_metres on the wire, so suffixed disk values still emit a clean JSON number to the website regardless of the on-disk shape. The only population that would have benefited from the on-disk rewrite is a single dev-channel feeder, which does not justify the added migration-chain complexity. Removes the migrator, its bats coverage, and the configure-validators.sh source that update.sh only carried for the migrator's sake. Addresses #101
1 parent 8078a67 commit 1cd86ad

3 files changed

Lines changed: 0 additions & 252 deletions

File tree

scripts/lib/update-migrations.sh

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -371,85 +371,6 @@ migrate_geo_to_configured_flag() {
371371
mv -f "$tmp" "$feed_env"
372372
}
373373

374-
# Rewrite the ALTITUDE value to bare metres. Idempotent — bare values
375-
# round-trip unchanged. The website's config-sync wire format expects
376-
# `alt.value` as a JSON number in metres; the pre-migration disk format
377-
# carried a unit-suffixed string (`120m`, `400ft`). Writing back the
378-
# already-validated suffix-stripped value lets every outbound payload
379-
# emit a clean number and means a server-side echo (`alt.value: 120` →
380-
# disk `ALTITUDE=120`) is a no-op-equality round-trip.
381-
#
382-
# Sidecar metadata (feed.meta.json) is intentionally NOT bumped. The
383-
# representation flips; the operator's last-edit semantics do not. A
384-
# website edit that arrives shortly after this migration runs must still
385-
# win over the pre-migration feeder stamp, which means edited_at must
386-
# stay where it was. Asymmetric with migrate_user_to_mlat_split, which
387-
# represents a real schema change.
388-
#
389-
# Unparseable values (regex shape fails OR post-conversion range gate
390-
# fails) are left untouched on disk and surface as a stderr warning.
391-
# The next operator-triggered apply will surface them via the validator
392-
# — the migrator's job is to flip canonical-but-suffixed values, not to
393-
# repair broken ones.
394-
migrate_altitude_to_bare_metres() {
395-
local feed_env="$1"
396-
[[ -f "$feed_env" ]] || return 0
397-
398-
# No ALTITUDE key on disk — nothing to migrate.
399-
if ! grep -qE '^[[:space:]]*ALTITUDE=' "$feed_env"; then
400-
return 0
401-
fi
402-
403-
local current converted rc=0
404-
current="$(_extract_env_value "$feed_env" ALTITUDE)"
405-
406-
# Empty value (present-but-empty tombstone, e.g. a recent
407-
# alt.value:null round-trip) — leave untouched.
408-
if [[ -z "$current" ]]; then
409-
return 0
410-
fi
411-
412-
converted="$(altitude_to_bare_metres "$current")" || rc=$?
413-
if (( rc != 0 )); then
414-
echo "migrate_altitude_to_bare_metres: leaving ALTITUDE=\"$current\" untouched (does not parse as a metric/imperial altitude in [-1000, 10000] metres)" >&2
415-
return 0
416-
fi
417-
418-
# Already bare — strict no-op (no write, no log spam). Without this
419-
# short-circuit, the second-and-later migration runs would still
420-
# rewrite the file (with identical contents) and bump mtime.
421-
if [[ "$converted" == "$current" ]]; then
422-
return 0
423-
fi
424-
425-
local tmp escaped
426-
tmp="$(mktemp "${feed_env}.XXXXXX")" || return 0
427-
# Escape exactly the way _apl_feed_apply_write does so a value the
428-
# apply layer would re-emit verbatim survives this rewrite identically.
429-
escaped="${converted//\\/\\\\}"
430-
escaped="${escaped//\$/\\\$}"
431-
escaped="${escaped//\`/\\\`}"
432-
escaped="${escaped//\"/\\\"}"
433-
# Replace the existing ALTITUDE line. `awk` so the replacement is
434-
# exact-key-prefix (not a partial match like `ALTITUDE_FOO`) and
435-
# respects per-line shape. First match wins (canonical case); later
436-
# duplicate ALTITUDE lines (operator hand-edit oddity) are passed
437-
# through so subsequent _apl_feed_apply_read can dedup them on its
438-
# next write cycle.
439-
awk -v new_line="ALTITUDE=\"$escaped\"" '
440-
BEGIN { replaced = 0 }
441-
/^[[:space:]]*ALTITUDE=/ && !replaced {
442-
print new_line
443-
replaced = 1
444-
next
445-
}
446-
{ print }
447-
' "$feed_env" > "$tmp" || { rm -f "$tmp"; return 0; }
448-
chmod --reference="$feed_env" "$tmp" 2>/dev/null || true
449-
chown --reference="$feed_env" "$tmp" 2>/dev/null || true
450-
mv -f "$tmp" "$feed_env"
451-
}
452-
453374
# Seed /etc/airplanes/feed.meta.json from the current feed.env on installs
454375
# that don't have it yet. The sidecar tracks per-write (edited_at, edited_by)
455376
# tuples for the LWW remote-config sync; without this seed, existing
@@ -537,10 +458,6 @@ run_config_file_migrations() {
537458
migrate_user_to_mlat_split "$feed_env"
538459
migrate_privacy_to_mlat_private "$feed_env"
539460
migrate_geo_to_configured_flag "$feed_env"
540-
# Runs BEFORE migrate_seed_feed_meta_json so the seeded sidecar can
541-
# reflect bare-metres state if it's being created in this same update
542-
# cycle.
543-
migrate_altitude_to_bare_metres "$feed_env"
544461
migrate_seed_feed_meta_json "$feed_env" "$(dirname "$feed_env")/feed.meta.json"
545462
if [[ -n "$_feed_lock_fd" ]]; then
546463
eval "exec ${_feed_lock_fd}>&-"

test/test_migrations.bats

Lines changed: 0 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ setup() {
1515
# shellcheck source=/dev/null
1616
source "$COMMON_LIB"
1717
# shellcheck source=/dev/null
18-
source "$REPO_ROOT/scripts/lib/configure-validators.sh"
19-
# shellcheck source=/dev/null
2018
source "$LIB"
2119
# shellcheck source=/dev/null
2220
source "$REPO_ROOT/scripts/lib/legacy-mlat-translation.sh"
@@ -723,165 +721,6 @@ EOF
723721
grep -qx 'GEO_CONFIGURED=true' "$FEED_ENV"
724722
}
725723

726-
# ---------------------------------------------------------------------------
727-
# migrate_altitude_to_bare_metres
728-
# ---------------------------------------------------------------------------
729-
730-
@test "migrate_altitude_to_bare_metres: ALTITUDE=120m → ALTITUDE=120 (strip suffix)" {
731-
cat > "$FEED_ENV" <<'EOF'
732-
LATITUDE="52.5"
733-
LONGITUDE="13.4"
734-
ALTITUDE="120m"
735-
GEO_CONFIGURED=true
736-
EOF
737-
migrate_altitude_to_bare_metres "$FEED_ENV"
738-
739-
grep -qx 'ALTITUDE="120"' "$FEED_ENV"
740-
grep -qx 'LATITUDE="52.5"' "$FEED_ENV"
741-
grep -qx 'LONGITUDE="13.4"' "$FEED_ENV"
742-
grep -qx 'GEO_CONFIGURED=true' "$FEED_ENV"
743-
}
744-
745-
@test "migrate_altitude_to_bare_metres: ALTITUDE=400ft → ALTITUDE=121.92" {
746-
cat > "$FEED_ENV" <<'EOF'
747-
ALTITUDE="400ft"
748-
EOF
749-
migrate_altitude_to_bare_metres "$FEED_ENV"
750-
751-
grep -qx 'ALTITUDE="121.92"' "$FEED_ENV"
752-
}
753-
754-
@test "migrate_altitude_to_bare_metres: bare ALTITUDE=42.5 is unchanged (idempotent)" {
755-
cat > "$FEED_ENV" <<'EOF'
756-
ALTITUDE="42.5"
757-
EOF
758-
local before
759-
before="$(cat "$FEED_ENV")"
760-
migrate_altitude_to_bare_metres "$FEED_ENV"
761-
[ "$(cat "$FEED_ENV")" = "$before" ]
762-
}
763-
764-
@test "migrate_altitude_to_bare_metres: empty ALTITUDE is unchanged" {
765-
cat > "$FEED_ENV" <<'EOF'
766-
ALTITUDE=""
767-
EOF
768-
local before
769-
before="$(cat "$FEED_ENV")"
770-
migrate_altitude_to_bare_metres "$FEED_ENV"
771-
[ "$(cat "$FEED_ENV")" = "$before" ]
772-
}
773-
774-
@test "migrate_altitude_to_bare_metres: missing ALTITUDE key is a no-op" {
775-
cat > "$FEED_ENV" <<'EOF'
776-
LATITUDE="52.5"
777-
LONGITUDE="13.4"
778-
EOF
779-
local before
780-
before="$(cat "$FEED_ENV")"
781-
migrate_altitude_to_bare_metres "$FEED_ENV"
782-
[ "$(cat "$FEED_ENV")" = "$before" ]
783-
}
784-
785-
@test "migrate_altitude_to_bare_metres: garbage value is preserved with a warning" {
786-
cat > "$FEED_ENV" <<'EOF'
787-
ALTITUDE="not-a-number"
788-
LATITUDE="52.5"
789-
EOF
790-
local before
791-
before="$(cat "$FEED_ENV")"
792-
run migrate_altitude_to_bare_metres "$FEED_ENV"
793-
[ "$status" -eq 0 ]
794-
[ "$(cat "$FEED_ENV")" = "$before" ]
795-
[[ "$output" == *"leaving ALTITUDE=\"not-a-number\" untouched"* ]]
796-
}
797-
798-
@test "migrate_altitude_to_bare_metres: out-of-range value is preserved with a warning" {
799-
# 33000ft is ~10058m, just above the 10000m upper bound.
800-
cat > "$FEED_ENV" <<'EOF'
801-
ALTITUDE="33000ft"
802-
EOF
803-
local before
804-
before="$(cat "$FEED_ENV")"
805-
run migrate_altitude_to_bare_metres "$FEED_ENV"
806-
[ "$status" -eq 0 ]
807-
[ "$(cat "$FEED_ENV")" = "$before" ]
808-
[[ "$output" == *"33000ft"* ]]
809-
}
810-
811-
@test "migrate_altitude_to_bare_metres: second run on bare-metres state is a strict no-op" {
812-
cat > "$FEED_ENV" <<'EOF'
813-
ALTITUDE="400ft"
814-
EOF
815-
migrate_altitude_to_bare_metres "$FEED_ENV"
816-
grep -qx 'ALTITUDE="121.92"' "$FEED_ENV"
817-
local after_first
818-
after_first="$(cat "$FEED_ENV")"
819-
820-
migrate_altitude_to_bare_metres "$FEED_ENV"
821-
[ "$(cat "$FEED_ENV")" = "$after_first" ]
822-
}
823-
824-
@test "migrate_altitude_to_bare_metres: does NOT bump feed.meta.json metadata" {
825-
# The migration is a representation flip, not a semantic edit. The
826-
# sidecar's edited_at must stay where it was so a freshly-stamped
827-
# website edit still wins over the pre-migration feeder tuple.
828-
cat > "$FEED_ENV" <<'EOF'
829-
ALTITUDE="120m"
830-
EOF
831-
META="$TMP/feed.meta.json"
832-
cat > "$META" <<'EOF'
833-
{"schema_version":1,"fields":{"ALTITUDE":{"edited_at":"2024-06-01T00:00:00Z","edited_by":"legacy"}}}
834-
EOF
835-
local meta_before
836-
meta_before="$(cat "$META")"
837-
838-
migrate_altitude_to_bare_metres "$FEED_ENV"
839-
840-
grep -qx 'ALTITUDE="120"' "$FEED_ENV"
841-
[ "$(cat "$META")" = "$meta_before" ]
842-
}
843-
844-
@test "migrate_altitude_to_bare_metres: preserves all non-altitude keys verbatim" {
845-
cat > "$FEED_ENV" <<'EOF'
846-
INPUT="127.0.0.1:30005"
847-
MLAT_USER="alice"
848-
MLAT_ENABLED=true
849-
MLAT_PRIVATE=false
850-
LATITUDE="52.5"
851-
LONGITUDE="13.4"
852-
ALTITUDE="400ft"
853-
GEO_CONFIGURED=true
854-
NET_OPTIONS="--net-heartbeat 60"
855-
GAIN=auto
856-
EOF
857-
migrate_altitude_to_bare_metres "$FEED_ENV"
858-
859-
grep -qx 'INPUT="127.0.0.1:30005"' "$FEED_ENV"
860-
grep -qx 'MLAT_USER="alice"' "$FEED_ENV"
861-
grep -qx 'MLAT_ENABLED=true' "$FEED_ENV"
862-
grep -qx 'MLAT_PRIVATE=false' "$FEED_ENV"
863-
grep -qx 'LATITUDE="52.5"' "$FEED_ENV"
864-
grep -qx 'LONGITUDE="13.4"' "$FEED_ENV"
865-
grep -qx 'ALTITUDE="121.92"' "$FEED_ENV"
866-
grep -qx 'GEO_CONFIGURED=true' "$FEED_ENV"
867-
grep -qx 'NET_OPTIONS="--net-heartbeat 60"' "$FEED_ENV"
868-
grep -qx 'GAIN=auto' "$FEED_ENV"
869-
}
870-
871-
@test "run_config_file_migrations: altitude bare-metres flip runs in the chain" {
872-
cat > "$FEED_ENV" <<'EOF'
873-
USER="alice"
874-
LATITUDE="52.5"
875-
LONGITUDE="13.4"
876-
ALTITUDE="400ft"
877-
EOF
878-
run_config_file_migrations "$FEED_ENV"
879-
880-
grep -qx 'MLAT_USER="alice"' "$FEED_ENV"
881-
grep -qx 'GEO_CONFIGURED=true' "$FEED_ENV"
882-
grep -qx 'ALTITUDE="121.92"' "$FEED_ENV"
883-
}
884-
885724
# ---------------------------------------------------------------------------
886725
# migrate_seed_feed_meta_json (DEV-380)
887726
# ---------------------------------------------------------------------------
@@ -989,7 +828,6 @@ EOF
989828
run bash -c "
990829
set -e
991830
source '$COMMON_LIB'
992-
source '$REPO_ROOT/scripts/lib/configure-validators.sh'
993831
source '$LIB'
994832
migrate_seed_feed_meta_json '$FEED_ENV' '$META'
995833
"

update.sh

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,6 @@ if [[ "$IMAGE_SERVICE_LAYOUT" == "1" ]]; then
336336
SYSTEMD_DIR="$(airplanes_path /etc/systemd/system)"
337337
fi
338338

339-
# Validator + canonicalizer helpers — needed by migrate_altitude_to_bare_metres
340-
# (calls altitude_to_bare_metres) and reused by any future config-rewriting
341-
# migrator. Sourced before update-migrations.sh so the migrator's function
342-
# definitions can rely on the helpers at chain-execution time.
343-
# shellcheck source=scripts/lib/configure-validators.sh
344-
source "$GIT/scripts/lib/configure-validators.sh"
345-
346339
# Migration helpers: legacy retirements, env-file rewrites, manifest-based
347340
# pruning, finalize symlinks. See scripts/lib/update-migrations.sh for the
348341
# function definitions and the migration ordering contract.

0 commit comments

Comments
 (0)