Record CFG-14 runtime path evidence
This commit is contained in:
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
SERVICE=${BONGO_TEST_SERVICE:-bongo.service}
|
||||
PACKAGE=${BONGO_TEST_PACKAGE:-mail-mta/bongo}
|
||||
RUNTIME_DIR=${BONGO_TEST_RUNTIME_DIR:-/run/bongo}
|
||||
STATE_DIR=${BONGO_TEST_STATE_DIR:-/var/lib/bongo}
|
||||
TMPFILES_NAME=${BONGO_TEST_TMPFILES_NAME:-bongo.conf}
|
||||
|
||||
if [ "${BONGO_ALLOW_LIVE_RUNTIME_TEST:-}" != 1 ]; then
|
||||
echo "set BONGO_ALLOW_LIVE_RUNTIME_TEST=1 for the disposable host" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
case "$RUNTIME_DIR" in
|
||||
/run/bongo) ;;
|
||||
*)
|
||||
echo "refusing to remove unexpected runtime directory $RUNTIME_DIR" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
systemctl_cmd()
|
||||
{
|
||||
sudo -n /usr/bin/systemctl "$@"
|
||||
}
|
||||
|
||||
runtime_pid_ready()
|
||||
{
|
||||
size=$(sudo -n /usr/bin/stat -c '%s' \
|
||||
"$RUNTIME_DIR/bongomanager.pid" 2>/dev/null || true)
|
||||
[ -n "$size" ] && [ "$size" -gt 0 ] 2>/dev/null
|
||||
}
|
||||
|
||||
restore_service()
|
||||
{
|
||||
systemctl_cmd reset-failed "$SERVICE" >/dev/null 2>&1 || true
|
||||
systemctl_cmd start "$SERVICE" >/dev/null 2>&1 || true
|
||||
}
|
||||
trap restore_service EXIT HUP INT TERM
|
||||
|
||||
package_paths=$(qlist -e "$PACKAGE")
|
||||
if printf '%s\n' "$package_paths" |
|
||||
grep -Eq '^(/run|/var/run)(/|$)|/bongomanager\.pid$|/[[:alnum:]_-]+\.pid$'; then
|
||||
echo "$PACKAGE contains a runtime directory or PID file" >&2
|
||||
printf '%s\n' "$package_paths" |
|
||||
grep -E '^(/run|/var/run)(/|$)|/bongomanager\.pid$|/[[:alnum:]_-]+\.pid$' >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "PASS package image contains no runtime directory or PID file"
|
||||
|
||||
tmpfiles_path=/usr/lib/tmpfiles.d/$TMPFILES_NAME
|
||||
if [ ! -f "$tmpfiles_path" ] ||
|
||||
! grep -Eq "^d[[:space:]]+$RUNTIME_DIR[[:space:]]+0750[[:space:]]+bongo[[:space:]]+bongo" "$tmpfiles_path"; then
|
||||
echo "$tmpfiles_path does not declare $RUNTIME_DIR correctly" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "PASS installed tmpfiles declaration owns $RUNTIME_DIR"
|
||||
|
||||
systemctl_cmd stop "$SERVICE"
|
||||
remaining=30
|
||||
while [ "$remaining" -gt 0 ]; do
|
||||
if ! /usr/bin/pgrep -x bongo-manager >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
remaining=$((remaining - 1))
|
||||
done
|
||||
if /usr/bin/pgrep -x bongo-manager >/dev/null 2>&1; then
|
||||
echo "$SERVICE did not stop cleanly" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo -n /usr/bin/rm -rf -- "$RUNTIME_DIR"
|
||||
if [ -e "$RUNTIME_DIR" ]; then
|
||||
echo "could not remove $RUNTIME_DIR before recreation test" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo -n /usr/bin/systemd-tmpfiles --create "$TMPFILES_NAME"
|
||||
|
||||
assert_path()
|
||||
{
|
||||
path=$1
|
||||
expected_mode=$2
|
||||
expected_owner=$3
|
||||
actual=$(sudo -n /usr/bin/stat -c '%a %U:%G' "$path")
|
||||
if [ "$actual" != "$expected_mode $expected_owner" ]; then
|
||||
echo "$path has $actual, expected $expected_mode $expected_owner" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_path "$RUNTIME_DIR" 750 bongo:bongo
|
||||
assert_path "$STATE_DIR" 750 bongo:bongo
|
||||
assert_path "$STATE_DIR/dbf" 750 bongo:bongo
|
||||
assert_path "$STATE_DIR/dbf/cookies" 700 bongo:bongo
|
||||
assert_path /etc/bongo/ssl.d 750 root:bongo
|
||||
echo "PASS tmpfiles recreated volatile and persistent directory ownership"
|
||||
|
||||
systemctl_cmd start "$SERVICE"
|
||||
remaining=30
|
||||
while [ "$remaining" -gt 0 ]; do
|
||||
if systemctl_cmd is-active "$SERVICE" >/dev/null 2>&1; then
|
||||
manager=$(systemctl_cmd show "$SERVICE" -p MainPID --value)
|
||||
if [ -n "$manager" ] && [ "$manager" -gt 1 ] 2>/dev/null &&
|
||||
runtime_pid_ready; then
|
||||
break
|
||||
fi
|
||||
fi
|
||||
sleep 1
|
||||
remaining=$((remaining - 1))
|
||||
done
|
||||
if ! systemctl_cmd is-active "$SERVICE" >/dev/null 2>&1 ||
|
||||
! runtime_pid_ready; then
|
||||
echo "$SERVICE did not create its runtime PID file after recreation" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap - EXIT HUP INT TERM
|
||||
echo "PASS manager PID $manager uses recreated $RUNTIME_DIR"
|
||||
echo "PASS runtime path lifecycle; service remains active"
|
||||
@@ -98,7 +98,7 @@ inputs and outputs is absent from the ZIP.
|
||||
| CFG-11 | DKIM/SPF/DMARC discovery, key import/generation, DNS hints, and task | [PASS](test-evidence/0.7-r1.md#cfg-11) | | |
|
||||
| CFG-12 | Manager start, reload, restart, clean stop, stale PID, and crash recovery | [PASS](test-evidence/0.7-r1.md#cfg-12) | | |
|
||||
| CFG-13 | Every agent starts as intended; permanent/effective privilege drops and supervisor exceptions are bounded | [PASS](test-evidence/0.7-r1.md#cfg-13) | | |
|
||||
| CFG-14 | tmpfiles creates runtime paths; package contains no runtime PID directories | | | |
|
||||
| CFG-14 | tmpfiles creates runtime paths; package contains no runtime PID directories | [PASS](test-evidence/0.7-r1.md#cfg-14) | | |
|
||||
| CFG-15 | systemd ordering, hardening, scanner timer, and worker scheduling | | | |
|
||||
| CFG-16 | Timezone cache rebuild uses the installed checked-in snapshot | | | |
|
||||
|
||||
|
||||
@@ -1231,3 +1231,49 @@ BONGO_ALLOW_LIVE_PRIVILEGE_TEST=1 \
|
||||
Runtime configuration: the installed Gentoo live package and existing
|
||||
disposable Bongo configuration were used. The check was read-only and did not
|
||||
alter process, configuration, mailbox, Queue, or credential state.
|
||||
|
||||
## CFG-14
|
||||
|
||||
Result: **PASS**
|
||||
|
||||
The Gentoo live package was rebuilt and reinstalled after overlay commit
|
||||
`0ee4d1e1`. The ebuild now passes the versioned Gentoo documentation path to
|
||||
CMake, so the installed documentation lives below
|
||||
`/usr/share/doc/bongo-9999`; the former unversioned
|
||||
`/usr/share/doc/bongo` staging path and its QA notice are gone. The installed
|
||||
package contains 1,436 paths, none below `/run` or `/var/run`, and no runtime
|
||||
PID file.
|
||||
|
||||
`contrib/testing/runtime-path-check.sh` then stopped Bongo cleanly, removed
|
||||
only the guarded volatile `/run/bongo` directory, and invoked the installed
|
||||
`bongo.conf` tmpfiles declaration. It recreated `/run/bongo`, the persistent
|
||||
state roots, and the TLS directory with the declared ownership and modes:
|
||||
|
||||
```text
|
||||
750 bongo:bongo /run/bongo
|
||||
750 bongo:bongo /var/lib/bongo
|
||||
750 bongo:bongo /var/lib/bongo/dbf
|
||||
700 bongo:bongo /var/lib/bongo/dbf/cookies
|
||||
750 root:bongo /etc/bongo/ssl.d
|
||||
```
|
||||
|
||||
After recreation the service started normally, placed its manager PID file
|
||||
below `/run/bongo`, and remained active/running as manager PID 1054117 with
|
||||
systemd result `success`.
|
||||
|
||||
```sh
|
||||
BONGO_ALLOW_LIVE_RUNTIME_TEST=1 \
|
||||
./contrib/testing/runtime-path-check.sh
|
||||
```
|
||||
|
||||
- Gentoo packaging source: overlay commit `0ee4d1e1`.
|
||||
- Complete rebuilt CTest result: 82 of 82 tests passed in 6.38 seconds.
|
||||
- Live result: package-image, tmpfiles declaration, directory recreation,
|
||||
ownership/mode, PID placement, and service recovery checks all passed.
|
||||
|
||||
Runtime configuration: the installed Gentoo live package and existing
|
||||
disposable Bongo configuration were used. The test intentionally removed only
|
||||
the volatile `/run/bongo` tree while the service was stopped, recreated it
|
||||
through systemd-tmpfiles, and left the service active. Persistent mail,
|
||||
configuration, Queue, credential, and certificate contents were not removed
|
||||
or modified.
|
||||
|
||||
Reference in New Issue
Block a user