部署:注册分岗人格并退役周期写入

This commit is contained in:
冰朔 2026-08-06 17:23:08 +08:00
commit 7b2f982829
11 changed files with 551 additions and 70 deletions

View 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)"