server-monitor-manager/tests/release-verification/run-positive-installation.sh

127 lines
4.8 KiB
Bash

#!/bin/bash
# Installs a published release exactly the way an operator does it: public curl
# downloads, checksum verification, signature verification, then the documented
# bootstrap commands. No gh CLI and no token, because the operator has neither —
# and because gh resolves the repository from git context, which the isolated
# workspace deliberately removes.
set -euo pipefail
TAG="${1:-}"
REPOSITORY="${SMM_REPOSITORY:-ochenstarik-ui/server-monitor-manager}"
if [[ -z "$TAG" ]]; then
echo "Usage: $0 <tag>" >&2
exit 1
fi
BASE_URL="https://github.com/${REPOSITORY}/releases/download/${TAG}"
CONTROL_PORT=17443
MONITOR_USER="ochenstarik-monitor"
MONITOR_HOME="/var/lib/ochenstarik-monitor"
METRICS_SCRIPT="/usr/local/libexec/ochenstarik-smm-metrics"
echo "Running positive installation test for $TAG..."
if command -v cosign >/dev/null 2>&1; then
echo "FAIL: cosign is already present before the clean-host installation test" >&2
exit 1
fi
download() {
local name="$1"
curl --fail --silent --show-error --location --retry 3 \
-o "$name" "${BASE_URL}/${name}" \
|| { echo "FAIL: asset is not downloadable: $name" >&2; exit 1; }
}
case "$(uname -m)" in
x86_64) RUNTIME="linux-x64" ;;
aarch64|arm64) RUNTIME="linux-arm64" ;;
*) echo "FAIL: unsupported architecture $(uname -m)" >&2; exit 1 ;;
esac
ARCHIVE="server-monitor-manager-${RUNTIME}.tar.gz"
download smm-setup.sh
download smm-setup.sh.sha256
sha256sum -c smm-setup.sh.sha256
download "$ARCHIVE"
download "$ARCHIVE.sha256"
sha256sum -c "$ARCHIVE.sha256"
# Signature material must sit beside the archive: verify_archive looks for it there.
download server-monitor-manager-manifest.json
download server-monitor-manager-manifest.sig
download server-monitor-manager-manifest.pem
sudo bash smm-setup.sh --tag "$TAG" install-hub 127.0.0.1 "$CONTROL_PORT" 51820
[[ "$(command -v cosign)" == "/usr/local/bin/cosign" ]] \
|| { echo "FAIL: installer did not provision /usr/local/bin/cosign" >&2; exit 1; }
cosign version >/dev/null
# Exercise the direct bootstrap paths after the short install-hub path has
# provisioned cosign on the otherwise clean runner.
sudo bash smm-setup.sh --tag "$TAG" preflight
sudo bash smm-setup.sh --tag "$TAG" verify-manifest \
server-monitor-manager-manifest.json \
server-monitor-manager-manifest.sig \
server-monitor-manager-manifest.pem
sudo bash smm-setup.sh --tag "$TAG" verify-release "$ARCHIVE"
echo "Checking Control healthz..."
for _ in {1..30}; do
if sudo curl --fail --silent \
--cacert /etc/ochenstarik-server-monitor-manager/control-ca.crt \
"https://127.0.0.1:${CONTROL_PORT}/healthz" >/dev/null; then
break
fi
sleep 1
done
sudo curl --fail --silent --show-error \
--cacert /etc/ochenstarik-server-monitor-manager/control-ca.crt \
"https://127.0.0.1:${CONTROL_PORT}/healthz"
echo "Enrolling a node..."
NODE_CODE="$(sudo bash smm-setup.sh --tag "$TAG" node-code test-node)"
# The file did not exist before this test and was created by install-hub above.
# Remove only that test-provisioned copy so install-node is also exercised from
# a host without cosign.
sudo rm -f -- /usr/local/bin/cosign
hash -r
if command -v cosign >/dev/null 2>&1; then
echo "FAIL: cosign is still present before the clean-host install-node test" >&2
exit 1
fi
SMM_ENROLL_CODE="$NODE_CODE" SMM_ACCEPT_CA_FINGERPRINT=1 \
sudo --preserve-env=SMM_ENROLL_CODE,SMM_ACCEPT_CA_FINGERPRINT \
bash smm-setup.sh --tag "$TAG" install-node
[[ "$(command -v cosign)" == "/usr/local/bin/cosign" ]] \
|| { echo "FAIL: install-node did not provision /usr/local/bin/cosign" >&2; exit 1; }
sudo systemctl is-active --quiet ochenstarik-smm-agent.service
sudo systemctl is-active --quiet ochenstarik-smm-control.service
echo "Installing monitor role..."
ssh-keygen -t ed25519 -N "" -f /tmp/monitor_key -q
sudo bash smm-setup.sh --tag "$TAG" install-monitor "$(cat /tmp/monitor_key.pub)"
echo "Verifying monitor snapshot against the contract..."
sudo grep -Fq "command=\"${METRICS_SCRIPT}\"" "${MONITOR_HOME}/.ssh/authorized_keys" \
|| { echo "FAIL: forced command is not pinned in authorized_keys" >&2; exit 1; }
SNAPSHOT="$(sudo -u "$MONITOR_USER" "$METRICS_SCRIPT")"
EXPECTED_KEYS="$(cut -d'=' -f1 tests/contracts/monitor-snapshot-v1.txt | sort)"
ACTUAL_KEYS="$(cut -d'=' -f1 <<<"$SNAPSHOT" | sort)"
if [[ "$EXPECTED_KEYS" != "$ACTUAL_KEYS" ]]; then
echo "FAIL: monitor snapshot keys do not match the contract" >&2
diff <(echo "$EXPECTED_KEYS") <(echo "$ACTUAL_KEYS") >&2 || true
exit 1
fi
echo "PASS: monitor snapshot matches the contract"
sudo bash smm-setup.sh --tag "$TAG" uninstall-monitor
sudo bash smm-setup.sh --tag "$TAG" uninstall-agent --purge
sudo bash smm-setup.sh --tag "$TAG" uninstall-control --confirm-destroy-control
echo "Positive installation test passed!"