server-monitor-manager/tests/bootstrap/test-bootstrap-contract.sh
Ochenstarik b897b0ea88 fix(bootstrap): compare release versions semantically against the installed one
The update guard compared the archive version with PROGRAM_VERSION using shell
string ordering. Both halves were wrong.

PROGRAM_VERSION is a constant describing the bootstrap source tree ("0.2.0-dev"),
never the deployed component, so it could not represent what is installed. The
cross-role compatibility check compared it with a manifest field such as
"v0.1.0-alpha.9"; those can never be equal, so update-control on a host that also
runs the agent always failed. The downgrade guard compared the same mismatched
pair and passed only by accident, because "v" sorts above "0" in ASCII.

String ordering is also wrong for the version scheme in use: "0.1.0-alpha.10"
sorts below "0.1.0-alpha.9", so the next release after the ninth would have been
rejected as a downgrade.

- record the installed version per role at install and update time, and compare
  against that instead of PROGRAM_VERSION;
- order versions with sort -V after stripping the leading "v", so prerelease
  numbering and tag prefixes compare correctly;
- treat an unknown peer version as a warning rather than a failure, because
  installations predating version recording have nothing to compare against;
- guard all of the above in the bootstrap contract test, including the six
  ordering cases and a check that the lexicographic comparison is not restored.

Verified by deliberately reintroducing each defect: lexicographic comparison,
sort without -V, and a missing version record are all caught by the contract test.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 01:05:22 +07:00

872 lines
42 KiB
Bash
Executable file

