The update is a skill (decision 4); deploy/update.sh and the installed .mam_deploy/update.sh are gone. - Phase 1 (installed code, update.sh): publish the update marker under the exclusive admission lock; refuse before any change while a running row, a live herdr agent in the workspace on any running server, an open job (unreadable JSON included, dry_run not), a live loop marker or a monitor.lock held by a monitor the skills did not start (U3) is there - the calling agent (server + pane, its row and one running job) excepted (lib_py/update.py precheck, decisions 1 and 7). Stop the monitor (TERM, then KILL and restart it if it does not end; decision 2), handle a leftover backup by its state (U4), back up .agents, .mam_deploy, root files, .venv, the installer's .mam files and the registry (SQLite backup API under the registry lock) into .mam/update-backup/, then exec a copy of install_phase.sh outside the tree (decision 5). - The copy (no lib.sh/lib_py, bash 3.2) runs the installer in place; on failure it restores the backup and restarts the monitor from the restored tree; on success it runs phase 2, post_update.sh of the new tree, which converts the registry with lib_py.registry_format and restarts the monitor if it ran. The backup and the marker are removed at the end. - install.sh updates in place (decisions 3, 4, 9): install_state keys are set, one line each; no updater is installed and an old one (.mam_deploy/update.sh, or a root update.sh the manifest lists) is removed; framework files the new version no longer ships are deleted when unmodified, kept and listed when modified, and dropped from base/, the manifest and asset_hashes.txt; a local source's .mam is not staged. remove.sh knows the new skill; CI shellchecks its scripts; docs point at the skill. - test_issue8_update_state and test_deploy_layout td6/td27 run the skill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
1.6 KiB
Bash
Executable File
48 lines
1.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# post_update.sh — multi-agent-mux-update phase 2 (Issue #72, decision 5).
|
|
# post_update.sh --monitor <0|1>
|
|
#
|
|
# Run by install_phase.sh from the NEWLY installed tree, in its own process:
|
|
# converts the registry with the new code's entry point (lib_py.registry_format,
|
|
# #71) and starts the monitor again if it ran before the update. Exit 0, or
|
|
# nonzero when the conversion or the monitor restart failed (the install is
|
|
# kept either way: the registry converts again on its next write).
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
WS="$(cd -P "$SCRIPT_DIR/../../../.." && pwd -P)"
|
|
export WORKSPACE_ROOT="$WS"
|
|
export AGENT_SESSIONS_YAML="$WS/.mam/agent-sessions.yaml"
|
|
# shellcheck source=../../lib.sh
|
|
source "$WS/.agents/skills/lib.sh"
|
|
|
|
MON=0
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--monitor) MON="$2"; shift 2 ;;
|
|
*) echo "ERROR: unknown arg: $1" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
rc=0
|
|
if [ ! -f "$AGENT_SESSIONS_YAML" ] && [ ! -f "$WS/.mam/agent-sessions.db" ]; then
|
|
echo "registry: nothing to convert (no registry)"
|
|
else
|
|
"$(_delegate_py_bin)" -m lib_py.registry_format --yaml "$AGENT_SESSIONS_YAML" || rc=$?
|
|
if [ "$rc" -ne 0 ]; then
|
|
echo "ERROR: the registry was not converted (rc $rc); the install is kept and the next registry write converts it" >&2
|
|
fi
|
|
fi
|
|
|
|
if [ "$MON" = "1" ]; then
|
|
if [ "${MAM_NO_SUBSCRIBER_DAEMON:-0}" = "1" ]; then
|
|
echo "monitor: not restarted (MAM_NO_SUBSCRIBER_DAEMON=1)"
|
|
elif pid="$(start_watchdog update "$WS")"; then
|
|
echo "monitor: restarted (PID $pid)"
|
|
else
|
|
echo "ERROR: could not restart the monitor daemon" >&2
|
|
rc=1
|
|
fi
|
|
fi
|
|
exit "$rc"
|