部署:注册分岗人格并退役周期写入
This commit is contained in:
parent
3d11ac75be
commit
7b2f982829
11 changed files with 551 additions and 70 deletions
230
server-tools/persona-team-handshake/retire-periodic-heartbeat-writers.sh
Executable file
230
server-tools/persona-team-handshake/retire-periodic-heartbeat-writers.sh
Executable file
|
|
@ -0,0 +1,230 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
expected_machine_id="caa7b1019517470f9d1368b6e79db49e"
|
||||
state_root="/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1"
|
||||
binary="${state_root}/release/forgejo-16.0.1-linux-amd64"
|
||||
config="${state_root}/config/app.ini"
|
||||
work_path="${state_root}/data"
|
||||
database="${state_root}/data/hlcc.db"
|
||||
api="http://127.0.0.1:3340/api/v1"
|
||||
receipt_root="/var/lib/guanghu/architecture-provision/receipts"
|
||||
receipt="${receipt_root}/HLCC-PERSONA-WRITER-RETIREMENT-20260806.json"
|
||||
archive_root="/var/lib/guanghu/legacy-archives/persona-writers/20260806"
|
||||
token_name="hlcc-persona-final-sync-20260806"
|
||||
temporary="$(mktemp -d)"
|
||||
credential_file="${temporary}/credentials"
|
||||
token=""
|
||||
completed=0
|
||||
|
||||
writers=(
|
||||
chenglu-agent.service
|
||||
chenglu-daily.timer
|
||||
guideng-agent.service
|
||||
kezhou-daily.timer
|
||||
)
|
||||
oneshots=(
|
||||
chenglu-daily.service
|
||||
kezhou-daily.service
|
||||
)
|
||||
keepers=(
|
||||
chenglu-team-handshake.service
|
||||
guideng-team-handshake.service
|
||||
kezhou-team-handshake.service
|
||||
)
|
||||
|
||||
declare -A old_repositories=(
|
||||
[chenglu-agent]="/var/lib/guanghu/forgejo/repositories/bingshuo/chenglu-agent.git"
|
||||
[guideng]="/var/lib/guanghu/forgejo/repositories/bingshuo/guideng.git"
|
||||
[kezhou]="/var/lib/guanghu/forgejo/repositories/bingshuo/kezhou.git"
|
||||
)
|
||||
declare -A work_repositories=(
|
||||
[chenglu-agent]="/var/lib/chenglu-agent/repository"
|
||||
[guideng]="/var/lib/guanghu/personas/guideng/repository"
|
||||
[kezhou]="/var/lib/guanghu/personas/kezhou/repository"
|
||||
)
|
||||
|
||||
cleanup_token() {
|
||||
if test -n "$token"; then
|
||||
TOKEN_NAME="$token_name" DATABASE="$database" python3 - <<'PY'
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
connection = sqlite3.connect(os.environ["DATABASE"], timeout=15)
|
||||
try:
|
||||
with connection:
|
||||
owner = connection.execute(
|
||||
"select id from user where lower_name = ?",
|
||||
("bingshuo",),
|
||||
).fetchone()
|
||||
if owner:
|
||||
connection.execute(
|
||||
"delete from access_token where uid = ? and name = ?",
|
||||
(owner[0], os.environ["TOKEN_NAME"]),
|
||||
)
|
||||
finally:
|
||||
connection.close()
|
||||
PY
|
||||
fi
|
||||
rm -f "$credential_file"
|
||||
rmdir "$temporary" 2>/dev/null || true
|
||||
}
|
||||
|
||||
rollback() {
|
||||
systemctl enable --now guanghu-forgejo.service >/dev/null 2>&1 || true
|
||||
for unit in "${writers[@]}"; do
|
||||
systemctl enable --now "$unit" >/dev/null 2>&1 || true
|
||||
done
|
||||
cleanup_token
|
||||
}
|
||||
|
||||
on_exit() {
|
||||
status=$?
|
||||
trap - EXIT
|
||||
if test "$completed" = 0; then
|
||||
rollback
|
||||
else
|
||||
cleanup_token
|
||||
fi
|
||||
exit "$status"
|
||||
}
|
||||
trap on_exit EXIT
|
||||
|
||||
test "$(cat /etc/machine-id)" = "$expected_machine_id"
|
||||
test -x "$binary"
|
||||
test -f "$config"
|
||||
test -f "$database"
|
||||
test "$(systemctl is-active hlcc-jd-candidate.service)" = "active"
|
||||
test "$(curl -fsS http://127.0.0.1:3341/health | jq -r .ready)" = "true"
|
||||
for unit in "${keepers[@]}"; do
|
||||
test "$(systemctl is-active "$unit")" = "active"
|
||||
done
|
||||
for name in chenglu-agent guideng kezhou; do
|
||||
test -d "${old_repositories[$name]}"
|
||||
test -d "${state_root}/data/repositories/bingshuo/${name}.git"
|
||||
git --git-dir="${old_repositories[$name]}" fsck --connectivity-only --no-dangling
|
||||
done
|
||||
|
||||
mkdir -p "$archive_root" "$receipt_root"
|
||||
for unit in "${writers[@]}" "${oneshots[@]}" guanghu-forgejo.service; do
|
||||
systemctl cat "$unit" >"${archive_root}/${unit}.txt" 2>&1 || true
|
||||
done
|
||||
source_paths=()
|
||||
for candidate in /opt/chenglu-agent /opt/guideng/agent /opt/kezhou/agent; do
|
||||
if test -e "$candidate"; then
|
||||
source_paths+=("$candidate")
|
||||
fi
|
||||
done
|
||||
if test "${#source_paths[@]}" -gt 0; then
|
||||
tar -czf "${archive_root}/legacy-persona-writer-source.tar.gz" "${source_paths[@]}"
|
||||
sha256sum "${archive_root}/legacy-persona-writer-source.tar.gz" \
|
||||
>"${archive_root}/legacy-persona-writer-source.tar.gz.sha256"
|
||||
fi
|
||||
|
||||
for unit in "${writers[@]}"; do
|
||||
systemctl disable --now "$unit"
|
||||
done
|
||||
for unit in "${oneshots[@]}"; do
|
||||
systemctl stop "$unit" || true
|
||||
done
|
||||
for unit in "${writers[@]}" "${oneshots[@]}"; do
|
||||
test "$(systemctl is-active "$unit" || true)" != "active"
|
||||
done
|
||||
|
||||
token="$(
|
||||
runuser -u guanghu -- "$binary" admin user generate-access-token \
|
||||
--username bingshuo \
|
||||
--token-name "$token_name" \
|
||||
--scopes write:repository,write:user \
|
||||
--raw \
|
||||
--config "$config" \
|
||||
--work-path "$work_path" |
|
||||
tail -n 1
|
||||
)"
|
||||
test -n "$token"
|
||||
test "${#token}" -ge 32
|
||||
printf 'http://bingshuo:%s@127.0.0.1:3340\n' "$token" >"$credential_file"
|
||||
chmod 0600 "$credential_file"
|
||||
|
||||
for name in chenglu-agent guideng kezhou; do
|
||||
source="${old_repositories[$name]}"
|
||||
target="http://127.0.0.1:3340/bingshuo/${name}.git"
|
||||
git -c "credential.helper=store --file ${credential_file}" \
|
||||
--git-dir="$source" push --prune "$target" \
|
||||
"refs/heads/*:refs/heads/*" \
|
||||
"refs/tags/*:refs/tags/*"
|
||||
|
||||
new_bare="${state_root}/data/repositories/bingshuo/${name}.git"
|
||||
old_refs="$(
|
||||
git --git-dir="$source" for-each-ref \
|
||||
--format='%(refname) %(objectname)' refs/heads refs/tags |
|
||||
sort
|
||||
)"
|
||||
new_refs="$(
|
||||
git --git-dir="$new_bare" for-each-ref \
|
||||
--format='%(refname) %(objectname)' refs/heads refs/tags |
|
||||
sort
|
||||
)"
|
||||
test "$new_refs" = "$old_refs"
|
||||
runuser -u guanghu -- \
|
||||
git -c "safe.directory=$new_bare" --git-dir="$new_bare" \
|
||||
fsck --connectivity-only --no-dangling
|
||||
|
||||
git -C "${work_repositories[$name]}" remote set-url origin \
|
||||
"https://guanghulab.com/code/bingshuo/${name}.git"
|
||||
done
|
||||
|
||||
systemctl disable --now guanghu-forgejo.service
|
||||
test "$(systemctl is-active guanghu-forgejo.service || true)" != "active"
|
||||
for unit in "${keepers[@]}"; do
|
||||
test "$(systemctl is-active "$unit")" = "active"
|
||||
done
|
||||
test "$(curl -fsS http://127.0.0.1:3341/health | jq -r .ready)" = "true"
|
||||
if ss -ltnH | awk '{print $4}' | grep -Eq '(^|:)3001$'; then
|
||||
exit 41
|
||||
fi
|
||||
|
||||
chenglu_sha="$(git --git-dir="${old_repositories[chenglu-agent]}" rev-parse refs/heads/main)"
|
||||
guideng_sha="$(git --git-dir="${old_repositories[guideng]}" rev-parse refs/heads/main)"
|
||||
kezhou_sha="$(git --git-dir="${old_repositories[kezhou]}" rev-parse refs/heads/main)"
|
||||
|
||||
jq -n \
|
||||
--arg completed_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
--arg chenglu "$chenglu_sha" \
|
||||
--arg guideng "$guideng_sha" \
|
||||
--arg kezhou "$kezhou_sha" \
|
||||
--arg source_archive_sha "$(
|
||||
awk '{print $1}' "${archive_root}/legacy-persona-writer-source.tar.gz.sha256" 2>/dev/null ||
|
||||
printf 'NO_SOURCE_ARCHIVE'
|
||||
)" \
|
||||
'{
|
||||
schema: "guanghu.persona-writer-retirement-receipt/v1",
|
||||
receipt_id: "HLCC-PERSONA-WRITER-RETIREMENT-20260806",
|
||||
target_node: "JD-FD-PRIMARY",
|
||||
completed_at: $completed_at,
|
||||
result: "PERIODIC_WRITERS_RETIRED_AFTER_EXACT_HISTORY_MIGRATION",
|
||||
controller: "ICE-P-ZY001",
|
||||
human_authority: "ICE-GL∞",
|
||||
repositories: [
|
||||
{name:"bingshuo/chenglu-agent", main_sha:$chenglu, refs:"EXACT_MATCH"},
|
||||
{name:"bingshuo/guideng", main_sha:$guideng, refs:"EXACT_MATCH"},
|
||||
{name:"bingshuo/kezhou", main_sha:$kezhou, refs:"EXACT_MATCH"}
|
||||
],
|
||||
periodic_writers: "DISABLED_AND_INACTIVE",
|
||||
old_repository_service: "DISABLED_AND_INACTIVE",
|
||||
role_handshake_services: "ALL_ACTIVE",
|
||||
current_code_channel: "HEALTHY",
|
||||
legacy_data_deleted: false,
|
||||
source_archive_sha256: $source_archive_sha,
|
||||
rule: "Scheduled repository writes are historical transport, not proof of language or persona continuity."
|
||||
}' >"${receipt}.tmp"
|
||||
chmod 0600 "${receipt}.tmp"
|
||||
mv "${receipt}.tmp" "$receipt"
|
||||
|
||||
completed=1
|
||||
token_to_delete="$token"
|
||||
cleanup_token
|
||||
token=""
|
||||
trap - EXIT
|
||||
printf 'PERIODIC_WRITERS_RETIRED receipt=%s token_deleted=%s\n' \
|
||||
"$receipt" "$(test -n "$token_to_delete" && printf true)"
|
||||
Loading…
Reference in a new issue