#!/usr/bin/env bash
set -Eeuo pipefail
IFS=$'\n\t'
root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)"
bootstrap="$root/deploy/ochenstarik-server-monitor-manager.sh"
helper="$root/deploy/ochenstarik-smm-policy-apply"
emergency="$root/deploy/ochenstarik-smm-emergency"
acceptance="$root/tests/acceptance/three-server-mesh.sh"
grep -Fq 'listing="$(/usr/sbin/nft -a list chain' "$helper" || {
printf '%s\n' "policy status probe must fail closed when nftables cannot be inspected" >&2
exit 1
}
grep -Fq "grep -Eiq 'No such file or directory|does not exist'" "$helper"
provisioning_helper_unit="$root/deploy/ochenstarik-smm-provisioning-helper.service"
grep -Fq 'EnvironmentFile=/etc/ochenstarik-server-monitor-manager/agent.env' "$provisioning_helper_unit"
grep -Fq 'ReadWritePaths=/var/lib/ochenstarik-server-monitor-manager/provisioning/rollback' "$provisioning_helper_unit"
grep -Fq 'install -d -m 0700 -o root -g root "$STATE_DIR/provisioning/rollback"' "$bootstrap"
if grep -Fq 'SMM_EnrollToken=$ENROLL_TOKEN' "$bootstrap"; then
printf '%s\n' "enrollment token is exposed through process argv" >&2
exit 1
fi
grep -Fq 'readonly ENROLLMENT_DIR="${STATE_DIR}-enrollment"' "$bootstrap"
grep -Fq 'install -d -m 0700 -o "$AGENT_USER" -g "$AGENT_USER" "$ENROLLMENT_DIR"' "$bootstrap"
grep -Fq 'token_temp="$(mktemp "$ENROLLMENT_DIR/.enroll-token.XXXXXXXX")"' "$bootstrap"
if grep -Fq '$STATE_DIR/enrollment' "$bootstrap"; then
printf '%s\n' "enrollment directory is beneath Control-writable state" >&2
exit 1
fi
grep -Fq 'chmod 0400 "$token_temp"' "$bootstrap"
grep -Fq 'mv -fT -- "$token_temp" "$token_file"' "$bootstrap"
grep -Fq '"SMM_EnrollTokenFile=$token_file"' "$bootstrap"
grep -Fq 'rm -f -- "$token_file"' "$bootstrap"
grep -Fq 'rm -f -- "$ENROLLMENT_TOKEN_FILE"' "$bootstrap"
grep -Fq 'rm -f -- "$ENROLLMENT_TOKEN_TEMP"' "$bootstrap"
grep -Fq 'SMM_AgentUid=$(id -u "$AGENT_USER")' "$bootstrap"
grep -Fq 'refresh_agent_uid() {' "$bootstrap"
grep -Fq 'agent_uid="$(id -u "$AGENT_USER")"' "$bootstrap"
grep -Fq "printf 'SMM_AgentUid=%s\\n' \"\$agent_uid\"" "$bootstrap"
grep -Fq ' refresh_agent_uid' "$bootstrap"
grep -Fq 'temp="$(mktemp "$ETC_DIR/.agent.env.XXXXXXXX")"' "$bootstrap"
grep -Fq 'mv -fT -- "$temp" "$env_file"' "$bootstrap"
refresh_line="$(grep -F -m1 -n ' refresh_agent_uid' "$bootstrap" | cut -d: -f1)"
stop_line="$(grep -F -m1 -n ' systemctl stop "$unit"' "$bootstrap" | cut -d: -f1)"
(( refresh_line < stop_line ))
help_output="$(bash "$bootstrap" --help)"
version_output="$(bash "$bootstrap" --version)"
grep -Fq "install-control ARCHIVE PUBLIC_HOST" <<<"$help_output"
grep -Fq "install-agent ARCHIVE NODE_ID CONTROL_URL CA_CERT" <<<"$help_output"
grep -Fq "install-node ARCHIVE" <<<"$help_output"
grep -Fq "mesh-init PUBLIC_ENDPOINT" <<<"$help_output"
grep -Fq "peer-add SMMPEER1_CODE" <<<"$help_output"
grep -Fq "mesh-status" <<<"$help_output"
grep -Fq "SMM_ENROLL_TOKEN" <<<"$help_output"
grep -Fq "node-code NODE_ID" <<<"$help_output"
grep -Fq "control-device-code DEVICE_ID" <<<"$help_output"
grep -Fq "verify-release ARCHIVE" <<<"$help_output"
grep -Fq "node-token NODE_ID" <<<"$help_output"
grep -Eq '^ochenstarik-server-monitor-manager [0-9]+\.[0-9]+\.[0-9]+-' <<<"$version_output"
extract_bootstrap_function() {
local name="$1"
awk -v signature="$name() {" '
$0 == signature { emitting = 1 }
emitting { print }
emitting && $0 == "}" { exit }
' "$bootstrap"
}
validate_port_definition="$(extract_bootstrap_function validate_port)"
validate_ipv4_literal_definition="$(extract_bootstrap_function validate_ipv4_literal)"
validate_control_url_definition="$(extract_bootstrap_function validate_control_url)"
for accepted_url in \
https://example.com \
https://host.example:7443 \
https://10.0.0.1:7443 \
'https://[2001:db8::1]:7443' \
'https://[::1]:7443' \
'https://[2001:db8::]' \
'https://[::]' \
'https://[::ffff:192.0.2.128]' \
'https://[2001:db8:3:4::192.0.2.33]:7443' \
'https://[1:2:3:4:5:6:192.0.2.1]' \
https://example.com/; do
if ! (fail() { exit 1; }; source <(printf '%s\n%s\n%s\n' "$validate_port_definition" "$validate_ipv4_literal_definition" "$validate_control_url_definition"); validate_control_url "$accepted_url"); then
printf 'valid Control URL was rejected: %s\n' "$accepted_url" >&2
exit 1
fi
done
for rejected_url in \
http://example.com \
https:// \
https://:7443 \
'https://[2001:db8::1' \
'https://[::::]' \
'https://[1:2:3]' \
'https://[::ffff:192.0.2.999]' \
'https://[::ffff:192.0.2]' \
'https://[::ffff:192.0.2.1.5]' \
'https://[::ffff:192.0.2.x]' \
'https://[1:2:3:4:5:6:7:192.0.2.1]' \
'https://[::ffff:192.0.2.1:]' \
'https://[1:2:3:4:5:6:192.0.2.1:]' \
'https://[1:2:3:4:5:6:7:8:]' \
'https://[:1:2:3:4:5:6:7]' \
'https://[::ffff:18446744073709551617.0.0.1]' \
'https://[::1]:18446744073709551696' \
'https://2001:db8::1:7443' \
'https://example.com:7443:7444' \
https://example..com \
https://999.0.0.1 \
https://18446744073709551617.0.0.1 \
https://example.com/path \
https://user@example.com \
'https://example.com:0' \
'https://example.com:65536' \
'https://example.com:18446744073709551696' \
'https://example.com?query=1' \
'https://example.com#fragment'; do
if (fail() { exit 1; }; source <(printf '%s\n%s\n%s\n' "$validate_port_definition" "$validate_ipv4_literal_definition" "$validate_control_url_definition"); validate_control_url "$rejected_url"); then
printf 'invalid Control URL was accepted: %s\n' "$rejected_url" >&2
exit 1
fi
done
for action in status version --version preflight help -h --help; do
if bash "$bootstrap" "$action" surplus >/dev/null 2>&1; then
printf 'bootstrap action accepted surplus arguments: %s\n' "$action" >&2
exit 1
fi
done
if ! bash "$bootstrap" >/dev/null 2>&1; then
printf '%s\n' 'bootstrap no-argument help form failed' >&2
exit 1
fi
for action in verify-release install-control install-agent install-node mesh-init peer-add \
update-control update-agent rollback node-code control-device-code node-token uninstall-control; do
if bash "$bootstrap" "$action" >/dev/null 2>&1; then
printf 'bootstrap action accepted missing arguments: %s\n' "$action" >&2
exit 1
fi
done
base64url_encode_definition="$(extract_bootstrap_function base64url_encode)"
create_device_code_definition="$(extract_bootstrap_function create_device_code)"
device_fixture="$(mktemp -d -t smm-device-code.XXXXXXXX)"
printf '%s\n' 'https://control.example:7443' >"$device_fixture/control-public-url"
printf '%s\n' 'fixture-ca' >"$device_fixture/control-ca.crt"
device_code="$(
ETC_DIR="$device_fixture"
require_root() { :; }
require_command() { :; }
validate_node_id() { [[ "$1" == 'desktop-device' ]]; }
validate_control_url() { [[ "$1" == 'https://control.example:7443' ]]; }
run_control_cli() {
[[ "$1" == 'device-token-create' && "$2" == 'desktop-device' ]]
printf '%043d\n' 0
}
openssl() { printf '%s' 'DER-fixture'; }
source <(printf '%s\n%s\n' "$base64url_encode_definition" "$create_device_code_definition")
create_device_code desktop-device
)"
[[ "$device_code" == SMMDEV1-* ]]
device_payload_encoded="${device_code#SMMDEV1-}"
device_payload_encoded="${device_payload_encoded//-/+}"
device_payload_encoded="${device_payload_encoded//_/\/}"
case $(( ${#device_payload_encoded} % 4 )) in
0) ;;
2) device_payload_encoded+='==' ;;
3) device_payload_encoded+='=' ;;
*) printf '%s\n' 'invalid generated SMMDEV1 base64url length' >&2; exit 1 ;;
esac
device_payload="$(printf '%s' "$device_payload_encoded" | base64 -d)"
grep -Fxq 'VERSION=1' <<<"$device_payload"
grep -Fxq 'DEVICE=desktop-device' <<<"$device_payload"
grep -Fxq 'TOKEN=0000000000000000000000000000000000000000000' <<<"$device_payload"
grep -Fxq 'URL=https://control.example:7443' <<<"$device_payload"
grep -Fxq "CA=$(printf '%s' 'DER-fixture' | base64 -w 0)" <<<"$device_payload"
rm -rf -- "$device_fixture"
grep -Fq 'readonly BOOTSTRAP_COMMAND="/usr/local/sbin/ochenstarik-server-monitor-manager.sh"' "$bootstrap"
grep -Fq 'staging="$(mktemp "$(dirname "$BOOTSTRAP_COMMAND")/.ochenstarik-server-monitor-manager.XXXXXXXX")"' "$bootstrap"
grep -Fq 'mv -fT -- "$staging" "$BOOTSTRAP_COMMAND"' "$bootstrap"
[[ "$(grep -Fc ' install_bootstrap_command' "$bootstrap")" -eq 3 ]]
update_role_definition="$(extract_bootstrap_function update_role)"
validation_line="$(grep -n -m1 'validate_control_state_migration' <<<"$update_role_definition" | cut -d: -f1)"
environment_validation_line="$(grep -n -m1 'validate_control_environment_migration' <<<"$update_role_definition" | cut -d: -f1)"
control_stop_line="$(grep -n -m1 'systemctl stop \"\$unit\"' <<<"$update_role_definition" | cut -d: -f1)"
(( validation_line < control_stop_line && environment_validation_line < control_stop_line ))
guard_arm_line="$(grep -n -m1 'CONTROL_UPDATE_RECOVERY_REQUIRED=1' <<<"$update_role_definition" | cut -d: -f1)"
guard_clear_line="$(grep -n -m1 'CONTROL_UPDATE_RECOVERY_REQUIRED=0' <<<"$update_role_definition" | cut -d: -f1)"
prepare_line="$(grep -n -m1 'prepare_control_state' <<<"$update_role_definition" | cut -d: -f1)"
rewrite_line="$(grep -n -m1 'rewrite_control_environment' <<<"$update_role_definition" | cut -d: -f1)"
bootstrap_line="$(grep -n -m1 'install_bootstrap_command' <<<"$update_role_definition" | cut -d: -f1)"
unit_line="$(grep -n -m1 'install_unit \"\$TEMP_DIR/deploy/\$CONTROL_UNIT\"' <<<"$update_role_definition" | cut -d: -f1)"
enable_line="$(grep -n -m1 'systemctl enable \"\$CONTROL_UNIT\"' <<<"$update_role_definition" | cut -d: -f1)"
binary_line="$(grep -n -m1 'install_tree_atomic \"\$TEMP_DIR/control\"' <<<"$update_role_definition" | cut -d: -f1)"
restart_line="$(grep -n -m1 'systemctl restart \"\$unit\"' <<<"$update_role_definition" | cut -d: -f1)"
active_line="$(grep -n -m1 'systemctl is-active --quiet \"\$unit\"' <<<"$update_role_definition" | cut -d: -f1)"
for guarded_line in "$control_stop_line" "$prepare_line" "$rewrite_line" "$bootstrap_line" \
"$unit_line" "$enable_line" "$binary_line" "$restart_line" "$active_line"; do
(( guard_arm_line < guarded_line && guarded_line < guard_clear_line ))
done
grep -Fq 'install_bootstrap_command' <<<"$update_role_definition"
grep -Fq 'install_unit "$TEMP_DIR/deploy/$CONTROL_UNIT" "$CONTROL_UNIT"' <<<"$update_role_definition"
grep -Fq 'install_tree_atomic "$TEMP_DIR/control" "$LIB_DIR/control" "$user"' <<<"$update_role_definition"
grep -Fq 'systemctl restart "$unit"' <<<"$update_role_definition"
grep -Fq 'systemctl is-active --quiet "$unit"' <<<"$update_role_definition"
grep -Fq 'install -d -m 0711 -o root -g root "$ETC_DIR" "$STATE_DIR"' "$bootstrap"
grep -Fq 'install -d -m 0700 -o "$CONTROL_USER" -g "$CONTROL_USER" "$STATE_DIR/control"' "$bootstrap"
grep -Fq 'Control__DatabasePath=$STATE_DIR/control/control.db' "$bootstrap"
grep -Fq 'Control__BackupDirectory=$STATE_DIR/control/backups' "$bootstrap"
validate_control_state_migration_definition="$(extract_bootstrap_function validate_control_state_migration)"
prepare_control_state_definition="$(extract_bootstrap_function prepare_control_state)"
control_state_fixture="$(mktemp -d -t smm-control-state.XXXXXXXX)"
mkdir -p "$control_state_fixture/backups"
printf '%s' database >"$control_state_fixture/control.db"
printf '%s' wal >"$control_state_fixture/control.db-wal"
printf '%s' backup >"$control_state_fixture/backups/manifest.json"
(
STATE_DIR="$control_state_fixture"
CONTROL_USER=fixture
fail() { printf '%s\n' "$*" >&2; exit 1; }
install() {
local arguments=()
while (( $# > 0 )); do
case "$1" in
-m|-o|-g) shift 2 ;;
*) arguments+=("$1"); shift ;;
esac
done
command install "${arguments[@]}"
}
chown() { :; }
source <(printf '%s\n%s\n' "$validate_control_state_migration_definition" "$prepare_control_state_definition")
validate_control_state_migration
prepare_control_state
)
[[ ! -e "$control_state_fixture/control.db" ]]
[[ "$(<"$control_state_fixture/control/control.db")" == database ]]
[[ "$(<"$control_state_fixture/control/control.db-wal")" == wal ]]
[[ "$(<"$control_state_fixture/control/backups/manifest.json")" == backup ]]
if [[ "$(uname -s)" != MINGW* ]]; then
[[ "$(stat -c '%a' "$control_state_fixture/control")" == 700 ]]
[[ "$(stat -c '%a' "$control_state_fixture/control/control.db")" == 600 ]]
fi
printf '%s' conflict >"$control_state_fixture/control.db"
if (
STATE_DIR="$control_state_fixture"
fail() { exit 1; }
source <(printf '%s\n' "$validate_control_state_migration_definition")
validate_control_state_migration
); then
printf '%s\n' 'conflicting legacy and role-isolated Control state was accepted' >&2
exit 1
fi
rm -rf -- "$control_state_fixture"
validate_control_environment_migration_definition="$(extract_bootstrap_function validate_control_environment_migration)"
rewrite_control_environment_definition="$(extract_bootstrap_function rewrite_control_environment)"
alpha7_fixture="$(mktemp -d -t smm-alpha7-update.XXXXXXXX)"
mkdir -p "$alpha7_fixture/state/backups" "$alpha7_fixture/etc"
printf '%s' alpha7-db >"$alpha7_fixture/state/control.db"
printf '%s' alpha7-wal >"$alpha7_fixture/state/control.db-wal"
printf '%s' alpha7-shm >"$alpha7_fixture/state/control.db-shm"
printf '%s' alpha7-backup >"$alpha7_fixture/state/backups/manifest.json"
cat >"$alpha7_fixture/etc/control.env" <<EOF
# alpha.7 fixture: preserve comments and every unrelated value
ASPNETCORE_URLS=https://0.0.0.0:7443
Control__DatabasePath=$alpha7_fixture/state/control.db
Control__CertificateAuthorityPath=/custom/control-ca.pfx
Control__BackupDirectory=$alpha7_fixture/state/backups
Control__LinkReconciliationSeconds=777
CUSTOM_VALUE=spaces are preserved exactly
EOF
cp "$alpha7_fixture/etc/control.env" "$alpha7_fixture/original.env"
(
STATE_DIR="$alpha7_fixture/state"
ETC_DIR="$alpha7_fixture/etc"
CONTROL_USER=fixture
fail() { printf '%s\n' "$*" >&2; exit 1; }
install() {
local arguments=()
while (( $# > 0 )); do
case "$1" in -m|-o|-g) shift 2 ;; *) arguments+=("$1"); shift ;; esac
done
command install "${arguments[@]}"
}
chown() { :; }
source <(printf '%s\n%s\n%s\n%s\n' \
"$validate_control_state_migration_definition" \
"$prepare_control_state_definition" \
"$validate_control_environment_migration_definition" \
"$rewrite_control_environment_definition")
validate_control_state_migration
validate_control_environment_migration
prepare_control_state
rewrite_control_environment
)
[[ "$(<"$alpha7_fixture/state/control/control.db")" == alpha7-db ]]
[[ "$(<"$alpha7_fixture/state/control/control.db-wal")" == alpha7-wal ]]
[[ "$(<"$alpha7_fixture/state/control/control.db-shm")" == alpha7-shm ]]
[[ "$(<"$alpha7_fixture/state/control/backups/manifest.json")" == alpha7-backup ]]
expected_env="$(sed \
-e "s|^Control__DatabasePath=.*|Control__DatabasePath=$alpha7_fixture/state/control/control.db|" \
-e "s|^Control__BackupDirectory=.*|Control__BackupDirectory=$alpha7_fixture/state/control/backups|" \
"$alpha7_fixture/original.env")"
[[ "$(<"$alpha7_fixture/etc/control.env")" == "$expected_env" ]]
printf '%s\n' "Control__DatabasePath=$alpha7_fixture/state/control/control.db" \
>>"$alpha7_fixture/etc/control.env"
if (
ETC_DIR="$alpha7_fixture/etc"
fail() { exit 1; }
source <(printf '%s\n' "$validate_control_environment_migration_definition")
validate_control_environment_migration
); then
printf '%s\n' 'conflicting Control environment paths were accepted' >&2
exit 1
fi
rm -rf -- "$alpha7_fixture"
record_control_legacy_state_definition="$(extract_bootstrap_function record_control_legacy_state)"
reverse_control_state_migration_definition="$(extract_bootstrap_function reverse_control_state_migration)"
restore_control_update_backup_definition="$(extract_bootstrap_function restore_control_update_backup)"
restore_control_binary_from_archive_definition="$(extract_bootstrap_function restore_control_binary_from_archive)"
recover_control_update_definition="$(extract_bootstrap_function recover_control_update)"
[[ -n "$record_control_legacy_state_definition" ]]
[[ -n "$reverse_control_state_migration_definition" ]]
[[ -n "$restore_control_update_backup_definition" ]]
[[ -n "$restore_control_binary_from_archive_definition" ]]
[[ -n "$recover_control_update_definition" ]]
recovery_fixture="$(mktemp -d -t smm-control-recovery.XXXXXXXX)"
recovery_root="$recovery_fixture/root"
archive_root="$recovery_fixture/archive-root"
mkdir -p \
"$recovery_root/var/lib/ochenstarik-server-monitor-manager/backups" \
"$recovery_root/etc/ochenstarik-server-monitor-manager" \
"$recovery_root/etc/systemd/system" \
"$recovery_root/usr/local/lib/ochenstarik-server-monitor-manager/control" \
"$archive_root/etc/ochenstarik-server-monitor-manager" \
"$archive_root/etc/systemd/system" \
"$archive_root/usr/local/lib/ochenstarik-server-monitor-manager/control"
printf '%s' original-db >"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db"
printf '%s' original-wal >"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db-wal"
printf '%s' original-shm >"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db-shm"
printf '%s' original-backup >"$recovery_root/var/lib/ochenstarik-server-monitor-manager/backups/identity"
printf '%s' old-binary >"$archive_root/usr/local/lib/ochenstarik-server-monitor-manager/control/ochenstarik-smm-control"
printf '%s\n' 'Control__DatabasePath=/var/lib/ochenstarik-server-monitor-manager/control.db' \
>"$archive_root/etc/ochenstarik-server-monitor-manager/control.env"
printf '%s' old-unit >"$archive_root/etc/systemd/system/ochenstarik-smm-control.service"
mkdir -p "$recovery_fixture/bootstrap-backups"
tar -C "$archive_root" -czf "$recovery_fixture/bootstrap-backups/alpha7.tar.gz" \
usr/local/lib/ochenstarik-server-monitor-manager/control \
etc/ochenstarik-server-monitor-manager/control.env \
etc/systemd/system/ochenstarik-smm-control.service
(
STATE_DIR="$recovery_root/var/lib/ochenstarik-server-monitor-manager"
CONTROL_USER=fixture
CONTROL_UPDATE_LEGACY_ITEMS=()
fail() { printf '%s\n' "$*" >&2; exit 1; }
install() {
local arguments=()
while (( $# > 0 )); do
case "$1" in -m|-o|-g) shift 2 ;; *) arguments+=("$1"); shift ;; esac
done
command install "${arguments[@]}"
}
chown() { :; }
source <(printf '%s\n%s\n%s\n' \
"$record_control_legacy_state_definition" \
"$prepare_control_state_definition" \
"$reverse_control_state_migration_definition")
record_control_legacy_state
prepare_control_state
[[ "$(<"$STATE_DIR/control/control.db")" == original-db ]]
reverse_control_state_migration
[[ "$(<"$STATE_DIR/control.db")" == original-db ]]
[[ "$(<"$STATE_DIR/control.db-wal")" == original-wal ]]
[[ "$(<"$STATE_DIR/control.db-shm")" == original-shm ]]
[[ "$(<"$STATE_DIR/backups/identity")" == original-backup ]]
[[ ! -e "$STATE_DIR/control/control.db" ]]
)
printf '%s' new-binary >"$recovery_root/usr/local/lib/ochenstarik-server-monitor-manager/control/ochenstarik-smm-control"
printf '%s\n' 'Control__DatabasePath=/var/lib/ochenstarik-server-monitor-manager/control/control.db' \
>"$recovery_root/etc/ochenstarik-server-monitor-manager/control.env"
printf '%s' new-unit >"$recovery_root/etc/systemd/system/ochenstarik-smm-control.service"
(
STATE_DIR="$recovery_root/var/lib/ochenstarik-server-monitor-manager"
BACKUP_DIR="$recovery_fixture/bootstrap-backups"
CONTROL_UNIT=ochenstarik-smm-control.service
CONTROL_UPDATE_LEGACY_ITEMS=()
systemctl() { :; }
fail() { printf '%s\n' "$*" >&2; exit 1; }
source <(printf '%s\n%s\n%s\n%s\n' \
"$reverse_control_state_migration_definition" \
"$restore_control_update_backup_definition" \
"$restore_control_binary_from_archive_definition" \
"$recover_control_update_definition")
restore_control_binary_from_archive "$BACKUP_DIR/alpha7.tar.gz" "$recovery_root"
[[ "$(<"$recovery_root/usr/local/lib/ochenstarik-server-monitor-manager/control/ochenstarik-smm-control")" == old-binary ]]
[[ "$(<"$recovery_root/etc/ochenstarik-server-monitor-manager/control.env")" == \
'Control__DatabasePath=/var/lib/ochenstarik-server-monitor-manager/control/control.db' ]]
)
rm -rf -- "$recovery_root/var/lib/ochenstarik-server-monitor-manager/control"
mkdir -p "$recovery_root/var/lib/ochenstarik-server-monitor-manager/control/backups"
mv "$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db" \
"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control/control.db"
mv "$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db-wal" \
"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control/control.db-wal"
mv "$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db-shm" \
"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control/control.db-shm"
mv "$recovery_root/var/lib/ochenstarik-server-monitor-manager/backups/identity" \
"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control/backups/identity"
rmdir "$recovery_root/var/lib/ochenstarik-server-monitor-manager/backups"
printf '%s' new-binary >"$recovery_root/usr/local/lib/ochenstarik-server-monitor-manager/control/ochenstarik-smm-control"
printf '%s\n' 'Control__DatabasePath=/var/lib/ochenstarik-server-monitor-manager/control/control.db' \
>"$recovery_root/etc/ochenstarik-server-monitor-manager/control.env"
printf '%s' new-unit >"$recovery_root/etc/systemd/system/ochenstarik-smm-control.service"
(
STATE_DIR="$recovery_root/var/lib/ochenstarik-server-monitor-manager"
BACKUP_DIR="$recovery_fixture/bootstrap-backups"
CONTROL_UNIT=ochenstarik-smm-control.service
CONTROL_UPDATE_LEGACY_ITEMS=(control.db control.db-wal control.db-shm backups)
systemctl() { :; }
fail() { printf '%s\n' "$*" >&2; exit 1; }
source <(printf '%s\n%s\n%s\n' \
"$reverse_control_state_migration_definition" \
"$restore_control_update_backup_definition" \
"$recover_control_update_definition")
recover_control_update alpha7 "$recovery_root"
)
[[ "$(<"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db")" == original-db ]]
[[ "$(<"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db-wal")" == original-wal ]]
[[ "$(<"$recovery_root/var/lib/ochenstarik-server-monitor-manager/control.db-shm")" == original-shm ]]
[[ "$(<"$recovery_root/var/lib/ochenstarik-server-monitor-manager/backups/identity")" == original-backup ]]
[[ "$(<"$recovery_root/usr/local/lib/ochenstarik-server-monitor-manager/control/ochenstarik-smm-control")" == old-binary ]]
[[ "$(<"$recovery_root/etc/ochenstarik-server-monitor-manager/control.env")" == \
'Control__DatabasePath=/var/lib/ochenstarik-server-monitor-manager/control.db' ]]
[[ "$(<"$recovery_root/etc/systemd/system/ochenstarik-smm-control.service")" == old-unit ]]
rm -rf -- "$recovery_fixture"
cleanup_definition="$(extract_bootstrap_function cleanup)"
[[ -n "$cleanup_definition" ]]
for failure_step in stop state environment bootstrap unit enable binary restart active; do
guard_fixture="$(mktemp -d -t smm-control-guard.XXXXXXXX)"
marker="$guard_fixture.recovered"
set +e
(
set -Eeuo pipefail
PROGRAM=test-bootstrap
TEMP_DIR="$guard_fixture"
ENROLLMENT_TOKEN_FILE=""
ENROLLMENT_TOKEN_TEMP=""
CONTROL_UPDATE_BACKUP_ID=fixture-backup
CONTROL_UPDATE_RECOVERY_REQUIRED=1
marker="$marker"
failure_step="$failure_step"
log() { :; }
recover_control_update() { printf '%s' "$failure_step" >"$marker"; }
source <(printf '%s\n' "$cleanup_definition")
trap cleanup EXIT
false
) >/dev/null 2>&1
guard_status=$?
set -e
(( guard_status != 0 )) || {
printf 'injected Control update failure was ignored: %s\n' "$failure_step" >&2
exit 1
}
[[ -f "$marker" && "$(<"$marker")" == "$failure_step" ]] || {
printf 'Control recovery guard was not invoked for: %s\n' "$failure_step" >&2
exit 1
}
rm -f -- "$marker"
done
role_is_installed_definition="$(extract_bootstrap_function role_is_installed)"
remove_shared_ca_if_unused_definition="$(extract_bootstrap_function remove_shared_ca_if_unused)"
uninstall_agent_definition="$(extract_bootstrap_function uninstall_agent)"
uninstall_control_definition="$(extract_bootstrap_function uninstall_control)"
grep -Fq 'remove_shared_ca_if_unused' <<<"$uninstall_agent_definition"
grep -Fq 'remove_shared_ca_if_unused' <<<"$uninstall_control_definition"
if grep -Fq 'control-ca.crt' <<<"$uninstall_agent_definition$uninstall_control_definition"; then
printf '%s\n' 'a role uninstaller deletes the shared CA directly' >&2
exit 1
fi
role_fixture="$(mktemp -d -t smm-role-uninstall.XXXXXXXX)"
mkdir -p "$role_fixture/etc" "$role_fixture/lib/control" "$role_fixture/lib/agent"
printf '%s' ca >"$role_fixture/etc/control-ca.crt"
(
ETC_DIR="$role_fixture/etc"; LIB_DIR="$role_fixture/lib"
source <(printf '%s\n%s\n' "$role_is_installed_definition" "$remove_shared_ca_if_unused_definition")
rm -rf "$LIB_DIR/agent"
remove_shared_ca_if_unused
)
[[ -f "$role_fixture/etc/control-ca.crt" ]]
rm -rf "$role_fixture/lib/control"
(
ETC_DIR="$role_fixture/etc"; LIB_DIR="$role_fixture/lib"
source <(printf '%s\n%s\n' "$role_is_installed_definition" "$remove_shared_ca_if_unused_definition")
remove_shared_ca_if_unused
)
[[ ! -e "$role_fixture/etc/control-ca.crt" ]]
mkdir -p "$role_fixture/lib/control" "$role_fixture/lib/agent"
printf '%s' ca >"$role_fixture/etc/control-ca.crt"
(
ETC_DIR="$role_fixture/etc"; LIB_DIR="$role_fixture/lib"
source <(printf '%s\n%s\n' "$role_is_installed_definition" "$remove_shared_ca_if_unused_definition")
rm -rf "$LIB_DIR/control"
remove_shared_ca_if_unused
)
[[ -f "$role_fixture/etc/control-ca.crt" ]]
rm -rf "$role_fixture/lib/agent"
(
ETC_DIR="$role_fixture/etc"; LIB_DIR="$role_fixture/lib"
source <(printf '%s\n%s\n' "$role_is_installed_definition" "$remove_shared_ca_if_unused_definition")
remove_shared_ca_if_unused
)
[[ ! -e "$role_fixture/etc/control-ca.crt" ]]
rm -rf -- "$role_fixture"
grep -Fq 'UMask=0077' "$root/deploy/ochenstarik-smm-control.service"
grep -Fq 'ReadWritePaths=/var/lib/ochenstarik-server-monitor-manager/control' "$root/deploy/ochenstarik-smm-control.service"
native_smoke="$root/tests/bootstrap/run-native-systemd-smoke.sh"
grep -Fq 'node_code="$(sudo "$system_bootstrap" node-code smoke-node)"' "$native_smoke"
grep -Fq 'export SMM_ENROLL_CODE="$node_code"' "$native_smoke"
grep -Fq 'export SMM_ACCEPT_CA_FINGERPRINT=1' "$native_smoke"
grep -Fq 'sudo test -s /var/lib/ochenstarik-server-monitor-manager/agent/agent.pfx' "$native_smoke"
grep -Fq 'sudo systemctl is-active --quiet ochenstarik-smm-agent.service' "$native_smoke"
grep -Fq 'device_code="$(sudo "$system_bootstrap" control-device-code smoke-device)"' "$native_smoke"
grep -Fq '[[ "$device_code" == SMMDEV1-* ]]' "$native_smoke"
grep -Fq 'sudo --preserve-env=SMM_ENROLL_CODE,SMM_ACCEPT_CA_FINGERPRINT' "$native_smoke"
if grep -Fq 'sudo env SMM_ENROLL_CODE=' "$native_smoke"; then
printf '%s\n' 'native smoke exposes the enrollment code through env argv' >&2
exit 1
fi
grep -Fq 'rm -rf -- "$LIB_DIR/control" "$STATE_DIR/control"' "$bootstrap"
if grep -Fq 'install -d -m 0750 -o root -g "$AGENT_USER" "$ETC_DIR"' "$bootstrap"; then
printf '%s\n' 'Agent installation still takes ownership of the shared configuration parent' >&2
exit 1
fi
emergency_help="$(bash "$emergency" --help)"
grep -Fq 'mesh-disable' <<<"$emergency_help"
grep -Fq 'firewall-restore' <<<"$emergency_help"
grep -Fq 'readonly RECONCILE_MARKER="$STATE_DIR/mesh/reconcile-requested"' "$emergency"
grep -Fq 'chown root:root "$temporary_marker"' "$emergency"
grep -Fq 'chmod 0600 "$temporary_marker"' "$emergency"
grep -Fq 'mv -f -- "$temporary_marker" "$RECONCILE_MARKER"' "$emergency"
grep -Fq '/usr/bin/flock -x 9' "$emergency"
grep -Fq 'generation="$(</proc/sys/kernel/random/uuid)"' "$emergency"
[[ "$(grep -Fc ' request_reconciliation' "$emergency")" -ge 2 ]]
if bash "$bootstrap" unsupported-action >/dev/null 2>&1; then
printf '%s\n' "unsupported bootstrap action unexpectedly succeeded" >&2
exit 1
fi
if env -u SUDO_UID -u SUDO_USER bash "$helper" link-connect source target tcp 22 10 >/dev/null 2>&1; then
printf '%s\n' "policy helper unexpectedly applied an unconfigured rule" >&2
exit 1
fi
if bash "$emergency" mesh-disable >/dev/null 2>&1; then
printf '%s\n' "emergency mutation unexpectedly succeeded without root" >&2
exit 1
fi
policy_state="$(mktemp -t smm-policy-state.XXXXXXXX)"
printf 'source\t10.77.0.2\tkey-source\tactive\n' >"$policy_state"
printf 'target\t10.77.0.3\tkey-target\tactive\n' >>"$policy_state"
connect_output="$(SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$policy_state" \
bash "$helper" link-connect source target tcp 22 10)"
grep -Fq 'ip saddr 10.77.0.2 ip daddr 10.77.0.3 tcp dport 22' <<<"$connect_output"
grep -Fq 'smm:source:target:tcp:22' <<<"$connect_output"
disconnect_output="$(SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$policy_state" \
bash "$helper" link-disconnect source target tcp 22)"
grep -Fq 'smm:source:target:tcp:22' <<<"$disconnect_output"
status_output="$(SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$policy_state" \
bash "$helper" link-status source target tcp 22)"
[[ "$status_output" == 'disabled' ]] || {
printf '%s\n' "policy helper returned an invalid factual status" >&2
exit 1
}
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$policy_state" \
bash "$helper" link-status source target tcp 22 unexpected >/dev/null 2>&1; then
printf '%s\n' "policy helper unexpectedly accepted extra link-status arguments" >&2
exit 1
fi
policy_listing="$(mktemp -t smm-policy-listing.XXXXXXXX)"
cat >"$policy_listing" <<'EOF'
ip saddr 10.77.0.2 ip daddr 10.77.0.3 tcp dport 22 counter accept comment "smm:source:target:tcp:22" # handle 5
counter accept comment "foreign:keep-me" # handle 6
counter accept comment "smm:source:target:tcp:22" # handle 7
counter accept comment "smm:FORGED:target:tcp:22" # handle 8
EOF
list_error="$(mktemp -t smm-policy-list-error.XXXXXXXX)"
list_output="$(SMM_POLICY_TESTING=1 SMM_POLICY_LISTING_FILE="$policy_listing" \
bash "$helper" link-list 2>"$list_error")"
[[ "$list_output" == $'source\ttarget\ttcp\t22\nsource\ttarget\ttcp\t22' ]]
if grep -Fq 'foreign:keep-me' <<<"$list_output"; then
printf '%s\n' "policy helper exposed a foreign nftables comment" >&2
exit 1
fi
grep -Fq 'forged managed comment ignored' "$list_error"
empty_listing="$(mktemp -t smm-policy-empty-listing.XXXXXXXX)"
empty_list_output="$(SMM_POLICY_TESTING=1 SMM_POLICY_LISTING_FILE="$empty_listing" \
bash "$helper" link-list)"
[[ -z "$empty_list_output" ]]
if SMM_POLICY_TESTING=1 SMM_POLICY_FIREWALL_UNAVAILABLE=1 \
bash "$helper" link-list >/dev/null 2>"$list_error"; then
printf '%s\n' "missing Link policy table unexpectedly produced a listing" >&2
exit 1
else
[[ $? -eq 79 ]]
fi
[[ "$(<"$list_error")" == 'mesh.firewall-unavailable' ]]
if SMM_POLICY_TESTING=1 bash "$helper" link-list unexpected >/dev/null 2>&1; then
printf '%s\n' "policy helper unexpectedly accepted extra link-list arguments" >&2
exit 1
fi
inactive_state="$(mktemp -t smm-policy-inactive-state.XXXXXXXX)"
printf 'source\t10.77.0.2\tkey-source\tactive\n' >"$inactive_state"
printf 'target\t10.77.0.3\t-\treserved\n' >>"$inactive_state"
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$inactive_state" \
bash "$helper" link-connect source target tcp 22 10 >/dev/null 2>"$list_error"; then
printf '%s\n' "policy helper unexpectedly activated a Link to a reserved Node" >&2
exit 1
else
[[ $? -eq 80 ]]
fi
[[ "$(<"$list_error")" == 'mesh.node-not-activated' ]]
printf 'source\t10.77.0.2\tkey-source\tactive\n' >"$inactive_state"
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$inactive_state" \
bash "$helper" link-connect source target tcp 22 10 >/dev/null 2>"$list_error"; then
printf '%s\n' "policy helper unexpectedly activated a Link to a missing Node" >&2
exit 1
else
[[ $? -eq 80 ]]
fi
[[ "$(<"$list_error")" == 'mesh.node-not-activated' ]]
printf 'source\t10.77.0.2\tkey-source\tactive\n' >"$inactive_state"
printf 'target\t\tkey-target\tactive\n' >>"$inactive_state"
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$inactive_state" \
bash "$helper" link-connect source target tcp 22 10 >/dev/null 2>"$list_error"; then
printf '%s\n' "policy helper unexpectedly accepted a blank Node address" >&2
exit 1
else
[[ $? -eq 78 ]]
fi
[[ "$(<"$list_error")" == 'policy helper: node has no valid mesh address: target' ]]
printf 'source\t10.77.0.2\tkey-source\tactive\n' >"$inactive_state"
printf 'target\tnot-an-ip\tkey-target\tactive\n' >>"$inactive_state"
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$inactive_state" \
bash "$helper" link-connect source target tcp 22 10 >/dev/null 2>"$list_error"; then
printf '%s\n' "policy helper unexpectedly accepted an invalid Node address" >&2
exit 1
else
[[ $? -eq 78 ]]
fi
[[ "$(<"$list_error")" == 'policy helper: node has no valid mesh address: target' ]]
printf 'source\t10.77.0.2\tkey-source\tactive\n' >"$inactive_state"
printf 'target\t999.77.0.3\tkey-target\tactive\n' >>"$inactive_state"
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$inactive_state" \
bash "$helper" link-connect source target tcp 22 10 >/dev/null 2>"$list_error"; then
printf '%s\n' "policy helper unexpectedly accepted an out-of-range Node address" >&2
exit 1
else
[[ $? -eq 78 ]]
fi
[[ "$(<"$list_error")" == 'policy helper: node has no valid mesh address: target' ]]
printf 'source\t10.77.0.2\tkey-source\tactive\n' >"$inactive_state"
printf 'target\t10.77.0.3\tkey-target\tgarbage!\n' >>"$inactive_state"
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$inactive_state" \
bash "$helper" link-connect source target tcp 22 10 >/dev/null 2>"$list_error"; then
printf '%s\n' "policy helper unexpectedly accepted a malformed Node status" >&2
exit 1
else
[[ $? -eq 78 ]]
fi
[[ "$(<"$list_error")" == 'policy helper: invalid mesh node status: target' ]]
generation_a='aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa'
generation_b='bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb'
reconcile_marker="$(mktemp -t smm-reconcile-marker.XXXXXXXX)"
printf '%s\n' "$generation_a" >"$reconcile_marker"
[[ "$(SMM_POLICY_TESTING=1 SMM_POLICY_FLOCK=true SMM_POLICY_RECONCILE_MARKER="$reconcile_marker" \
bash "$helper" reconcile-status)" == "requested:$generation_a" ]]
printf '%s\n' "$generation_b" >"$reconcile_marker"
SMM_POLICY_TESTING=1 SMM_POLICY_FLOCK=true SMM_POLICY_RECONCILE_MARKER="$reconcile_marker" \
bash "$helper" reconcile-complete "$generation_a" >/dev/null
[[ "$(<"$reconcile_marker")" == "$generation_b" ]]
SMM_POLICY_TESTING=1 SMM_POLICY_FLOCK=true SMM_POLICY_RECONCILE_MARKER="$reconcile_marker" \
bash "$helper" reconcile-complete "$generation_b" >/dev/null
[[ ! -e "$reconcile_marker" ]]
[[ "$(SMM_POLICY_TESTING=1 SMM_POLICY_FLOCK=true SMM_POLICY_RECONCILE_MARKER="$reconcile_marker" \
bash "$helper" reconcile-status)" == 'complete' ]]
missing_mesh="$reconcile_marker-missing/mesh/reconcile-requested"
[[ "$(SMM_POLICY_TESTING=1 SMM_POLICY_FLOCK=true SMM_POLICY_RECONCILE_MARKER="$missing_mesh" \
bash "$helper" reconcile-status)" == 'complete' ]]
if SMM_POLICY_TESTING=1 SMM_POLICY_FLOCK=true SMM_POLICY_RECONCILE_MARKER="$reconcile_marker" \
bash "$helper" reconcile-complete unexpected extra >/dev/null 2>&1; then
printf '%s\n' "policy helper unexpectedly accepted extra reconcile-complete arguments" >&2
exit 1
fi
firewall_error="$(mktemp -t smm-firewall-error.XXXXXXXX)"
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$policy_state" \
SMM_POLICY_FIREWALL_UNAVAILABLE=1 bash "$helper" \
link-status source target tcp 22 >/dev/null 2>"$firewall_error"; then
printf '%s\n' "missing firewall unexpectedly produced a factual Link status" >&2
exit 1
else
[[ $? -eq 79 ]]
fi
[[ "$(<"$firewall_error")" == 'mesh.firewall-unavailable' ]]
if SMM_POLICY_TESTING=1 SMM_POLICY_STATE_FILE="$policy_state" \
SMM_POLICY_FIREWALL_ERROR='permission denied' bash "$helper" \
link-status source target tcp 22 >/dev/null 2>"$firewall_error"; then
printf '%s\n' "unknown nft inspection error unexpectedly produced a factual Link status" >&2
exit 1
else
[[ $? -eq 78 ]]
fi
grep -Fq 'permission denied' "$firewall_error"
if grep -Fq 'mesh.firewall-unavailable' "$firewall_error"; then
printf '%s\n' "unknown nft inspection error was misclassified as missing firewall" >&2
exit 1
fi
rm -f -- "$firewall_error" "$reconcile_marker" "$policy_state" \
"$policy_listing" "$empty_listing" "$list_error" "$inactive_state"
extract_shell_function() {
local name="$1"
awk -v signature="$name() {" '
$0 == signature { emitting = 1 }
emitting { print }
emitting && $0 == "}" { exit }
' "$acceptance"
}
eval "$(extract_shell_function probe_factual_status)"
SOURCE_NODE_ID=source
TARGET_PORT=22
probe_counter="$(mktemp -t smm-factual-probe.XXXXXXXX)"
printf '%s\n' 0 >"$probe_counter"
hub_ssh() {
local count
count="$(( $(<"$probe_counter") + 1 ))"
printf '%s\n' "$count" >"$probe_counter"
[[ "$count" -eq 1 ]] && printf '%s\n' disabled || printf '%s\n' active
}
if probe_factual_status target active; then
printf '%s\n' "initial factual mismatch unexpectedly passed" >&2
exit 1
fi
probe_factual_status target active || {
printf '%s\n' "factual probe did not allow convergence after an initial mismatch" >&2
exit 1
}
rm -f -- "$probe_counter" "${reconcile_marker}.lock"
fixture="$(mktemp -d -t smm-bootstrap-test.XXXXXXXX)"
trap 'rm -rf -- "$fixture"' EXIT
mkdir -p "$fixture/payload/agent" "$fixture/payload/control" "$fixture/payload/provisioning-helper" "$fixture/payload/deploy" "$fixture/payload/bootstrap"
install -m 0755 /bin/true "$fixture/payload/agent/ochenstarik-smm-agent"
install -m 0755 /bin/true "$fixture/payload/control/ochenstarik-smm-control"
install -m 0755 /bin/true "$fixture/payload/provisioning-helper/ochenstarik-smm-provisioning-helper"
install -m 0755 "$helper" "$fixture/payload/deploy/ochenstarik-smm-policy-apply"
install -m 0755 "$emergency" "$fixture/payload/deploy/ochenstarik-smm-emergency"
install -m 0644 "$root/deploy/ochenstarik-smm-control.service" "$fixture/payload/deploy/"
install -m 0644 "$root/deploy/ochenstarik-smm-agent.service" "$fixture/payload/deploy/"
install -m 0644 "$root/deploy/ochenstarik-smm-provisioning-helper.service" "$fixture/payload/deploy/"
install -m 0644 "$root/deploy/ochenstarik-smm-firewall.service" "$fixture/payload/deploy/"
install -m 0755 "$bootstrap" "$fixture/payload/bootstrap/ochenstarik-server-monitor-manager.sh"
tar -C "$fixture/payload" -czf "$fixture/release.tar.gz" agent control provisioning-helper deploy bootstrap
sha256sum "$fixture/release.tar.gz" >"$fixture/release.tar.gz.sha256"
# Create a signed manifest for verify-release (required by hardened verify_archive)
release_hash="$(sha256sum "$fixture/release.tar.gz" | awk '{ print $1 }')"
cat >"$fixture/server-monitor-manager-manifest.json" <<MEOF
{
"version": "v0.0.0-test",
"hashes": {
"release.tar.gz": "$release_hash"
}
}
MEOF
if command -v cosign &>/dev/null; then
COSIGN_PASSWORD="" cosign generate-key-pair --output-key-prefix="$fixture/contract-test"
COSIGN_PASSWORD="" cosign sign-blob --yes --key "$fixture/contract-test.key" \
--output-signature "$fixture/server-monitor-manager-manifest.sig" \
"$fixture/server-monitor-manager-manifest.json"
SMM_TEST_PUBKEY="$fixture/contract-test.pub" \
bash "$bootstrap" verify-release "$fixture/release.tar.gz" >/dev/null
else
# Cosign unavailable — fall back to SMM_ALLOW_UNSIGNED for contract test only
SMM_ALLOW_UNSIGNED=1 bash "$bootstrap" verify-release "$fixture/release.tar.gz" >/dev/null
fi
# Corrupt the manifest hash and verify rejection
cat >"$fixture/server-monitor-manager-manifest.json" <<MEOF
{
"version": "v0.0.0-test",
"hashes": {
"release.tar.gz": "$(printf '%064d' 0)"
}
}
MEOF
if command -v cosign &>/dev/null; then
COSIGN_PASSWORD="" cosign sign-blob --yes --key "$fixture/contract-test.key" \
--output-signature "$fixture/server-monitor-manager-manifest.sig" \
"$fixture/server-monitor-manager-manifest.json"
if SMM_TEST_PUBKEY="$fixture/contract-test.pub" \
bash "$bootstrap" verify-release "$fixture/release.tar.gz" >/dev/null 2>&1; then
printf '%s\n' "corrupt release checksum unexpectedly succeeded" >&2
exit 1
fi
else
printf '%064d %s\n' 0 release.tar.gz >"$fixture/release.tar.gz.sha256"
if SMM_ALLOW_UNSIGNED=1 bash "$bootstrap" verify-release "$fixture/release.tar.gz" >/dev/null 2>&1; then
printf '%s\n' "corrupt release checksum unexpectedly succeeded" >&2
exit 1
fi
fi
# Version ordering. Lexicographic comparison would rank "0.1.0-alpha.10" below
# "0.1.0-alpha.9" and reject every release after the ninth as a downgrade.
version_helpers="$(sed -n '/^normalize_version()/,/^}/p;/^version_lt()/,/^}/p' "$bootstrap")"
version_case() {
local left="$1" right="$2" expected="$3" actual
if bash -c "$version_helpers
version_lt \"\$1\" \"\$2\"" _ "$left" "$right"; then actual="lt"; else actual="ge"; fi
if [[ "$actual" != "$expected" ]]; then
printf 'version_lt %s %s returned %s, expected %s\n' "$left" "$right" "$actual" "$expected" >&2
exit 1
fi
}
version_case "v0.1.0-alpha.9" "v0.1.0-alpha.10" lt
version_case "v0.1.0-alpha.10" "v0.1.0-alpha.9" ge
version_case "v0.1.0-alpha.9" "v0.1.0-alpha.9" ge
version_case "0.1.0-alpha.9" "v0.1.0-alpha.9" ge
version_case "v0.1.0-alpha.9" "v0.2.0" lt
version_case "v0.2.0" "v0.1.0-alpha.9" ge
# The downgrade guard must compare against the recorded installed version, never against
# PROGRAM_VERSION: that constant tracks the source tree, not the deployed component.
grep -Fq 'installed="$(read_installed_version "$role")"' "$bootstrap" || {
printf '%s\n' "update_role must compare against the recorded installed version" >&2
exit 1
}
if grep -qE '"\$new_version" *< *"\$PROGRAM_VERSION"' "$bootstrap"; then
printf '%s\n' "lexicographic version comparison against PROGRAM_VERSION reintroduced" >&2
exit 1
fi
grep -Fq 'record_installed_version control' "$bootstrap" || {
printf '%s\n' "install-control must record the installed version" >&2
exit 1
}
grep -Fq 'record_installed_version agent' "$bootstrap" || {
printf '%s\n' "install-agent must record the installed version" >&2
exit 1
}
printf '%s\n' "BOOTSTRAP_CONTRACT=PASS"