diff --git a/.github/workflows/package-openwrt.yml b/.github/workflows/package-openwrt.yml index d8d79fe0..dfd80513 100644 --- a/.github/workflows/package-openwrt.yml +++ b/.github/workflows/package-openwrt.yml @@ -841,6 +841,17 @@ jobs: fi done + # Maintainer scripts. adbdump prints each registered script as a + # ":" key under scripts:. An upgrade runs only pre-upgrade and + # post-upgrade, so a package missing either restarts nothing. + for s in post-install pre-upgrade post-upgrade pre-deinstall; do + if grep -qE "^[[:space:]]*${s}:" "$DUMP"; then + echo " PASS script: $s" + else + echo " FAIL script: missing $s"; fail=1 + fi + done + if [ "$fail" -ne 0 ]; then echo "apk structural verification FAILED" exit 1 diff --git a/packaging/openwrt-apk/README.md b/packaging/openwrt-apk/README.md index d7eec73e..26383661 100644 --- a/packaging/openwrt-apk/README.md +++ b/packaging/openwrt-apk/README.md @@ -94,6 +94,21 @@ key; a single `--allow-untrusted` package install does not. If we ever publish a apk feed, add ECDSA (prime256v1) signing via `apk mkpkg --sign` and distribute the public key to `/etc/apk/keys/`. +## Upgrading + +Upgrade with the same command, pointed at the new package: + +```bash +ssh root@192.168.1.1 apk add --allow-untrusted /tmp/fips__.apk +``` + +The new package's upgrade scripts stop `fips` and `fips-gateway` before the +files are replaced, then start `fips` again and start `fips-gateway` only if it +was enabled, so the upgrade keeps the gateway's enabled state. apk runs +the incoming package's upgrade scripts, not the installed one's, so this holds +from the first upgrade onto a package that carries them, whatever version is +installed. + `/etc/fips/fips.yaml` is marked as a config file (via `/lib/apk/packages/fips.conffiles`), so apk preserves local edits across upgrades, and `/lib/upgrade/keep.d/fips` preserves `/etc/fips/` across `sysupgrade` — the diff --git a/packaging/openwrt-apk/build-apk.sh b/packaging/openwrt-apk/build-apk.sh index cfe18a60..89063850 100755 --- a/packaging/openwrt-apk/build-apk.sh +++ b/packaging/openwrt-apk/build-apk.sh @@ -228,16 +228,53 @@ cat > "$STAGE_DIR/lib/apk/packages/${PKG_NAME}.conffiles" <<'EOF' EOF # ---- maintainer scripts ---- -# Map our opkg maintainer scripts onto apk's lifecycle phases: -# opkg postinst -> apk post-install (enable + start the daemon) -# opkg prerm -> apk pre-deinstall (stop + disable services) - # Both bodies come from packaging/openwrt-ipk/scripts/, the same files the # .ipk ships, so the two packagers cannot drift apart and testing/openwrt/ -# exercises what both install. apk runs post-install only on a fresh install, -# so the postinst's upgrade branch is unreachable here. +# exercises what both install. apk-tools v3 runs a different script on each +# path, and only ever the incoming package's: +# +# fresh install post-install = postinst as shipped (enable + start fips; +# the gateway stays off) +# upgrade pre-upgrade = prerm, told it is an opkg-style upgrade; +# runs before any file is replaced +# post-upgrade = postinst with PKG_UPGRADE=1; runs after +# removal pre-deinstall = prerm as shipped (stop + disable both) +# +# On an upgrade apk passes " " and a PATH-only +# environment, which is not the contract the bodies were written for: prerm +# would read the new version as "not an upgrade" and disable the gateway, and +# postinst would see no PKG_UPGRADE. The upgrade pair therefore gets one header +# line that restores opkg's contract, "upgrade " for prerm and +# PKG_UPGRADE=1 for postinst (OpenWrt's own package-pack.mk builds its +# post-upgrade scripts the same way). +# +# Registering post-upgrade alone would not restart anything: procd treats a +# start of a running instance with an unchanged command line as a no-op, so +# the old binaries would keep running until a reboot. pre-upgrade stops both +# services first, which also means a failed extraction leaves them stopped, +# as an opkg upgrade already does. + +wrap_script() { + # wrap_script + # Writes to with inserted after its #! line. + local header="$1" src="$2" dst="$3" + if [ "$(head -n 1 "$src")" != "#!/bin/sh" ]; then + echo "Error: $src does not start with #!/bin/sh; cannot wrap it." >&2 + exit 1 + fi + { + echo "#!/bin/sh" + echo "$header" + tail -n +2 "$src" + } > "$dst" + chmod 0755 "$dst" +} + install -m 0755 "$SCRIPTS_SRC/postinst" "$SCRIPTS_DIR/post-install" install -m 0755 "$SCRIPTS_SRC/prerm" "$SCRIPTS_DIR/pre-deinstall" +# shellcheck disable=SC2016 # $1 is expanded by the script at run time +wrap_script 'set -- upgrade "$1"' "$SCRIPTS_SRC/prerm" "$SCRIPTS_DIR/pre-upgrade" +wrap_script 'export PKG_UPGRADE=1' "$SCRIPTS_SRC/postinst" "$SCRIPTS_DIR/post-upgrade" # --------------------------------------------------------------------------- # 3. Assemble the .apk via apk mkpkg @@ -268,6 +305,8 @@ $FAKEROOT "$APK_BIN" mkpkg \ --info "maintainer:FIPS Network" \ --info "depends:$DEPENDS" \ --script "post-install:$SCRIPTS_DIR/post-install" \ + --script "pre-upgrade:$SCRIPTS_DIR/pre-upgrade" \ + --script "post-upgrade:$SCRIPTS_DIR/post-upgrade" \ --script "pre-deinstall:$SCRIPTS_DIR/pre-deinstall" \ --files "$STAGE_DIR" \ --output "$DIST_DIR/$PKG_FILENAME" diff --git a/packaging/openwrt-ipk/scripts/postinst b/packaging/openwrt-ipk/scripts/postinst index 3e505e6d..18361729 100755 --- a/packaging/openwrt-ipk/scripts/postinst +++ b/packaging/openwrt-ipk/scripts/postinst @@ -2,7 +2,8 @@ # Maintainer script run after the FIPS package is unpacked. # # Installed as the .ipk CONTROL/postinst and registered as the .apk -# post-install script, so one body serves both packagers. +# post-install script, and as the .apk post-upgrade script with PKG_UPGRADE=1 +# exported ahead of this body, so one body serves both packagers. # # The fips daemon is enabled and started on every install. The gateway is not: # the package ships that service disabled, and the README and the deployment @@ -19,8 +20,9 @@ # re-enabled, which also re-enables one an operator had # disabled by hand. # -# Under apk this script runs only on a fresh install, so it takes the first -# branch and the gateway stays off. +# Under apk, a fresh install runs this as post-install and the gateway stays +# off. An upgrade runs it as post-upgrade, after the .apk pre-upgrade script +# (the prerm body) has stopped the services and left the marker. UPGRADE_MARKER=/tmp/fips-prerm-upgrade diff --git a/packaging/openwrt-ipk/scripts/prerm b/packaging/openwrt-ipk/scripts/prerm index f1db5153..09dcf365 100755 --- a/packaging/openwrt-ipk/scripts/prerm +++ b/packaging/openwrt-ipk/scripts/prerm @@ -2,7 +2,8 @@ # Maintainer script run before the FIPS package is removed or replaced. # # Installed as the .ipk CONTROL/prerm and registered as the .apk pre-deinstall -# script, so one body serves both packagers. +# script, and as the .apk pre-upgrade script with its arguments rewritten to +# "upgrade ", so one body serves both packagers. # # opkg calls this with "upgrade " when the package is being # replaced. Disabling the services there would erase the operator's choice, diff --git a/testing/openwrt/maintainer-scripts-test.sh b/testing/openwrt/maintainer-scripts-test.sh index 8a8d4eea..e31b8d22 100755 --- a/testing/openwrt/maintainer-scripts-test.sh +++ b/testing/openwrt/maintainer-scripts-test.sh @@ -31,9 +31,23 @@ if [[ ! -f "$SCRIPT_DIR/scenarios.sh" ]]; then exit 2 fi +# The .apk wraps the shared bodies for its upgrade path. package-test.sh builds +# the package on the host with the real build-apk.sh, checks what it registers, +# and leaves the four scripts here so the scenarios run exactly what ships. +APK_DIR="$(mktemp -d)" || { echo "openwrt-scripts: mktemp failed" >&2; exit 2; } +trap 'rm -rf "$APK_DIR"' EXIT +bash "$SCRIPT_DIR/package-test.sh" --keep "$APK_DIR" +rc=$? +if [[ $rc -ne 0 ]]; then + echo "openwrt-scripts: package-test.sh exited $rc" >&2 + exit $rc +fi + docker run --rm --network none \ -v "$PROJECT_ROOT:/src:ro" \ + -v "$APK_DIR:/apk:ro" \ -e REPO=/src \ + -e APK_SCRIPTS=/apk \ -e "POSTINST=${POSTINST:-}" \ -e "PRERM=${PRERM:-}" \ "$IMAGE" sh /src/testing/openwrt/scenarios.sh diff --git a/testing/openwrt/package-test.sh b/testing/openwrt/package-test.sh new file mode 100755 index 00000000..c15ecdfa --- /dev/null +++ b/testing/openwrt/package-test.sh @@ -0,0 +1,240 @@ +#!/bin/bash +# ── OpenWrt package contents, checked on the host ─────────────────────────── +# Runs the real packaging/openwrt-apk/build-apk.sh against placeholder +# binaries and a stub `apk` that records what `apk mkpkg` was asked to +# package. No docker, no apk-tools and no FIPS build are needed. +# +# What it checks is which maintainer scripts the .apk registers and what each +# one does with apk's upgrade arguments and environment (apk-tools v3 passes +# " " and a PATH-only environment to pre-upgrade and +# post-upgrade). Whether a real `apk mkpkg` accepts the result is left to the +# GitHub packaging workflow, which builds with the real tool. +# +# Usage: package-test.sh [--keep ] +# --keep copy the captured apk scripts into as post-install, +# pre-upgrade, post-upgrade and pre-deinstall, so +# scenarios.sh can run them under ash. +# +# Exit 0 = every check passed. Exit 1 = at least one failed. Exit 2 = the +# harness could not run; never treated as a pass. +# ───────────────────────────────────────────────────────────────────────────── +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +SCRIPTS_SRC="$PROJECT_ROOT/packaging/openwrt-ipk/scripts" + +KEEP="" +while [[ $# -gt 0 ]]; do + case "$1" in + --keep) + [[ $# -ge 2 ]] || { echo "package-test: --keep needs a directory" >&2; exit 2; } + KEEP="$2" + shift 2 + ;; + *) echo "package-test: unknown argument: $1" >&2; exit 2 ;; + esac +done +if [[ -n "$KEEP" && ! -d "$KEEP" ]]; then + echo "package-test: --keep needs an existing directory" >&2 + exit 2 +fi + +# The version is unique to this run so the cleanup below removes only what +# this run's builders wrote into dist/. +PKG_VERSION="pkgtest.$$" +TMP="$(mktemp -d)" || { echo "package-test: mktemp failed" >&2; exit 2; } + +trap 'rm -rf "$TMP"; rm -f "$PROJECT_ROOT/dist/fips_${PKG_VERSION}_"*' EXIT + +harness_fail() { + echo "package-test: $*" >&2 + exit 2 +} + +FAILURES=0 +CASES=0 + +ok() { + CASES=$((CASES + 1)) + echo " ok $*" + return 0 +} + +bad() { + CASES=$((CASES + 1)) + FAILURES=$((FAILURES + 1)) + echo " FAIL $*" + return 0 +} + +# ── Build the .apk against a stub apk ─────────────────────────────────────── + +BINS="$TMP/bins" +CAPTURE="$TMP/capture" +mkdir -p "$BINS" "$CAPTURE" || harness_fail "cannot create $TMP subdirectories" +for bin in fips fipsctl fipstop fips-gateway; do + printf 'x' > "$BINS/$bin" || harness_fail "cannot write placeholder $bin" +done + +# The stub knows only the arguments build-apk.sh passes today. Anything else +# exits 64, so a new mkpkg argument fails the build rather than going unseen. +cat > "$TMP/apk" <&2; exit 64; } +shift +files="" +out="" +while [ \$# -gt 0 ]; do + [ \$# -ge 2 ] || { echo "stub apk: \$1 has no value" >&2; exit 64; } + case "\$1" in + --info) ;; + --script) + phase="\${2%%:*}" + cp "\${2#*:}" "\$cap/script.\$phase" + echo "\$phase" >> "\$cap/phases" + ;; + --files) files="\$2" ;; + --output) out="\$2" ;; + *) echo "stub apk: unknown argument \$1" >&2; exit 64 ;; + esac + shift 2 +done +[ -n "\$files" ] && [ -n "\$out" ] || { echo "stub apk: --files and --output are required" >&2; exit 64; } +(cd "\$files" && find . -mindepth 1 | LC_ALL=C sort) > "\$cap/payload" +: > "\$out" +: > "\$cap/called" +STUB +chmod 0755 "$TMP/apk" || harness_fail "cannot make the stub apk executable" + +echo "OpenWrt package checks" +echo "==> build-apk.sh with a stub apk" +if ! PKG_VERSION="$PKG_VERSION" APK_VERSION=0.0.0-r0 APK_BIN="$TMP/apk" \ + bash "$PROJECT_ROOT/packaging/openwrt-apk/build-apk.sh" --arch x86_64 --bin-dir "$BINS" \ + > "$TMP/build-apk.log" 2>&1; then + cat "$TMP/build-apk.log" >&2 + harness_fail "build-apk.sh failed, so nothing was checked" +fi +[[ -f "$CAPTURE/called" ]] || harness_fail "build-apk.sh exited 0 but never ran apk mkpkg" +[[ -f "$CAPTURE/phases" ]] || harness_fail "apk mkpkg ran but no script phase was recorded" + +# ── A1. The .apk registers exactly the four lifecycle scripts ─────────────── +# apk runs only post-install on a fresh install, only pre-upgrade and +# post-upgrade on an upgrade, and only pre-deinstall on a removal. +WANT_PHASES="post-install post-upgrade pre-deinstall pre-upgrade" +got_phases="$(LC_ALL=C sort "$CAPTURE/phases" | tr '\n' ' ')" +got_phases="${got_phases% }" +if [[ "$got_phases" == "$WANT_PHASES" ]]; then + ok "A1 the .apk registers $WANT_PHASES" +else + missing="" + for phase in $WANT_PHASES; do + grep -qxF "$phase" "$CAPTURE/phases" || missing="$missing $phase" + done + bad "A1 registered phases are '$got_phases', want '$WANT_PHASES'; missing:${missing:- none}" +fi + +# ── A2. Every registered script starts with a working #! line ─────────────── +# apk execs the script directly, so the kernel reads line 1. +for phase in $WANT_PHASES; do + script="$CAPTURE/script.$phase" + if [[ ! -f "$script" ]]; then + bad "A2 $phase is not registered, so it has no #! line" + elif [[ "$(head -n 1 "$script")" == "#!/bin/sh" ]]; then + ok "A2 $phase starts with #!/bin/sh" + else + bad "A2 $phase starts with '$(head -n 1 "$script")', not #!/bin/sh" + fi +done + +# ── A3. Install and removal ship the shared bodies unchanged ──────────────── +for pair in post-install:postinst pre-deinstall:prerm; do + phase="${pair%%:*}" + src="$SCRIPTS_SRC/${pair#*:}" + if cmp -s "$CAPTURE/script.$phase" "$src"; then + ok "A3 $phase is the shipped ${pair#*:}, byte for byte" + else + bad "A3 $phase differs from the shipped ${pair#*:}" + fi +done + +# ── A4 and A5. The upgrade pair wraps the shared bodies ───────────────────── +# A4 reads the structure: the script ends with the body after its #! line, and +# at least one header line sits between the two. A5 runs the header with apk's +# upgrade argv and environment, so what is judged is what the shell does with +# it, not how it reads. +for pair in pre-upgrade:prerm post-upgrade:postinst; do + phase="${pair%%:*}" + src="$SCRIPTS_SRC/${pair#*:}" + script="$CAPTURE/script.$phase" + if [[ ! -f "$script" ]]; then + bad "A4 $phase is not registered" + bad "A5 $phase is not registered, so its header cannot run" + continue + fi + + tail -n +2 "$src" > "$TMP/body" || harness_fail "cannot read $src" + body_lines=$(wc -l < "$TMP/body") + script_lines=$(wc -l < "$script") + header_lines=$((script_lines - body_lines)) + if [[ $header_lines -lt 2 ]]; then + bad "A4 $phase has $header_lines header line(s) before the ${pair#*:} body, want at least 2" + elif ! tail -n "$body_lines" "$script" | cmp -s - "$TMP/body"; then + bad "A4 $phase does not end with the ${pair#*:} body" + else + ok "A4 $phase is a $header_lines-line header and the ${pair#*:} body" + fi + + if [[ $header_lines -lt 1 ]]; then + bad "A5 $phase has no header to run" + continue + fi + probe="$TMP/probe.$phase" + { + head -n "$header_lines" "$script" + # shellcheck disable=SC2016 + printf '%s\n' 'printf '\''%s|%s|%s\n'\'' "${1-}" "${2-}" "${PKG_UPGRADE-}"' + } > "$probe" + chmod 0755 "$probe" || harness_fail "cannot make the $phase probe executable" + got="$(env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin "$probe" 0.6.0-r1 0.5.2-r1)" + rc=$? + if [[ $rc -eq 126 || $rc -eq 127 ]]; then + harness_fail "the $phase probe could not be executed (exit $rc)" + fi + IFS='|' read -r f1 f2 f3 <<< "$got" + case "$phase" in + pre-upgrade) + if [[ $rc -eq 0 && "$f1|$f2" == "upgrade|0.6.0-r1" ]]; then + ok "A5 pre-upgrade hands the body 'upgrade 0.6.0-r1'" + else + bad "A5 pre-upgrade hands the body '$f1 $f2' (exit $rc), want 'upgrade 0.6.0-r1'" + fi + ;; + post-upgrade) + if [[ $rc -eq 0 && "$f3" == "1" ]]; then + ok "A5 post-upgrade runs the body with PKG_UPGRADE=1" + else + bad "A5 post-upgrade runs the body with PKG_UPGRADE='$f3' (exit $rc), want 1" + fi + ;; + esac +done + +# ── Hand the scripts to the ash scenarios ─────────────────────────────────── +if [[ -n "$KEEP" ]]; then + for phase in $WANT_PHASES; do + [[ -f "$CAPTURE/script.$phase" ]] || continue + install -m 0755 "$CAPTURE/script.$phase" "$KEEP/$phase" \ + || harness_fail "cannot copy $phase into $KEEP" + done +fi + +echo "" +if [[ $FAILURES -eq 0 ]]; then + echo "package-test: all $CASES checks passed" + exit 0 +fi +echo "package-test: $FAILURES of $CASES checks failed" +exit 1 diff --git a/testing/openwrt/scenarios.sh b/testing/openwrt/scenarios.sh index b060d0b1..6c7f4007 100755 --- a/testing/openwrt/scenarios.sh +++ b/testing/openwrt/scenarios.sh @@ -11,6 +11,13 @@ # POSTINST and PRERM may be pointed at other files. That is the seam used to # see a scenario red against the previously released scripts, and to re-break # the fixed ones during a break-check. +# +# APK_SCRIPTS names a directory holding the four scripts the .apk registers +# (post-install, pre-upgrade, post-upgrade, pre-deinstall), as captured from +# the real build-apk.sh by package-test.sh --keep. Scenarios 8 to 10 execute +# them directly with apk-tools v3's argv and PATH-only environment, so the +# kernel reads their #! line and ash runs them. A missing directory or script +# fails those scenarios; it is never a skip. set -u @@ -19,6 +26,7 @@ POSTINST="${POSTINST:-$REPO/packaging/openwrt-ipk/scripts/postinst}" PRERM="${PRERM:-$REPO/packaging/openwrt-ipk/scripts/prerm}" RELEASED_PRERM="$REPO/testing/openwrt/fixtures/released-prerm" INIT_GATEWAY="$REPO/packaging/openwrt-ipk/files/etc/init.d/fips-gateway" +APK_SCRIPTS="${APK_SCRIPTS:-}" SHIPPED_YAML="$REPO/packaging/openwrt-ipk/files/etc/fips/fips.yaml" WORK=/tmp/fips-openwrt-scenarios @@ -146,6 +154,52 @@ assert_absent() { return 0 } +assert_present() { + if [ -e "$1" ]; then + ok "$2" + else + bad "$2 — $1 does not exist" + fi + return 0 +} + +first_call_line() { + grep -nxF "$1" "$CALLS" | head -n 1 | cut -d: -f1 + return 0 +} + +assert_order() { + # assert_order + first="$(first_call_line "$1")" + second="$(first_call_line "$2")" + if [ -z "$first" ] || [ -z "$second" ]; then + bad "$3 — '$1' and '$2' were not both called: $(calls_oneline)" + elif [ "$first" -lt "$second" ]; then + ok "$3" + else + bad "$3 — '$2' came before '$1': $(calls_oneline)" + fi + return 0 +} + +run_apk_script() { + # run_apk_script + # Runs one captured .apk script the way apk-tools v3 does: executed + # directly, with only PATH in the environment. The stubs' own state + # variables are passed through so they can record the calls. + phase="$1" + shift + script="$APK_SCRIPTS/$phase" + if [ -z "$APK_SCRIPTS" ] || [ ! -x "$script" ]; then + bad "the .apk $phase script is not available at '$script'" + return 1 + fi + env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin \ + CALLS="$CALLS" GW_STATE="$GW_STATE" FIPS_STATE="$FIPS_STATE" \ + "$script" "$@" >/dev/null 2>&1 + return 0 +} + # ── 1. Fresh install ──────────────────────────────────────────────────────── # opkg runs the postinst with "configure"; PKG_UPGRADE is set only on upgrades, # so both its absence and an explicit 0 must leave the gateway alone. @@ -321,9 +375,69 @@ YAML return 0 } +# ── 8. apk fresh install ──────────────────────────────────────────────────── +# apk-tools v3 runs only post-install, with the new version as its argument. +scenario_apk_fresh_install() { + note "scenario 8: apk fresh install" + reset_state + + run_apk_script post-install 0.6.0-r1 || return 0 + + assert_called "fips enable" "an apk install enables the daemon" + assert_called "fips start" "an apk install starts the daemon" + assert_not_called "fips-gateway enable" "an apk install does not enable the gateway" + assert_not_called "fips-gateway start" "an apk install does not start the gateway" + assert_file_is "$GW_STATE" "0" "an apk install leaves the gateway disabled" + return 0 +} + +# ── 9. apk upgrade, gateway enabled ───────────────────────────────────────── +# apk-tools v3 runs only the new package's pre-upgrade and post-upgrade, with +# " "; the old package runs nothing. +scenario_apk_upgrade_enabled() { + note "scenario 9: apk upgrade, gateway enabled" + reset_state + echo 1 > "$GW_STATE" + echo 1 > "$FIPS_STATE" + + run_apk_script pre-upgrade 0.6.0-r1 0.5.2-r1 || return 0 + assert_called "fips-gateway stop" "pre-upgrade stops the gateway" + assert_called "fips stop" "pre-upgrade stops the daemon" + assert_not_called "fips-gateway disable" "pre-upgrade does not disable the gateway" + assert_not_called "fips disable" "pre-upgrade does not disable the daemon" + assert_file_is "$GW_STATE" "1" "the gateway is still enabled after pre-upgrade" + assert_present "$UPGRADE_MARKER" "pre-upgrade leaves the upgrade marker" + + run_apk_script post-upgrade 0.6.0-r1 0.5.2-r1 || return 0 + assert_order "fips stop" "fips start" "the daemon is started again after it was stopped" + assert_order "fips-gateway stop" "fips-gateway start" "the gateway is started again after it was stopped" + assert_not_called "fips-gateway enable" "an enabled gateway does not need re-enabling" + assert_file_is "$GW_STATE" "1" "the gateway stays enabled across the apk upgrade" + assert_absent "$UPGRADE_MARKER" "post-upgrade removes the upgrade marker" + return 0 +} + +# ── 10. apk upgrade, gateway disabled ─────────────────────────────────────── +scenario_apk_upgrade_disabled() { + note "scenario 10: apk upgrade, gateway disabled" + reset_state + echo 1 > "$FIPS_STATE" + + run_apk_script pre-upgrade 0.6.0-r1 0.5.2-r1 || return 0 + run_apk_script post-upgrade 0.6.0-r1 0.5.2-r1 || return 0 + + assert_order "fips stop" "fips start" "the daemon is started again after it was stopped" + assert_file_is "$GW_STATE" "0" "a disabled gateway stays disabled across the apk upgrade" + assert_not_called "fips-gateway enable" "a disabled gateway is not enabled by the apk upgrade" + assert_not_called "fips-gateway start" "a disabled gateway is not started by the apk upgrade" + assert_absent "$UPGRADE_MARKER" "post-upgrade removes the upgrade marker" + return 0 +} + echo "OpenWrt maintainer-script scenarios (shell: $(readlink -f /proc/$$/exe 2>/dev/null || echo sh))" echo " postinst: $POSTINST" echo " prerm: $PRERM" +echo " apk: ${APK_SCRIPTS:-(not set)}" scenario_fresh_install scenario_upgrade_from_released @@ -332,6 +446,9 @@ scenario_upgrade_disabled scenario_removal scenario_config_reader scenario_start_service_guard +scenario_apk_fresh_install +scenario_apk_upgrade_enabled +scenario_apk_upgrade_disabled echo "" if [ "$FAILURES" -eq 0 ]; then