Some checks failed
Tests / Declarative: Post Actions failed: 2, passed: 142
One script with a 'fixture' and a 'code' subcommand meant the wrong subcommand was always one word away, in front of an audience, with different blast radii behind each: the triage demo touches only a ConfigMap, the code demo pushes to a repository and deletes issues. Those should not share a command line. Each demo is now its own driver with the same five verbs - monitor, reset, preflight, run, status - so knowing one teaches the other. What they genuinely share (credentials, Jenkins access, the tick reader, the lab-wide preflight checks) moved to hermes_demo_lib.sh rather than being duplicated, because the reason to split was clarity at the command line, not two copies of the same helper drifting apart. Each reset now covers only its own demo. The triage reset no longer reaches into a Gitea repository it never writes to, and the code reset owns the repository cleanup entirely. The credentials file is now hermes_demo.env since both read it; the old hermes_triage_demo.env is still sourced as a fallback so a filled-in file keeps working, and both names stay git-ignored. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
99 lines
3.8 KiB
Bash
Executable File
99 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Drive and narrate the Hermes automated-triage demo.
|
|
#
|
|
# This is the autonomous loop: a build fails, Ariadne diagnoses it through
|
|
# Hermes, authorizes a predefined repair, performs it, and rebuilds green
|
|
# without a human touching anything.
|
|
#
|
|
# hermes_triage_demo.sh monitor # follow the Test Automation Diagram live
|
|
# hermes_triage_demo.sh reset # restore the demo to its pre-run state
|
|
# hermes_triage_demo.sh preflight # confirm the lab is ready to demo
|
|
# hermes_triage_demo.sh run # arm the failure and narrate the loop
|
|
# hermes_triage_demo.sh status # current incident/alert state, no changes
|
|
#
|
|
# The code-proposal demo is a separate script: hermes_code_demo.sh. They prove
|
|
# different halves of the diagram and reset different things, so they are kept
|
|
# apart rather than behind one command.
|
|
#
|
|
# FIRST RUN: copy hermes_demo.env.example to hermes_demo.env in this directory
|
|
# and fill it in. That file is git-ignored precisely so it can hold real
|
|
# tokens; this script sources it automatically.
|
|
#
|
|
# Needs kubectl access to the cluster as well. Nothing here mutates the cluster
|
|
# directly: the demo only asks Jenkins to run a parameterized build.
|
|
set -euo pipefail
|
|
|
|
# shellcheck source=scripts/ops/hermes_demo_lib.sh
|
|
. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/hermes_demo_lib.sh"
|
|
|
|
# The fixture is a ConfigMap the demo job reads. Resetting it is the whole
|
|
# blast radius of this script: no repository is touched, because the triage
|
|
# loop repairs infrastructure rather than source.
|
|
cmd_reset() {
|
|
say "Reset — restoring the triage demo to its pre-run state"
|
|
note "fixture -> healthy"
|
|
if kubectl -n "$DEMO_NS" patch cm hermes-triage-demo-fixture \
|
|
--type merge -p '{"data":{"state":"healthy"}}' >/dev/null 2>&1; then
|
|
note " fixture: $(kubectl -n "$DEMO_NS" get cm hermes-triage-demo-fixture -o jsonpath='{.data.state}')"
|
|
else
|
|
note " fixture patch failed (is the demo namespace present?)"
|
|
fi
|
|
say "Ready"
|
|
note "no repository was touched; this demo repairs infrastructure, not source"
|
|
note "run 'preflight' next, then 'run'"
|
|
}
|
|
|
|
cmd_preflight() {
|
|
require_jenkins
|
|
say "Preflight — triage demo"
|
|
note "fixture state: $(kubectl -n "$DEMO_NS" get cm hermes-triage-demo-fixture -o jsonpath='{.data.state}' 2>/dev/null || echo MISSING)"
|
|
shared_preflight
|
|
}
|
|
|
|
cmd_status() {
|
|
shared_status
|
|
say "Demo namespace"
|
|
kubectl -n "$DEMO_NS" get jobs --no-headers 2>/dev/null | sed 's/^/ /'
|
|
}
|
|
|
|
cmd_run() {
|
|
require_jenkins
|
|
local start_num next_num
|
|
start_num="$(last_build_number "$FIXTURE_JOB")"
|
|
next_num=$((start_num + 1))
|
|
say "Arming the demo failure (SEED_FAILURE=true) -> build #$next_num"
|
|
note "HTTP $(jenkins_post "/job/$FIXTURE_JOB/buildWithParameters?SEED_FAILURE=true")"
|
|
note "Only manual step. Everything after this is automatic."
|
|
|
|
say "Waiting for the seeded build to fail"
|
|
note "result: $(wait_for_build "$FIXTURE_JOB" "$next_num")"
|
|
|
|
say "Ariadne detects, gathers evidence, asks Hermes, authorizes, repairs"
|
|
note "the repair is a single in-process ConfigMap patch, so watch the fixture"
|
|
for _ in $(seq 1 40); do
|
|
sleep 10
|
|
if [ "$(kubectl -n "$DEMO_NS" get cm hermes-triage-demo-fixture -o jsonpath='{.data.state}' 2>/dev/null)" = "healthy" ]; then
|
|
note "fixture patched back to healthy"
|
|
break
|
|
fi
|
|
done
|
|
ariadne_ticks 400 4
|
|
|
|
say "Ariadne triggers one rebuild with seeding disabled"
|
|
note "result: $(wait_for_build "$FIXTURE_JOB" $((next_num + 1)))"
|
|
|
|
say "Resolution"
|
|
sleep 45
|
|
ariadne_ticks 200 3
|
|
note "fixture state: $(kubectl -n "$DEMO_NS" get cm hermes-triage-demo-fixture -o jsonpath='{.data.state}')"
|
|
}
|
|
|
|
case "${1:-}" in
|
|
run|fixture) cmd_run ;;
|
|
status) cmd_status ;;
|
|
preflight) cmd_preflight ;;
|
|
reset) cmd_reset ;;
|
|
monitor) run_monitor "$FIXTURE_JOB" ;;
|
|
*) sed -n '2,17p' "$0" | sed 's/^# \{0,1\}//' ; exit 1 ;;
|
|
esac
|