fixes in opnsesne addon

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-10 11:30:05 +02:00
1 parent c507e9e12a
commit 17f1de681e
16 files changed
+251 -8

No files matched your search

+3 -1
View File
@@ -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"
+125
View File
@@ -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'
+3
View File
@@ -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.