diff --git a/README.md b/README.md index cc08bde..f17452d 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,39 @@ Kod pluginu OPNsense znajduje się w: opnsense/plugin/ ``` +## OPNsense: autostart i sprawdzanie aktualizacji aplikacji + +W **Services -> RustProxy** zaznacz **Enabled** i naciśnij **Apply**. Pakiet +instaluje wykonywalny syshook w +`/usr/local/etc/rc.syshook.d/start/50-rustproxy.start`. Po restarcie systemu, +gdy sieć już działa, hook odświeża konfigurację z OPNsense i uruchamia usługę +tylko wtedy, gdy jest włączona. Powtórny start nie tworzy drugiego procesu. + +Pole **Update check interval (seconds)** steruje argumentem RustProxy +`--update-check-interval-secs`. Domyślnie `3600` (godzina); dopuszczalny zakres +to `60`–`604800` sekund. Wartość nie dotyczy `POLL_INTERVAL` buildera, +który nadal odpowiada wyłącznie za sprawdzanie repozytorium kodu. + +Sprawdzenie po restarcie OPNsense: + +```sh +ls -l /usr/local/etc/rc.syshook.d/start/50-rustproxy.start +configctl rustproxy status +cat /var/run/rustproxy/command.txt +``` + +W `command.txt` powinien wystąpić aktualnie ustawiony parametr +`--update-check-interval-secs `. Jeśli usługa nie wystartuje, sprawdź +`/var/log/rustproxy/rustproxy.log` oraz uruchom ręcznie: + +```sh +configctl template reload OPNsense/RustProxy +configctl rustproxy start +``` + +Zmiana wtyczki zwiększa tylko `OPNSENSE_PACKAGING_REVISION` do `3`. +Rewizja pakowania Linux (`PACKAGING_REVISION=2`) pozostaje bez zmian. + ## Rotacja logów RustProxy - **DEB/RPM:** builder zawsze umieszcza `packaging/rustproxy.logrotate` w `/etc/logrotate.d/rustproxy` (nFPM: `config|noreplace`). Logrotate jest zależnością obu pakietów. Reguła obejmuje `/var/log/rustproxy/*.jsonl`, `*.log` i `vhosts/*.jsonl`, z rotacją codzienną lub po przekroczeniu 100 MiB, 14 archiwami, gzip z opóźnioną kompresją, `copytruncate` oraz `su rustproxy rustproxy`. @@ -155,7 +188,7 @@ opnsense/plugin/ **Uwaga FreeBSD:** `newsyslog` działa przez zmianę nazwy pliku, nie ma `copytruncate`. Pliki JSONL i inne logi otwarte bezpośrednio przez aplikację muszą być przez nią ponownie otwierane po rotacji. W przeciwnym razie proces może pisać do poprzedniego (przeniesionego) pliku; zachowanie nie jest identyczne z Linux. Reguły są instalowane, ale na działającym OPNsense należy zweryfikować sposób otwierania plików przez RustProxy. -Zmiana konfiguracji pakietów ustawia `PACKAGING_REVISION=2`. `check-and-build.sh` porównuje rewizję z metadanymi aktualnych repozytoriów; po podmianie buildera `./start.sh` przebudowuje obie gałęzie **nawet przy tym samym SHA źródła**. Automatyczny release DEB/RPM oraz rewizja PKG są zwiększane, aby menedżer pakietów mógł zainstalować nową wersję. Konfiguracja w `/etc/logrotate.d/rustproxy` jest oznaczona jako `noreplace`, więc lokalna wersja zmodyfikowana przez administratora może zostać zachowana (zależnie od menedżera pakietów). +Poprzednia zmiana rotacji logów ustawiła `PACKAGING_REVISION=2`. `check-and-build.sh` sprawdza osobno rewizję pakowania Linux i OPNsense; nowa wersja samej wtyczki przebudowuje **tylko OPNsense**, nawet przy niezmienionym SHA aplikacji. Rewizja pakietu PKG zwiększy się automatycznie. W przypadku zmiany rewizji Linux analogicznie odświeżane są DEB/RPM. Konfiguracja w `/etc/logrotate.d/rustproxy` jest oznaczona jako `noreplace`, więc lokalna wersja zmodyfikowana przez administratora może zostać zachowana (zależnie od menedżera pakietów). Kontrola po zainstalowaniu: diff --git a/opnsense/plugin/Makefile b/opnsense/plugin/Makefile index abd1039..02a527d 100644 --- a/opnsense/plugin/Makefile +++ b/opnsense/plugin/Makefile @@ -1,6 +1,6 @@ PLUGIN_NAME= rustproxy PLUGIN_VERSION?= 0.23.3 -PLUGIN_REVISION?= 1 +PLUGIN_REVISION?= 2 PLUGIN_COMMENT= RustProxy reverse proxy service PLUGIN_MAINTAINER?= local@localhost PLUGIN_WWW?= https://git.linuxiarz.pl/gru/RustProxy diff --git a/opnsense/plugin/src/etc/rc.d/rustproxy b/opnsense/plugin/src/etc/rc.d/rustproxy index b21f7b1..31ddb99 100755 --- a/opnsense/plugin/src/etc/rc.d/rustproxy +++ b/opnsense/plugin/src/etc/rc.d/rustproxy @@ -24,6 +24,7 @@ load_rc_config "$name" : ${rustproxy_command:="/usr/local/sbin/rust-proxy"} : ${rustproxy_restart_delay:="5"} : ${rustproxy_allow_remote_admin:="1"} +: ${rustproxy_update_check_interval_secs:="3600"} # FreeBSD uses jemalloc rather than glibc. Keep the same low-arena intent as # Linux MALLOC_ARENA_MAX=2 with the native jemalloc knob. rc.conf can override # rustproxy_malloc_conf or set it to an empty value to disable the tuning. @@ -147,7 +148,22 @@ rustproxy_admin_listen_resolved="$(rustproxy_resolve_listener \ "$rustproxy_admin_listen_legacy" "$rustproxy_admin_listen" \ "0.0.0.0" "9090" "admin")" || exit 1 -rustproxy_runtime_args="--data-dir ${rustproxy_data_dir} --admin-listen ${rustproxy_admin_listen_resolved} --update-check-interval-secs 3600 serve --proxy-listen ${rustproxy_proxy_listen_resolved}" +# The CLI expects a positive interval (seconds), not a value hardcoded in rc.d. +# Validate again at runtime for hand-written or stale configurations. +rustproxy_valid_update_interval() +{ + case "$1" in + ''|*[!0-9]*) return 1 ;; + esac + [ "$1" -ge 60 ] 2>/dev/null && [ "$1" -le 604800 ] 2>/dev/null +} + +if ! rustproxy_valid_update_interval "$rustproxy_update_check_interval_secs"; then + echo "Invalid RustProxy update check interval: ${rustproxy_update_check_interval_secs} (60-604800 seconds)" >&2 + exit 1 +fi + +rustproxy_runtime_args="--data-dir ${rustproxy_data_dir} --admin-listen ${rustproxy_admin_listen_resolved} --update-check-interval-secs ${rustproxy_update_check_interval_secs} serve --proxy-listen ${rustproxy_proxy_listen_resolved}" if [ "$rustproxy_tls_enabled" = "1" ]; then rustproxy_runtime_args="${rustproxy_runtime_args} --tls-listen ${rustproxy_tls_listen_resolved}" fi @@ -201,6 +217,7 @@ rustproxy_prestart() if [ -n "${rustproxy_malloc_conf}" ]; then echo "RustProxy allocator: MALLOC_CONF=${rustproxy_malloc_conf}" fi + echo "RustProxy update check interval: ${rustproxy_update_check_interval_secs}s" echo "RustProxy exec: ${rustproxy_command} ${rustproxy_runtime_args}" printf '%s\n' "${rustproxy_command} ${rustproxy_runtime_args}" > "${rustproxy_run_dir}/command.txt" /bin/chmod 0640 "${rustproxy_run_dir}/command.txt" diff --git a/opnsense/plugin/src/etc/rc.syshook.d/start/50-rustproxy.start b/opnsense/plugin/src/etc/rc.syshook.d/start/50-rustproxy.start new file mode 100755 index 0000000..43ae702 --- /dev/null +++ b/opnsense/plugin/src/etc/rc.syshook.d/start/50-rustproxy.start @@ -0,0 +1,19 @@ +#!/bin/sh + +# OPNsense invokes this hook after networking and configd are available. +# Regenerate from config.xml on every boot: /var and /usr/local/etc may have +# been restored, or the administrator may have changed the GUI settings. +# Retry briefly if configd is still finishing startup on slower firewalls. +attempt=1 +while ! /usr/local/sbin/configctl template reload OPNsense/RustProxy; do + if [ "$attempt" -ge 3 ]; then + echo "RustProxy: failed to render configuration during boot (3 attempts)" >&2 + exit 1 + fi + attempt=$((attempt + 1)) + /bin/sleep 2 +done + +# Use the helper directly: its enabled check is based on the freshly rendered +# configuration and it does not rely on configd reloading our action registry. +exec /usr/local/opnsense/scripts/rustproxy/service.sh boot diff --git a/opnsense/plugin/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml b/opnsense/plugin/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml index f7e8bdb..d941823 100644 --- a/opnsense/plugin/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml +++ b/opnsense/plugin/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml @@ -76,4 +76,16 @@ checkbox Pass --allow-remote-admin so the RustProxy panel accepts non-loopback clients. Keep firewall access restricted to trusted networks; do not expose the admin port to WAN unless this is intentional. + + + + header + true + + + rustproxy.general.updateCheckIntervalSecs + + text + How often RustProxy checks for new application versions. Default: 3600 seconds (1 hour). Allowed range: 60-604800 seconds. Changes take effect after Apply. + diff --git a/opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_5_0.php b/opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_5_0.php new file mode 100644 index 0000000..c5c8acb --- /dev/null +++ b/opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_5_0.php @@ -0,0 +1,17 @@ +general->updateCheckIntervalSecs) === '') { + $model->general->updateCheckIntervalSecs = '3600'; + } + } +} diff --git a/opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml b/opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml index fa791fb..8f04577 100644 --- a/opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml +++ b/opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml @@ -1,6 +1,6 @@ //OPNsense/rustproxy - 1.4.0 + 1.5.0 RustProxy service settings @@ -57,6 +57,13 @@ 1 Y + + 3600 + 60 + 604800 + Y + Enter the number of seconds between update checks (60-604800). + diff --git a/opnsense/plugin/src/opnsense/scripts/rustproxy/service.sh b/opnsense/plugin/src/opnsense/scripts/rustproxy/service.sh index d4f1c44..ec9949c 100755 --- a/opnsense/plugin/src/opnsense/scripts/rustproxy/service.sh +++ b/opnsense/plugin/src/opnsense/scripts/rustproxy/service.sh @@ -16,6 +16,11 @@ start_service() echo "RustProxy is disabled in OPNsense configuration" return 0 fi + # OPNsense may invoke rc.d in addition to this boot hook. Avoid a second + # daemon supervisor when the service is already running. + if "$RC_SCRIPT" status >/dev/null 2>&1; then + return 0 + fi "$RC_SCRIPT" onestart } diff --git a/opnsense/plugin/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf b/opnsense/plugin/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf index dc4cffb..6ace7d0 100644 --- a/opnsense/plugin/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf +++ b/opnsense/plugin/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf @@ -10,6 +10,8 @@ rustproxy_tls_port="{% if not helpers.empty('OPNsense.rustproxy.general.tlsPort' rustproxy_admin_address="{% if not helpers.empty('OPNsense.rustproxy.general.adminAddress') %}{{ OPNsense.rustproxy.general.adminAddress }}{% endif %}" rustproxy_admin_port="{% if not helpers.empty('OPNsense.rustproxy.general.adminPort') %}{{ OPNsense.rustproxy.general.adminPort }}{% endif %}" rustproxy_allow_remote_admin="{% if not helpers.empty('OPNsense.rustproxy.general.allowRemoteAdmin') %}1{% else %}0{% endif %}" +# Existing installations without this setting use the 3600-second default. +rustproxy_update_check_interval_secs="{% if not helpers.empty('OPNsense.rustproxy.general.updateCheckIntervalSecs') %}{{ OPNsense.rustproxy.general.updateCheckIntervalSecs }}{% else %}3600{% endif %}" # Legacy 1.2.x combined settings. They are only used when the corresponding # new split address/port fields are both empty. diff --git a/scripts/build-opnsense-release.sh b/scripts/build-opnsense-release.sh index 66bd6c0..51dd611 100755 --- a/scripts/build-opnsense-release.sh +++ b/scripts/build-opnsense-release.sh @@ -100,7 +100,7 @@ source_ref=$SOURCE_BRANCH source_commit=$SHA build_reason=$BUILD_REASON source_revision=$SOURCE_REVISION -packaging_revision=$PACKAGING_REVISION +packaging_revision=$OPNSENSE_PACKAGING_REVISION opnsense_series=$OPNSENSE_ABI freebsd_release=$FREEBSD_RELEASE freebsd_abi=$FREEBSD_ABI diff --git a/scripts/check-and-build.sh b/scripts/check-and-build.sh index 3505e4f..c179ece 100755 --- a/scripts/check-and-build.sh +++ b/scripts/check-and-build.sh @@ -44,7 +44,7 @@ opnsense_release_complete_for_commit() { [[ -f "$opnsense/os-rustproxy-latest.pkg" ]] || return 1 grep -Fqx "source_commit=$sha" "$opnsense/BUILD-INFO.txt" || return 1 grep -Fqx "opnsense_series=$OPNSENSE_ABI" "$opnsense/BUILD-INFO.txt" || return 1 - grep -Fqx "packaging_revision=$PACKAGING_REVISION" "$opnsense/BUILD-INFO.txt" || return 1 + grep -Fqx "packaging_revision=$OPNSENSE_PACKAGING_REVISION" "$opnsense/BUILD-INFO.txt" || return 1 [[ -d "$package_dir" ]] || return 1 find "$package_dir" -maxdepth 1 -type f -name 'os-rustproxy-*.pkg' -print -quit | grep -q . || return 1 return 0 diff --git a/scripts/lib.sh b/scripts/lib.sh index 5cd279b..e35d6cb 100755 --- a/scripts/lib.sh +++ b/scripts/lib.sh @@ -3,6 +3,7 @@ set -Eeuo pipefail # Increment when package payload/installation semantics change without a source commit. PACKAGING_REVISION=2 +OPNSENSE_PACKAGING_REVISION=3 log() { printf '%s %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$*" diff --git a/scripts/package-opnsense.sh b/scripts/package-opnsense.sh index 8eaf2cd..11dc848 100755 --- a/scripts/package-opnsense.sh +++ b/scripts/package-opnsense.sh @@ -36,7 +36,7 @@ mkdir -p "$STAGE/usr/local/sbin" install -m 0555 "$BINARY" "$STAGE/usr/local/sbin/rust-proxy" chmod 0555 "$STAGE/usr/local/etc/rc.d/rustproxy" -chmod 0555 "$STAGE/usr/local/etc/rc.syshook.d/10-rustproxy.start" +chmod 0555 "$STAGE/usr/local/etc/rc.syshook.d/start/50-rustproxy.start" chmod 0555 "$STAGE/usr/local/opnsense/scripts/rustproxy/service.sh" POST_INSTALL_FILE="$PLUGIN_ROOT/+POST_INSTALL.pre" diff --git a/tests/log-rotation.sh b/tests/log-rotation.sh index 27ed6ef..b33d784 100755 --- a/tests/log-rotation.sh +++ b/tests/log-rotation.sh @@ -28,7 +28,7 @@ grep -Fq '14 100M $D0 GBEZP /var/run/rustproxy/daemon.pid SIGHUP' "$OPNSENSE_CON grep -Fq ' -H -P ${pidfile}' "$ROOT/opnsense/plugin/src/etc/rc.d/rustproxy" grep -Fq 'COPY packaging/ /opt/rust-package-builder/packaging/' "$ROOT/Dockerfile" grep -Fq 'packaging_revision=$PACKAGING_REVISION' "$ROOT/scripts/build-linux-release.sh" -grep -Fq 'packaging_revision=$PACKAGING_REVISION' "$ROOT/scripts/build-opnsense-release.sh" +grep -Fq 'packaging_revision=$OPNSENSE_PACKAGING_REVISION' "$ROOT/scripts/build-opnsense-release.sh" # Test staging and native PKG manifest without compiling Rust or signing RPM/DEB. for tool in file zstd tar sha256sum python3; do @@ -78,6 +78,8 @@ path='/usr/local/etc/newsyslog.conf.d/rustproxy.conf' assert path in manifest['files'], f'{path} missing from PKG manifest' assert path in manifest['files'] and len(manifest['files'][path]) == 64 assert '/usr/local/etc/rc.d/rustproxy' in manifest['files'] +assert '/usr/local/etc/rc.syshook.d/start/50-rustproxy.start' in manifest['files'] +assert '/usr/local/etc/rc.syshook.d/10-rustproxy.start' not in manifest['files'] PY zstd -dc "$WORK/os-rustproxy.pkg" | tar -xOf - /usr/local/etc/newsyslog.conf.d/rustproxy.conf > "$WORK/packaged-newsyslog.conf" cmp "$OPNSENSE_CONF" "$WORK/packaged-newsyslog.conf" diff --git a/tests/opnsense-plugin.sh b/tests/opnsense-plugin.sh new file mode 100755 index 0000000..1b0f022 --- /dev/null +++ b/tests/opnsense-plugin.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash +set -Eeuo pipefail +ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd) +SRC="$ROOT/opnsense/plugin/src" +WORK=$(mktemp -d) +trap 'rm -rf "$WORK"' EXIT + +RC="$SRC/etc/rc.d/rustproxy" +HOOK="$SRC/etc/rc.syshook.d/start/50-rustproxy.start" +SERVICE="$SRC/opnsense/scripts/rustproxy/service.sh" +MODEL="$SRC/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml" +FORM="$SRC/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml" +TEMPLATE="$SRC/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf" + +[[ -f "$HOOK" && -x "$HOOK" ]] || { echo 'Boot syshook must exist and be executable' >&2; exit 1; } +[[ ! -e "$SRC/etc/rc.syshook.d/10-rustproxy.start" ]] || { echo 'Old hook path still exists' >&2; exit 1; } +for script in "$RC" "$HOOK" "$SERVICE"; do + sh -n "$script" +done +php -l "$SRC/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_5_0.php" >/dev/null + +# Ensure GUI, model and Jinja template agree about the new setting. +python3 - "$MODEL" "$FORM" "$TEMPLATE" <<'PY' +import pathlib, sys, xml.etree.ElementTree as ET +model = ET.parse(sys.argv[1]).getroot() +form = ET.parse(sys.argv[2]).getroot() +template = pathlib.Path(sys.argv[3]).read_text() +assert model.find('version').text == '1.5.0' +field = model.find('./items/general/updateCheckIntervalSecs') +assert field is not None and field.attrib['type'] == 'IntegerField' +assert field.findtext('Default') == '3600' +assert field.findtext('MinimumValue') == '60' +assert field.findtext('MaximumValue') == '604800' +assert 'rustproxy.general.updateCheckIntervalSecs' in [e.text for e in form.iter('id')] +assert 'rustproxy_update_check_interval_secs=' in template +assert 'OPNsense.rustproxy.general.updateCheckIntervalSecs' in template +PY + +# Isolate the rc.d argument composition without running FreeBSD-only commands. +cat > "$WORK/rc.subr" <<'EOF' +load_rc_config() { :; } +run_rc_command() { printf '%s\n' "$command_args"; } +EOF +python3 - "$RC" "$WORK/rc-test" "$WORK" <<'PY' +from pathlib import Path +import sys +src = Path(sys.argv[1]).read_text() +work = Path(sys.argv[3]) +src = src.replace('. /etc/rc.subr', '. "'+str(work/'rc.subr')+'"') +src = src.replace('config_file="/usr/local/etc/rustproxy/opnsense.conf"', 'config_file="'+str(work/'opnsense.conf')+'"') +Path(sys.argv[2]).write_text(src) +PY + +assert_interval() { + local val=$1 + printf 'enabled="1"\nrustproxy_update_check_interval_secs="%s"\n' "$val" > "$WORK/opnsense.conf" + local args + args=$(sh "$WORK/rc-test" start) + [[ "$args" == *"--update-check-interval-secs $val serve"* ]] || { + echo "Wrong update interval arguments: $args" >&2; exit 1; + } +} +assert_interval 3600 +assert_interval 7200 +assert_interval 60 +assert_interval 604800 +printf 'enabled="1"\n' > "$WORK/opnsense.conf" +args=$(sh "$WORK/rc-test" start) +[[ "$args" == *'--update-check-interval-secs 3600 serve'* ]] || exit 1 +for invalid in 0 59 604801 nope '1;touch /tmp/pwn'; do + printf 'enabled="1"\nrustproxy_update_check_interval_secs="%s"\n' "$invalid" > "$WORK/opnsense.conf" + if sh "$WORK/rc-test" start >/dev/null 2>&1; then + echo "Interval '$invalid' should have failed" >&2; exit 1 + fi +done + +# Mock configd + rc.d so we can exercise the actual hook and service wrapper. +mkdir -p "$WORK/bin" +cat > "$WORK/bin/configctl" <<'EOF' +#!/bin/sh +printf 'template %s\n' "$*" >> "$TEST_LOG" +if [ "${FAIL_RENDER:-0}" = 1 ]; then + exit 2 +fi +printf 'enabled="%s"\n' "${ENABLED:-1}" > "$TEST_CONFIG" +EOF +cat > "$WORK/bin/rustproxy-rc" <<'EOF' +#!/bin/sh +case "$1" in + status) [ -f "$TEST_PID" ] ;; + onestart) printf 'start\n' >> "$TEST_LOG"; touch "$TEST_PID" ;; + onestop) printf 'stop\n' >> "$TEST_LOG"; rm -f "$TEST_PID" ;; + *) exit 1 ;; +esac +EOF +chmod +x "$WORK/bin/configctl" "$WORK/bin/rustproxy-rc" +python3 - "$HOOK" "$SERVICE" "$WORK" <<'PY' +from pathlib import Path +import sys +hook = Path(sys.argv[1]).read_text() +service = Path(sys.argv[2]).read_text() +w = Path(sys.argv[3]) +hook = hook.replace('/usr/local/sbin/configctl', str(w/'bin/configctl')) +hook = hook.replace('/usr/local/opnsense/scripts/rustproxy/service.sh', str(w/'service-test')) +service = service.replace('/usr/local/etc/rustproxy/opnsense.conf', str(w/'opnsense.conf')) +service = service.replace('/usr/local/etc/rc.d/rustproxy', str(w/'bin/rustproxy-rc')) +(w/'hook-test').write_text(hook) +(w/'service-test').write_text(service) +PY +chmod +x "$WORK/hook-test" "$WORK/service-test" +export TEST_LOG="$WORK/actions.log" TEST_CONFIG="$WORK/opnsense.conf" TEST_PID="$WORK/pidfile" +: > "$TEST_LOG" +ENABLED=1 "$WORK/hook-test" +[[ $(grep -cx start "$TEST_LOG") == 1 ]] || { echo 'Boot did not start service' >&2; exit 1; } +ENABLED=1 "$WORK/hook-test" +[[ $(grep -cx start "$TEST_LOG") == 1 ]] || { echo 'Duplicate supervisor start' >&2; exit 1; } +rm -f "$TEST_PID" +ENABLED=0 "$WORK/hook-test" +[[ $(grep -cx start "$TEST_LOG") == 1 ]] || { echo 'Disabled service started' >&2; exit 1; } +if FAIL_RENDER=1 ENABLED=1 "$WORK/hook-test" >/dev/null 2>&1; then + echo 'Broken configuration reload was not reported' >&2; exit 1 +fi +[[ $(grep -cx start "$TEST_LOG") == 1 ]] || { echo 'Started despite failed template rendering' >&2; exit 1; } + +echo 'OPNsense boot / update interval checks: OK' diff --git a/tests/static.sh b/tests/static.sh index 84fb4c5..62fa6b2 100755 --- a/tests/static.sh +++ b/tests/static.sh @@ -32,6 +32,9 @@ grep -q 'package-opnsense.sh' "$ROOT/scripts/build-opnsense-release.sh" grep -q 'generate-opnsense-repo.py' "$ROOT/scripts/build-opnsense-release.sh" grep -q 'last_opnsense_commit' "$ROOT/scripts/build-opnsense-release.sh" test -f "$ROOT/opnsense/plugin/src/etc/rc.d/rustproxy" +test -x "$ROOT/opnsense/plugin/src/etc/rc.syshook.d/start/50-rustproxy.start" +! test -e "$ROOT/opnsense/plugin/src/etc/rc.syshook.d/10-rustproxy.start" +grep -q 'OPNSENSE_PACKAGING_REVISION=3' "$ROOT/scripts/lib.sh" test -f "$ROOT/opnsense/patches/0.20.0/0001-opnsense-build.patch" # Per-branch state/retry logic.