guanghu-ice-heart/zero-point/core-channel/revive-guard/install-pre-op-map-agent-v2.sh

128 lines
3.6 KiB
Shell

#!/usr/bin/env bash
set -euo pipefail
# Installs the read-only Guanghu interactive map agent with rollback material.
# Run from the revive-guard directory:
# sudo bash install-pre-op-map-agent-v2.sh BS-SG-003
NODE_ID="${1:-BS-SG-003}"
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
AGENT_SOURCE="$SOURCE_DIR/pre-op-map-agent-v2.py"
HOOK_SOURCE="$SOURCE_DIR/pre-op-map-agent-v2.sh"
MAP_SOURCE="$SOURCE_DIR/maps/$NODE_ID.json"
MAP_HASH_SOURCE="$MAP_SOURCE.sha256"
INSTALL_ROOT="/opt/guanghu/map-agent"
MAP_ROOT="/etc/guanghu/navigation-maps"
SHELL_ROOT="/etc/guanghu/shell.d"
PROFILE_HOOK="/etc/profile.d/guanghu-map-agent.sh"
BASH_SYSTEM_RC="/etc/bash.bashrc"
BACKUP_ROOT="/var/backups/guanghu-map-agent"
RECEIPT_ROOT="/var/lib/guanghu/map-agent/install-receipts"
TIMESTAMP="$(date -u +%Y%m%dT%H%M%SZ)"
BACKUP_DIR="$BACKUP_ROOT/$TIMESTAMP"
RECEIPT="$RECEIPT_ROOT/install-$NODE_ID-$TIMESTAMP.json"
if [ "$(id -u)" -ne 0 ]; then
echo "需要 root 权限安装服务器入口地图 Agent。" >&2
exit 1
fi
for source_file in "$AGENT_SOURCE" "$HOOK_SOURCE" "$MAP_SOURCE" "$MAP_HASH_SOURCE"; do
if [ ! -f "$source_file" ]; then
echo "缺少安装源文件: $source_file" >&2
exit 1
fi
done
python3 "$AGENT_SOURCE" \
--map "$MAP_SOURCE" \
--static-only \
--no-receipt \
--json >/dev/null
install -d -m 0750 "$INSTALL_ROOT" "$MAP_ROOT" "$SHELL_ROOT"
install -d -m 0750 "$BACKUP_DIR" "$RECEIPT_ROOT"
for current in \
"$INSTALL_ROOT/pre-op-map-agent-v2.py" \
"$MAP_ROOT/$NODE_ID.json" \
"$MAP_ROOT/$NODE_ID.json.sha256" \
"$SHELL_ROOT/map-agent.sh" \
"$PROFILE_HOOK" \
"$BASH_SYSTEM_RC"; do
if [ -e "$current" ]; then
backup_name="$(printf '%s' "$current" | sed 's#^/##; s#/#__#g')"
cp -a "$current" "$BACKUP_DIR/$backup_name"
fi
done
install -m 0755 "$AGENT_SOURCE" "$INSTALL_ROOT/pre-op-map-agent-v2.py"
install -m 0644 "$MAP_SOURCE" "$MAP_ROOT/$NODE_ID.json"
install -m 0644 "$MAP_HASH_SOURCE" "$MAP_ROOT/$NODE_ID.json.sha256"
install -m 0644 "$HOOK_SOURCE" "$SHELL_ROOT/map-agent.sh"
cat >"$PROFILE_HOOK" <<'EOF'
# 光湖服务器入口地图 Agent v2 · login shells
if [ -r /etc/guanghu/shell.d/map-agent.sh ]; then
. /etc/guanghu/shell.d/map-agent.sh
fi
EOF
chmod 0644 "$PROFILE_HOOK"
BEGIN_MARKER="# BEGIN GUANGHU MAP AGENT V2"
END_MARKER="# END GUANGHU MAP AGENT V2"
if ! grep -Fq "$BEGIN_MARKER" "$BASH_SYSTEM_RC"; then
cat >>"$BASH_SYSTEM_RC" <<'EOF'
# BEGIN GUANGHU MAP AGENT V2
if [ -r /etc/guanghu/shell.d/map-agent.sh ]; then
. /etc/guanghu/shell.d/map-agent.sh
fi
# END GUANGHU MAP AGENT V2
EOF
fi
python3 "$INSTALL_ROOT/pre-op-map-agent-v2.py" \
--map "$MAP_ROOT/$NODE_ID.json" \
--static-only \
--no-receipt \
--json >/dev/null
map_sha256="$(sha256sum "$MAP_ROOT/$NODE_ID.json" | awk '{print $1}')"
agent_sha256="$(sha256sum "$INSTALL_ROOT/pre-op-map-agent-v2.py" | awk '{print $1}')"
cat >"$RECEIPT" <<EOF
{
"schema_version": "guanghu.map-agent-install-receipt/v2",
"node_id": "$NODE_ID",
"installed_at": "$TIMESTAMP",
"map_sha256": "$map_sha256",
"agent_sha256": "$agent_sha256",
"backup_dir": "$BACKUP_DIR",
"interactive_entrypoints": [
"$PROFILE_HOOK",
"$BASH_SYSTEM_RC"
],
"status": "INSTALLED_STATIC_VERIFIED"
}
EOF
chmod 0600 "$RECEIPT"
set +e
python3 "$INSTALL_ROOT/pre-op-map-agent-v2.py" \
--map "$MAP_ROOT/$NODE_ID.json" \
--receipt-root "/var/lib/guanghu/map-agent/receipts" \
--persona "installer" \
--json
live_status=$?
set -e
echo "INSTALL_RECEIPT=$RECEIPT"
echo "ROLLBACK_BACKUP=$BACKUP_DIR"
if [ "$live_status" -eq 0 ]; then
echo "REALTIME_MAP_STATUS=MAP_VERIFIED"
else
echo "REALTIME_MAP_STATUS=MAP_DRIFT"
fi
exit "$live_status"