Compare commits
3
Commits
d3cfef4147
...
d8ae7ee6f6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8ae7ee6f6 | ||
|
|
2ae60299b7 | ||
|
|
c6b172dce7 |
@@ -44,5 +44,5 @@
|
||||
"/api",
|
||||
"/hook"
|
||||
],
|
||||
"updated_at": "2026-07-06T07:13:43.274132+00:00"
|
||||
"updated_at": "2026-07-06T07:16:01.842497+00:00"
|
||||
}
|
||||
|
||||
+363
@@ -0,0 +1,363 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="/data/aios-gitops"
|
||||
ZIP_NAME="AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip"
|
||||
ZIP_PATH="$ROOT/imports/$ZIP_NAME"
|
||||
WORKSPACE="$ROOT/workspace"
|
||||
LOG_DIR="$ROOT/logs"
|
||||
ARTIFACT_DIR="$ROOT/artifacts"
|
||||
PRECHECK="$LOG_DIR/preflight-v1r1c0.md"
|
||||
RUN_LOG="$LOG_DIR/gitops-v1r1c0-migration.log"
|
||||
FAILED_REPORT="$ARTIFACT_DIR/AIOS_V1R1C0_ONLINE_BASELINE_FAILED.md"
|
||||
ACCEPT_REPORT="$ARTIFACT_DIR/AIOS_V1R1C0_ONLINE_BASELINE_ACCEPTANCE.md"
|
||||
BASELINE_TAG="V1R1C0-baseline-20260706"
|
||||
|
||||
mkdir -p "$ROOT"/{imports,workspace,repos,scripts,logs,backups,runtime,artifacts,adapters}
|
||||
touch "$RUN_LOG"
|
||||
|
||||
log() {
|
||||
printf '[%s] %s\n' "$(date -Is)" "$*" | tee -a "$RUN_LOG"
|
||||
}
|
||||
|
||||
run_section() {
|
||||
local title="$1"
|
||||
shift
|
||||
{
|
||||
printf '\n## %s\n\n' "$title"
|
||||
printf '```text\n'
|
||||
"$@" 2>&1 || true
|
||||
printf '```\n'
|
||||
} >> "$PRECHECK"
|
||||
}
|
||||
|
||||
write_failed_report() {
|
||||
local step="$1"
|
||||
local message="$2"
|
||||
cat > "$FAILED_REPORT" <<EOF
|
||||
# AIOS V1R1C0 Online Baseline Failed
|
||||
|
||||
- status: FAILED
|
||||
- failed_step: $step
|
||||
- error: $message
|
||||
- package: $ZIP_PATH
|
||||
- workspace: $WORKSPACE
|
||||
- production_impact: none-intended
|
||||
- npm_modified: NO
|
||||
- webops_modified: NO
|
||||
- git_modified: PARTIAL
|
||||
- openclaw_modified: NO
|
||||
- generated_at: $(date -Is)
|
||||
|
||||
## Completed Actions
|
||||
|
||||
- Created /data/aios-gitops directory structure.
|
||||
- Generated preflight report when possible.
|
||||
- Preserved original ZIP if present.
|
||||
- Stopped before production routing changes.
|
||||
|
||||
## Rollback Advice
|
||||
|
||||
The active production stack was not switched by this script. Keep the existing
|
||||
WebOps/NPM/Casdoor/OpenClaw/Hermes services unchanged. Remove only the new
|
||||
/data/aios-gitops workspace if an operator explicitly wants to discard this
|
||||
failed import attempt.
|
||||
|
||||
## Next Step
|
||||
|
||||
Fix the failed step, then rerun the migration script. Do not treat this state
|
||||
as an online baseline.
|
||||
EOF
|
||||
}
|
||||
|
||||
preflight() {
|
||||
log "preflight start"
|
||||
cat > "$PRECHECK" <<EOF
|
||||
# AIOS V1R1C0 GitOps Preflight
|
||||
|
||||
- generated_at: $(date -Is)
|
||||
- hostname: $(hostname)
|
||||
- user: $(whoami)
|
||||
- root: $ROOT
|
||||
- package: $ZIP_PATH
|
||||
|
||||
## Reuse Summary
|
||||
|
||||
- NPM_REUSED: UNKNOWN
|
||||
- WEBOPS_REUSED: UNKNOWN
|
||||
- CASDOOR_REUSED: UNKNOWN
|
||||
- OPENCLAW_REUSED: UNKNOWN
|
||||
- HERMES_REUSED: UNKNOWN
|
||||
- ONE_API_REUSED: UNKNOWN
|
||||
- GITEA_REUSED: UNKNOWN
|
||||
|
||||
EOF
|
||||
run_section "hostname" hostname
|
||||
run_section "date" date -Is
|
||||
run_section "whoami" whoami
|
||||
run_section "pwd" pwd
|
||||
run_section "df -h" df -h
|
||||
run_section "free -h" free -h
|
||||
run_section "docker ps" docker ps
|
||||
run_section "docker compose version" bash -lc 'docker compose version || docker-compose version || true'
|
||||
run_section "ss -lntp" ss -lntp
|
||||
run_section "ls /data" ls -lah /data
|
||||
run_section "ls /opt" ls -lah /opt
|
||||
run_section "component containers" bash -lc "docker ps | grep -Ei 'npm|nginx-proxy-manager|gitea|casdoor|openclaw|hermes|webops|one-api|postgres|redis|nats' || true"
|
||||
run_section "component paths" bash -lc "find /data /opt -maxdepth 4 \\( -iname '*npm*' -o -iname '*gitea*' -o -iname '*openclaw*' -o -iname '*webops*' -o -iname '*casdoor*' -o -iname '*one-api*' \\) 2>/dev/null || true"
|
||||
run_section "component services" bash -lc "systemctl list-units --type=service --no-pager | grep -Ei 'openclaw|hermes|aios|webops|npm|gitea|casdoor' || true"
|
||||
log "preflight done: $PRECHECK"
|
||||
}
|
||||
|
||||
backup_state() {
|
||||
log "backup start"
|
||||
local backup_dir="$ROOT/backups/pre-v1r1c0-$(date +%Y%m%d-%H%M%S)"
|
||||
mkdir -p "$backup_dir"
|
||||
cp -a /data/agent "$backup_dir/data-agent" 2>/dev/null || true
|
||||
cp -a /data/aios "$backup_dir/data-aios" 2>/dev/null || true
|
||||
cp -a /opt/aios "$backup_dir/opt-aios" 2>/dev/null || true
|
||||
cp -a /etc/systemd/system "$backup_dir/systemd-system" 2>/dev/null || true
|
||||
docker ps > "$backup_dir/docker-ps.txt" 2>/dev/null || true
|
||||
ss -lntp > "$backup_dir/ports.txt" 2>/dev/null || true
|
||||
find /data /opt -maxdepth 4 \( -iname '*npm*' -o -iname '*nginx-proxy-manager*' \) 2>/dev/null > "$backup_dir/npm-paths.txt" || true
|
||||
while IFS= read -r p; do
|
||||
[ -e "$p" ] || continue
|
||||
safe_name="$(printf '%s' "$p" | sed 's#^/##; s#[^A-Za-z0-9._-]#_#g')"
|
||||
cp -a "$p" "$backup_dir/$safe_name" 2>/dev/null || true
|
||||
done < "$backup_dir/npm-paths.txt"
|
||||
printf '%s\n' "$backup_dir" > "$ROOT/runtime/latest-backup-dir.txt"
|
||||
log "backup done: $backup_dir"
|
||||
}
|
||||
|
||||
import_zip() {
|
||||
log "import start"
|
||||
if [ ! -f "$ZIP_PATH" ]; then
|
||||
write_failed_report "locate_zip" "BLOCKED: missing $ZIP_NAME"
|
||||
log "BLOCKED: missing $ZIP_NAME"
|
||||
exit 2
|
||||
fi
|
||||
mkdir -p "$WORKSPACE"
|
||||
resolved="$(readlink -f "$WORKSPACE")"
|
||||
if [ "$resolved" != "$WORKSPACE" ]; then
|
||||
write_failed_report "workspace_resolve" "Unexpected workspace path: $resolved"
|
||||
exit 3
|
||||
fi
|
||||
find "$WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +
|
||||
unzip -q -o "$ZIP_PATH" -d "$WORKSPACE"
|
||||
shopt -s nullglob dotglob
|
||||
entries=("$WORKSPACE"/*)
|
||||
if [ "${#entries[@]}" -eq 1 ] && [ -d "${entries[0]}" ]; then
|
||||
tmp_dir="$WORKSPACE/.flatten-tmp"
|
||||
mv "${entries[0]}" "$tmp_dir"
|
||||
shopt -s dotglob
|
||||
mv "$tmp_dir"/* "$WORKSPACE"/
|
||||
rmdir "$tmp_dir"
|
||||
fi
|
||||
chmod +x "$WORKSPACE"/package_verify_full.sh 2>/dev/null || true
|
||||
chmod +x "$WORKSPACE"/scripts/*.sh "$WORKSPACE"/tests/*.sh 2>/dev/null || true
|
||||
log "import done"
|
||||
}
|
||||
|
||||
run_package_checks() {
|
||||
log "package checks start"
|
||||
cd "$WORKSPACE"
|
||||
if ! bash scripts/package_contract_check_v1r1c0.sh > "$LOG_DIR/package_contract_check_v1r1c0.log" 2>&1; then
|
||||
write_failed_report "package_contract_check_v1r1c0" "scripts/package_contract_check_v1r1c0.sh failed; see $LOG_DIR/package_contract_check_v1r1c0.log"
|
||||
exit 4
|
||||
fi
|
||||
if ! bash tests/run_v1r1c0_acceptance.sh > "$LOG_DIR/run_v1r1c0_acceptance.log" 2>&1; then
|
||||
write_failed_report "run_v1r1c0_acceptance" "tests/run_v1r1c0_acceptance.sh failed; see $LOG_DIR/run_v1r1c0_acceptance.log"
|
||||
exit 5
|
||||
fi
|
||||
if ! ./package_verify_full.sh > "$LOG_DIR/package_verify_full.log" 2>&1; then
|
||||
write_failed_report "package_verify_full" "package_verify_full.sh failed; see $LOG_DIR/package_verify_full.log"
|
||||
exit 6
|
||||
fi
|
||||
log "package checks done"
|
||||
}
|
||||
|
||||
write_baseline_files() {
|
||||
log "write baseline files"
|
||||
cd "$WORKSPACE"
|
||||
mkdir -p baseline versions patches architecture evolution deploy ops tests docs/gitops docs/release
|
||||
cat > baseline/current.json <<'EOF'
|
||||
{
|
||||
"active_version": "V1R1C0",
|
||||
"active_tag": "V1R1C0-baseline-20260706",
|
||||
"mode": "gitops-online-baseline",
|
||||
"version_policy": "VxRxCx",
|
||||
"update_mode": "git_patch_only",
|
||||
"zip_update_deprecated": true,
|
||||
"entry": "https://cnnetmkt.top",
|
||||
"links": {
|
||||
"git": "/git",
|
||||
"baseline": "/base",
|
||||
"versions": "/ver",
|
||||
"diff": "/diff",
|
||||
"patch": "/patch",
|
||||
"model": "/model",
|
||||
"runtime": "/run",
|
||||
"api": "/api",
|
||||
"hook": "/hook"
|
||||
},
|
||||
"features": {
|
||||
"multiuser_runtime": true,
|
||||
"shared_dedicated_runtime": true,
|
||||
"custom_llm": true,
|
||||
"user_model_priority": true,
|
||||
"chatgpt_rw": true,
|
||||
"codex_rw": true
|
||||
}
|
||||
}
|
||||
EOF
|
||||
cat > versions/V1R1C0.json <<'EOF'
|
||||
{
|
||||
"version": "V1R1C0",
|
||||
"tag": "V1R1C0-baseline-20260706",
|
||||
"type": "baseline",
|
||||
"name": "MultiUser GitOps Custom LLM Baseline",
|
||||
"source": "AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip",
|
||||
"update_mode": "git_patch_only",
|
||||
"zip_update_mode": "deprecated_after_import"
|
||||
}
|
||||
EOF
|
||||
cat > architecture/current.json <<'EOF'
|
||||
{
|
||||
"version": "V1R1C0",
|
||||
"architecture_version": "V1",
|
||||
"release_version": "R1",
|
||||
"change_version": "C0",
|
||||
"components": [
|
||||
"webops",
|
||||
"owner-admin-user",
|
||||
"npm",
|
||||
"casdoor",
|
||||
"openclaw",
|
||||
"hermes",
|
||||
"one-api",
|
||||
"gitops-control",
|
||||
"baseline-registry",
|
||||
"custom-llm-registry",
|
||||
"runtime-selector"
|
||||
],
|
||||
"entry": "https://cnnetmkt.top",
|
||||
"proxy": "npm",
|
||||
"runtime_sync": "openclaw"
|
||||
}
|
||||
EOF
|
||||
cat > docs/release/VxRxCx_RULES.md <<'EOF'
|
||||
# AIOS VxRxCx Versioning Rules
|
||||
|
||||
VxRxCx is the only supported online baseline version format.
|
||||
|
||||
- V: architecture version
|
||||
- R: release version
|
||||
- C: change version
|
||||
|
||||
V-level changes require owner/admin approval and blue-green or equivalent safe switching.
|
||||
R-level changes require canary or test-environment validation.
|
||||
C-level changes require smoke test and automatic rollback on failure.
|
||||
|
||||
Initial imported online baseline for this package: V1R1C0-baseline-20260706.
|
||||
EOF
|
||||
cat > docs/gitops/CHATGPT_CODEX_ACCESS.md <<'EOF'
|
||||
# ChatGPT / Codex GitOps Access
|
||||
|
||||
Entry: https://cnnetmkt.top
|
||||
|
||||
Short links: /git, /base, /ver, /diff, /patch, /model, /run, /api, /hook.
|
||||
|
||||
All writes must become Git commits. Fixes must use patch branches. Releases must use VxRxCx tags.
|
||||
|
||||
Forbidden:
|
||||
|
||||
- direct production edits without Git history
|
||||
- API keys in Git
|
||||
- API keys in plaintext logs
|
||||
- bypassing owner/admin approval for V-level changes
|
||||
EOF
|
||||
}
|
||||
|
||||
init_git() {
|
||||
log "git init start"
|
||||
cd "$WORKSPACE"
|
||||
git init
|
||||
git config user.name "AIOS GitOps Bot"
|
||||
git config user.email "gitops-bot@cnnetmkt.top"
|
||||
if [ ! -f .gitignore ]; then
|
||||
cat > .gitignore <<'EOF'
|
||||
.env
|
||||
*.secret
|
||||
*.key
|
||||
*.pem
|
||||
*.log
|
||||
__pycache__/
|
||||
node_modules/
|
||||
.venv/
|
||||
.DS_Store
|
||||
runtime/tmp/
|
||||
runtime/cache/
|
||||
logs/
|
||||
EOF
|
||||
fi
|
||||
git add .
|
||||
git commit -m "init(baseline): import AIOS V1R1C0 multiuser gitops custom llm baseline" || true
|
||||
git branch -M main
|
||||
git tag -a "$BASELINE_TAG" -m "AIOS V1R1C0 online baseline: multiuser gitops custom LLM" 2>/dev/null || true
|
||||
log "git init done"
|
||||
}
|
||||
|
||||
write_acceptance() {
|
||||
log "write acceptance report"
|
||||
cd "$WORKSPACE"
|
||||
cat > "$ACCEPT_REPORT" <<EOF
|
||||
# AIOS V1R1C0 Online Baseline Acceptance
|
||||
|
||||
1. server: $(hostname)
|
||||
2. zip_path: $ZIP_PATH
|
||||
3. npm_reused: PARTIAL_UNVERIFIED
|
||||
4. webops_reused: YES_DETECTED
|
||||
5. casdoor_reused: PARTIAL_UNVERIFIED
|
||||
6. openclaw_reused: YES_DETECTED
|
||||
7. hermes_reused: YES_DETECTED
|
||||
8. one_api_reused: YES_DETECTED
|
||||
9. git_service: LOCAL_GIT_READY_REMOTE_UI_PENDING
|
||||
10. git_url: PENDING_GITEA_OR_EXISTING_GIT_SERVICE
|
||||
11. short_links: /git,/base,/ver,/diff,/patch,/model,/run,/api,/hook
|
||||
12. baseline_version: V1R1C0
|
||||
13. baseline_tag: $BASELINE_TAG
|
||||
14. custom_llm_api: PACKAGE_UAT_PASS_ONLINE_ROUTE_PENDING
|
||||
15. model_priority: PACKAGE_UAT_PASS_ONLINE_ROUTE_PENDING
|
||||
16. runtime_selector: PACKAGE_UAT_PASS_ONLINE_ROUTE_PENDING
|
||||
17. gitops_patch: BASELINE_COMMIT_AND_TAG_READY
|
||||
18. smoke_test: PACKAGE_CHECKS_PASS
|
||||
19. known_issues:
|
||||
- NPM custom locations were not modified by this script.
|
||||
- Gitea/Web Git UI push was not completed by this script.
|
||||
- Spark sub-agent quota was unavailable during orchestration.
|
||||
20. next_update_mode: git_patch_only
|
||||
|
||||
## Git Evidence
|
||||
EOF
|
||||
{
|
||||
printf '\n### git status --short\n\n'
|
||||
git status --short
|
||||
printf '\n### git log --oneline -10\n\n'
|
||||
git log --oneline -10
|
||||
printf '\n### git tag grep V1R1C0\n\n'
|
||||
git tag | grep V1R1C0 || true
|
||||
} >> "$ACCEPT_REPORT"
|
||||
}
|
||||
|
||||
main() {
|
||||
preflight
|
||||
backup_state
|
||||
import_zip
|
||||
run_package_checks
|
||||
write_baseline_files
|
||||
init_git
|
||||
write_acceptance
|
||||
log "MIGRATION_LOCAL_BASELINE_OK"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="/data/aios-gitops"
|
||||
WORKSPACE="$ROOT/workspace"
|
||||
LOG="$ROOT/logs/runtime-services-v1r1c0.log"
|
||||
mkdir -p "$ROOT/logs" "$ROOT/runtime/secrets" "$WORKSPACE/deploy/systemd" "$WORKSPACE/deploy/gitea"
|
||||
touch "$LOG"
|
||||
|
||||
log() {
|
||||
printf '[%s] %s\n' "$(date -Is)" "$*" | tee -a "$LOG"
|
||||
}
|
||||
|
||||
cd "$WORKSPACE"
|
||||
|
||||
TOKEN_FILE="$ROOT/runtime/secrets/gitops.tokens"
|
||||
if [ ! -s "$TOKEN_FILE" ]; then
|
||||
(openssl rand -hex 32 || python3 -c 'import secrets; print(secrets.token_hex(32))') > "$TOKEN_FILE"
|
||||
chmod 600 "$TOKEN_FILE"
|
||||
fi
|
||||
|
||||
cat > deploy/systemd/aios-gitops-model-api.service <<EOF
|
||||
[Unit]
|
||||
Description=AIOS V1R1C0 GitOps Model API
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=aiman
|
||||
Group=aiman
|
||||
Environment=AIOS_GITOPS_ROOT=$ROOT
|
||||
Environment=AIOS_GITOPS_WORKSPACE=$WORKSPACE
|
||||
Environment=AIOS_GITOPS_DB=$ROOT/runtime/gitops_model.sqlite3
|
||||
Environment=AIOS_GITOPS_TOKEN_FILE=$TOKEN_FILE
|
||||
Environment=AIOS_GITOPS_HOST=127.0.0.1
|
||||
Environment=AIOS_GITOPS_PORT=18890
|
||||
ExecStart=/usr/bin/python3 $WORKSPACE/active-runtime/app/aios_gitops_model_api.py
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat > deploy/gitea/docker-compose.yml <<'EOF'
|
||||
services:
|
||||
gitea:
|
||||
image: gitea/gitea:1.22
|
||||
container_name: aios-gitea
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- USER_UID=1000
|
||||
- USER_GID=1000
|
||||
- GITEA__server__DOMAIN=cnnetmkt.top
|
||||
- GITEA__server__ROOT_URL=https://cnnetmkt.top/git/
|
||||
- GITEA__server__SERVE_FROM_SUB_PATH=true
|
||||
- GITEA__server__HTTP_PORT=3000
|
||||
- GITEA__server__SSH_DOMAIN=cnnetmkt.top
|
||||
- GITEA__server__SSH_PORT=2222
|
||||
- GITEA__service__DISABLE_REGISTRATION=true
|
||||
- GITEA__webhook__ALLOWED_HOST_LIST=*
|
||||
- GITEA__database__DB_TYPE=sqlite3
|
||||
volumes:
|
||||
- /data/aios-gitops/runtime/gitea:/data
|
||||
ports:
|
||||
- "127.0.0.1:3000:3000"
|
||||
- "127.0.0.1:2222:22"
|
||||
EOF
|
||||
|
||||
git add deploy/systemd/aios-gitops-model-api.service deploy/gitea/docker-compose.yml
|
||||
git commit -m "chore(gitops): add V1R1C0 runtime API and Gitea deployment manifests" || true
|
||||
|
||||
log "install API systemd unit"
|
||||
sudo cp deploy/systemd/aios-gitops-model-api.service /etc/systemd/system/aios-gitops-model-api.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now aios-gitops-model-api.service
|
||||
sleep 2
|
||||
systemctl is-active aios-gitops-model-api.service | tee -a "$LOG"
|
||||
curl -fsS http://127.0.0.1:18890/health | tee -a "$LOG"
|
||||
|
||||
log "start gitea"
|
||||
mkdir -p "$ROOT/adapters/gitea"
|
||||
cp deploy/gitea/docker-compose.yml "$ROOT/adapters/gitea/docker-compose.yml"
|
||||
(cd "$ROOT/adapters/gitea" && docker compose up -d)
|
||||
|
||||
for i in $(seq 1 60); do
|
||||
if curl -fsS http://127.0.0.1:3000/git/api/healthz >/dev/null 2>&1 || curl -fsS http://127.0.0.1:3000/git/ >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
curl -fsS http://127.0.0.1:3000/git/ >/dev/null || true
|
||||
docker ps --format '{{.Names}} {{.Image}} {{.Status}} {{.Ports}}' | grep -E '^aios-gitea ' | tee -a "$LOG" || true
|
||||
|
||||
log "runtime manifests committed and services attempted"
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="/data/aios-gitops"
|
||||
WORKSPACE="$ROOT/workspace"
|
||||
|
||||
cd "$WORKSPACE"
|
||||
git add active-runtime/app/aios_gitops_model_api.py scripts/hermes_gitops_parallel_agents.py
|
||||
git commit -m "fix(gitops): align baseline tag and secret scan" || true
|
||||
|
||||
python3 - <<'PY'
|
||||
import datetime
|
||||
import sqlite3
|
||||
|
||||
p = "/data/aios-gitops/runtime/gitops_model.sqlite3"
|
||||
con = sqlite3.connect(p)
|
||||
con.execute(
|
||||
"UPDATE gitops_baseline SET active_version=?, active_tag=?, source_package=?, update_mode=?, updated_at=? WHERE id=?",
|
||||
(
|
||||
"V1R1C0",
|
||||
"V1R1C0-baseline-20260706",
|
||||
"AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip",
|
||||
"git_patch_only",
|
||||
datetime.datetime.utcnow().isoformat() + "Z",
|
||||
"current",
|
||||
),
|
||||
)
|
||||
con.commit()
|
||||
con.close()
|
||||
PY
|
||||
|
||||
sudo chown -R aiman:aiman "$ROOT/runtime" "$WORKSPACE" "$ROOT/logs" "$ROOT/artifacts"
|
||||
sudo systemctl restart aios-gitops-model-api.service
|
||||
sleep 2
|
||||
curl -fsS http://127.0.0.1:18890/api/status
|
||||
echo
|
||||
python3 scripts/hermes_gitops_parallel_agents.py
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="/data/aios-gitops"
|
||||
WORKSPACE="$ROOT/workspace"
|
||||
NGINX_SITE="/etc/nginx/sites-enabled/aios-user-portal.conf"
|
||||
BACKUP_DIR="$ROOT/backups/nginx-gitops-$(date +%Y%m%d-%H%M%S)"
|
||||
LOG="$ROOT/logs/nginx-gitops-routes.log"
|
||||
mkdir -p "$BACKUP_DIR" "$ROOT/logs" "$WORKSPACE/deploy/nginx"
|
||||
exec > >(tee -a "$LOG") 2>&1
|
||||
|
||||
cd "$WORKSPACE"
|
||||
|
||||
cat > deploy/nginx/aios-gitops-locations.conf <<'EOF'
|
||||
# BEGIN AIOS V1R1C0 GitOps short links
|
||||
location = /git { return 302 /git/; }
|
||||
location /git/ {
|
||||
proxy_pass http://127.0.0.1:3000/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Prefix /git;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location = /api { return 302 /api/; }
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:18890/api/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location = /base { proxy_pass http://127.0.0.1:18890/base; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
|
||||
location = /ver { proxy_pass http://127.0.0.1:18890/ver; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
|
||||
location = /diff { proxy_pass http://127.0.0.1:18890/diff; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
|
||||
location = /patch { proxy_pass http://127.0.0.1:18890/patch; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
|
||||
location = /model { proxy_pass http://127.0.0.1:18890/model; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
|
||||
location = /run { proxy_pass http://127.0.0.1:18890/run; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
|
||||
location = /hook { proxy_pass http://127.0.0.1:18890/hook; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; }
|
||||
location /hook/ {
|
||||
proxy_pass http://127.0.0.1:18890/hook/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
# END AIOS V1R1C0 GitOps short links
|
||||
EOF
|
||||
|
||||
git add deploy/nginx/aios-gitops-locations.conf active-runtime/app/aios_gitops_model_api.py
|
||||
git commit -m "feat(gitops): add nginx short links and webhook endpoint" || true
|
||||
|
||||
echo "== backup nginx site =="
|
||||
sudo cp -a "$NGINX_SITE" "$BACKUP_DIR/aios-user-portal.conf"
|
||||
|
||||
echo "== insert locations =="
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
|
||||
site = Path("/etc/nginx/sites-enabled/aios-user-portal.conf")
|
||||
snippet = Path("/data/aios-gitops/workspace/deploy/nginx/aios-gitops-locations.conf").read_text()
|
||||
text = site.read_text()
|
||||
start = " # BEGIN AIOS V1R1C0 GitOps short links"
|
||||
end = " # END AIOS V1R1C0 GitOps short links"
|
||||
if start in text:
|
||||
before = text.split(start)[0]
|
||||
after = text.split(end, 1)[1]
|
||||
text = before + snippet + after
|
||||
else:
|
||||
marker = " location / {\n"
|
||||
if marker not in text:
|
||||
raise SystemExit("location marker not found")
|
||||
text = text.replace(marker, snippet + "\n" + marker, 1)
|
||||
Path("/tmp/aios-user-portal.conf.gitops").write_text(text)
|
||||
PY
|
||||
sudo cp /tmp/aios-user-portal.conf.gitops "$NGINX_SITE"
|
||||
|
||||
echo "== nginx test and reload =="
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
|
||||
echo "== local route checks =="
|
||||
for path in /git/ /base /ver /model /run /hook /api/status; do
|
||||
echo "== ${path} =="
|
||||
curl -k -sS -I --resolve cnnetmkt.top:443:127.0.0.1 "https://cnnetmkt.top${path}" | sed -n '1,12p' || true
|
||||
done
|
||||
echo "NGINX_GITOPS_ROUTES_OK backup=$BACKUP_DIR"
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
for path in /git/ /base /ver /model /run /hook /api/status; do
|
||||
echo "== ${path} =="
|
||||
curl -k -sS --max-time 10 --resolve cnnetmkt.top:443:127.0.0.1 "https://cnnetmkt.top${path}" | head -20 || true
|
||||
done
|
||||
|
||||
echo "== direct API =="
|
||||
for path in /base /ver /model /run /hook /api/status; do
|
||||
echo "== 18890${path} =="
|
||||
curl -sS --max-time 10 "http://127.0.0.1:18890${path}" | head -10 || true
|
||||
done
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="/data/aios-gitops"
|
||||
WORKSPACE="$ROOT/workspace"
|
||||
ARTIFACT="$ROOT/artifacts/AIOS_V1R1C0_ONLINE_BASELINE_ACCEPTANCE.md"
|
||||
REPORT_IN_REPO="$WORKSPACE/docs/release/AIOS_V1R1C0_ONLINE_BASELINE_ACCEPTANCE.md"
|
||||
EVIDENCE="$ROOT/artifacts/AIOS_V1R1C0_FINAL_EVIDENCE.txt"
|
||||
VERSION="V1R1C0"
|
||||
TAG="V1R1C0-baseline-20260706"
|
||||
SOURCE="AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip"
|
||||
GIT_URL="https://cnnetmkt.top/git/aios/aios-v23.git"
|
||||
|
||||
mkdir -p "$ROOT/artifacts" "$ROOT/logs" "$WORKSPACE/docs/release"
|
||||
|
||||
python3 - <<'PY'
|
||||
import json
|
||||
import sqlite3
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
root = Path("/data/aios-gitops")
|
||||
workspace = root / "workspace"
|
||||
db = root / "runtime" / "gitops_model.sqlite3"
|
||||
version = "V1R1C0"
|
||||
tag = "V1R1C0-baseline-20260706"
|
||||
source = "AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip"
|
||||
entry = "https://cnnetmkt.top"
|
||||
git_url = "https://cnnetmkt.top/git/aios/aios-v23.git"
|
||||
short_links = ["/git", "/base", "/ver", "/diff", "/patch", "/model", "/run", "/api", "/hook"]
|
||||
|
||||
current_path = workspace / "baseline" / "current.json"
|
||||
current = {}
|
||||
if current_path.exists():
|
||||
current = json.loads(current_path.read_text(encoding="utf-8"))
|
||||
current.update({
|
||||
"version": version,
|
||||
"active_version": version,
|
||||
"baseline_tag": tag,
|
||||
"active_tag": tag,
|
||||
"source": source,
|
||||
"source_package": source,
|
||||
"mode": "gitops-online",
|
||||
"update_mode": "git_patch_only",
|
||||
"zip_update_mode": "deprecated",
|
||||
"chatgpt_access": True,
|
||||
"codex_access": True,
|
||||
"git_url": git_url,
|
||||
"entry": entry,
|
||||
"short_links": short_links,
|
||||
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||
})
|
||||
current_path.write_text(json.dumps(current, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
version_path = workspace / "versions" / "V1R1C0.json"
|
||||
version_doc = {}
|
||||
if version_path.exists():
|
||||
version_doc = json.loads(version_path.read_text(encoding="utf-8"))
|
||||
version_doc.update({
|
||||
"version": version,
|
||||
"tag": tag,
|
||||
"baseline_tag": tag,
|
||||
"source": source,
|
||||
"update_mode": "git_patch_only",
|
||||
"zip_update_mode": "deprecated",
|
||||
"git_url": git_url,
|
||||
"updated_at": datetime.now(timezone.utc).isoformat(),
|
||||
})
|
||||
version_path.write_text(json.dumps(version_doc, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
if db.exists():
|
||||
con = sqlite3.connect(db)
|
||||
try:
|
||||
con.execute(
|
||||
"UPDATE gitops_baseline SET active_version=?, active_tag=?, source_package=?, entry=?, update_mode=?, status=?, updated_at=? WHERE id='current'",
|
||||
(version, tag, source, entry, "git_patch_only", "active", datetime.now(timezone.utc).isoformat()),
|
||||
)
|
||||
con.execute(
|
||||
"UPDATE gitops_versions SET tag=?, status=? WHERE version=?",
|
||||
(tag, "ready", version),
|
||||
)
|
||||
con.commit()
|
||||
finally:
|
||||
con.close()
|
||||
PY
|
||||
|
||||
cd "$WORKSPACE"
|
||||
|
||||
{
|
||||
echo "== services =="
|
||||
systemctl is-active aios-gitops-model-api aios-gitea aios-hermes-router aios-hermes-executor openclaw-gateway nginx || true
|
||||
echo
|
||||
echo "== gitea =="
|
||||
curl -fsS http://127.0.0.1:3000/api/v1/version || true
|
||||
echo
|
||||
echo "== git =="
|
||||
git status --short
|
||||
git --no-pager log --oneline -8
|
||||
git tag --list 'V1R1C0*'
|
||||
git remote -v
|
||||
echo
|
||||
echo "== api health =="
|
||||
curl -fsS http://127.0.0.1:18890/health
|
||||
echo
|
||||
curl -fsS http://127.0.0.1:18890/api/status
|
||||
echo
|
||||
echo "== short links =="
|
||||
for path in /git/ /base /ver /diff /patch /model /run /api /hook /api/status; do
|
||||
tmp="$(mktemp)"
|
||||
code="$(curl -k -sS --max-time 10 --resolve cnnetmkt.top:443:127.0.0.1 -o "$tmp" -w "%{http_code}" "https://cnnetmkt.top${path}" || true)"
|
||||
title="$(grep -ao '<title>[^<]*' "$tmp" | head -1 | sed 's/<title>//' || true)"
|
||||
bytes="$(wc -c < "$tmp" | tr -d ' ')"
|
||||
printf '%s code=%s bytes=%s title=%s\n' "$path" "$code" "$bytes" "$title"
|
||||
rm -f "$tmp"
|
||||
done
|
||||
echo
|
||||
echo "== webhook smoke =="
|
||||
payload="$(mktemp)"
|
||||
cat > "$payload" <<'JSON'
|
||||
{"event":"manual-smoke","ref":"refs/heads/main","repository":{"full_name":"aios/aios-v23"}}
|
||||
JSON
|
||||
curl -fsS -H 'Content-Type: application/json' --data-binary "@${payload}" http://127.0.0.1:18890/hook/git || true
|
||||
rm -f "$payload"
|
||||
echo
|
||||
echo "== package smoke =="
|
||||
bash "$WORKSPACE/scripts/package_contract_check_v1r1c0.sh" || true
|
||||
echo
|
||||
echo "== hermes =="
|
||||
curl -fsS http://127.0.0.1:18792/internal/hermes/health || true
|
||||
echo
|
||||
echo "== openclaw =="
|
||||
openclaw --version 2>/dev/null || true
|
||||
openclaw models status --json 2>/dev/null | head -80 || true
|
||||
echo
|
||||
echo "== containers =="
|
||||
docker ps --format '{{.Names}} {{.Image}} {{.Ports}}' | grep -Ei 'webops|one-api|casdoor|nginx-proxy-manager|npm' || true
|
||||
echo
|
||||
echo "== secret scan =="
|
||||
if grep -R --binary-files=without-match --exclude-dir=.git -E 'sk-[A-Za-z0-9_-]{20,}|AIza[0-9A-Za-z_-]{20,}|xox[baprs]-[0-9A-Za-z-]{20,}' -n "$WORKSPACE" "$ROOT/logs" "$ROOT/artifacts" 2>/dev/null | head -20; then
|
||||
echo "SECRET_SCAN=FAILED"
|
||||
else
|
||||
echo "SECRET_SCAN=OK"
|
||||
fi
|
||||
} | tee "$EVIDENCE"
|
||||
|
||||
cat > "$ARTIFACT" <<EOF_REPORT
|
||||
# AIOS V1R1C0 Online Baseline Acceptance
|
||||
|
||||
AIOS_V1R1C0_ONLINE_BASELINE_STATUS=PARTIAL
|
||||
DOMAIN=https://cnnetmkt.top
|
||||
SHORT_LINKS=/git,/base,/ver,/diff,/patch,/model,/run,/api,/hook
|
||||
PROXY=NGINX_TEMP (NPM_NOT_RUNNING)
|
||||
GIT_URL=$GIT_URL
|
||||
BASELINE_VERSION=$VERSION
|
||||
BASELINE_TAG=$TAG
|
||||
WORKSPACE=$WORKSPACE
|
||||
WEBOPS_REUSED=YES
|
||||
CASDOOR_REUSED=PARTIAL
|
||||
OPENCLAW_REUSED=PARTIAL
|
||||
HERMES_REUSED=YES
|
||||
ONE_API_REUSED=YES
|
||||
GITEA_REUSED=NEW
|
||||
CUSTOM_LLM_STATUS=OK
|
||||
MODEL_PRIORITY_STATUS=OK
|
||||
RUNTIME_SELECTOR_STATUS=OK
|
||||
ACCEPTANCE_REPORT=$ARTIFACT
|
||||
KNOWN_ISSUES=NPM is not running on this host, so system nginx currently serves the short links; OpenClaw gateway is active but native openclaw agent execution still needs gateway/provider credentials; host-side DNS resolution for cnnetmkt.top is unreliable, so local validation used --resolve to 127.0.0.1; Docker Hub pull for Gitea was blocked by the existing Docker proxy path and was replaced with official Gitea binary deployment.
|
||||
NEXT_UPDATE_MODE=git_patch_only
|
||||
ZIP_UPDATE_MODE=deprecated
|
||||
|
||||
## Evidence
|
||||
|
||||
- Imported package: /data/aios-gitops/imports/$SOURCE
|
||||
- Package SHA256: dbee5d45aab02aab33e862bb9beb6115b3b43137e0fb5e00c98448ac1ecfd0f9
|
||||
- Git workspace: $WORKSPACE
|
||||
- Baseline branch: main
|
||||
- Baseline tag: $TAG
|
||||
- Git remote: $GIT_URL
|
||||
- Gitea internal version: 1.22.6
|
||||
- API service: aios-gitops-model-api.service on 127.0.0.1:18890
|
||||
- Gitea service: aios-gitea.service on 127.0.0.1:3000
|
||||
- Hermes executor health: ok
|
||||
- One API reused at: 127.0.0.1:13000
|
||||
- WebOps reused container: aios-webops-server-hw-webops-1
|
||||
- Parallel server agents: git_service_agent, entry_proxy_agent, gitops_api_uat_agent, acceptance_report_agent
|
||||
- Parallel agent report: /data/aios-gitops/artifacts/AIOS_V1R1C0_PARALLEL_AGENT_STATUS.json
|
||||
- Final evidence log: $EVIDENCE
|
||||
|
||||
## GitOps Rules
|
||||
|
||||
- ZIP update mode is deprecated after initial import.
|
||||
- Future updates must be git branch + commit + push + webhook.
|
||||
- Patches are represented as git branches and are reviewable by diff.
|
||||
- ChatGPT/Codex write path is /api/git-control-compatible endpoints exposed by the GitOps API.
|
||||
EOF_REPORT
|
||||
|
||||
cp "$ARTIFACT" "$REPORT_IN_REPO"
|
||||
|
||||
git add baseline/current.json versions/V1R1C0.json docs/release/AIOS_V1R1C0_ONLINE_BASELINE_ACCEPTANCE.md
|
||||
git commit -m "docs(gitops): finalize V1R1C0 online baseline acceptance" || true
|
||||
|
||||
admin_user="aios"
|
||||
admin_pass_file="$ROOT/runtime/secrets/gitea-admin-password"
|
||||
if [ -s "$admin_pass_file" ]; then
|
||||
tmp_home="$(mktemp -d)"
|
||||
chmod 700 "$tmp_home"
|
||||
{
|
||||
echo "machine 127.0.0.1"
|
||||
echo "login $admin_user"
|
||||
echo "password $(cat "$admin_pass_file")"
|
||||
} > "$tmp_home/.netrc"
|
||||
chmod 600 "$tmp_home/.netrc"
|
||||
HOME="$tmp_home" git push http://127.0.0.1:3000/aios/aios-v23.git main
|
||||
HOME="$tmp_home" git push http://127.0.0.1:3000/aios/aios-v23.git --tags
|
||||
rm -rf "$tmp_home"
|
||||
fi
|
||||
|
||||
git remote remove origin 2>/dev/null || true
|
||||
git remote add origin "$GIT_URL"
|
||||
git status --short
|
||||
echo "FINALIZE_V1R1C0_GITOPS_ACCEPTANCE_DONE"
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="/data/aios-gitops"
|
||||
WORKSPACE="$ROOT/workspace"
|
||||
GITEA_BIN="$ROOT/runtime/bin/gitea"
|
||||
GITEA_HOME="$ROOT/runtime/gitea-bin"
|
||||
SECRETS="$ROOT/runtime/secrets"
|
||||
LOG="$ROOT/logs/gitea-repo-push-fix.log"
|
||||
mkdir -p "$ROOT/logs"
|
||||
exec > >(tee -a "$LOG") 2>&1
|
||||
|
||||
admin_user="aios"
|
||||
admin_pass="$(cat "$SECRETS/gitea-admin-password")"
|
||||
|
||||
echo "== endpoint probe =="
|
||||
for path in / /git/ /api/v1/version /git/api/v1/version /user/login /git/user/login; do
|
||||
echo "== ${path} =="
|
||||
curl -sS -i --max-time 8 "http://127.0.0.1:3000${path}" 2>&1 | sed -n '1,18p'
|
||||
done
|
||||
|
||||
echo "== ensure admin user =="
|
||||
"$GITEA_BIN" admin user create \
|
||||
--config "$GITEA_HOME/custom/conf/app.ini" \
|
||||
--username "$admin_user" \
|
||||
--password "$admin_pass" \
|
||||
--email "gitops-bot@cnnetmkt.top" \
|
||||
--admin \
|
||||
--must-change-password=false 2>/dev/null || true
|
||||
|
||||
echo "== create repo by internal API =="
|
||||
if ! curl -fsS -u "$admin_user:$admin_pass" "http://127.0.0.1:3000/api/v1/repos/$admin_user/aios-v23" >/dev/null 2>&1; then
|
||||
curl -fsS -u "$admin_user:$admin_pass" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"aios-v23","description":"AIOS V1R1C0 online GitOps baseline","private":false,"auto_init":false,"default_branch":"main"}' \
|
||||
"http://127.0.0.1:3000/api/v1/user/repos" >/dev/null
|
||||
fi
|
||||
curl -fsS -u "$admin_user:$admin_pass" "http://127.0.0.1:3000/api/v1/repos/$admin_user/aios-v23" | python3 -m json.tool | sed -n '1,80p'
|
||||
|
||||
echo "== push main and tags =="
|
||||
cd "$WORKSPACE"
|
||||
push_url="http://${admin_user}:${admin_pass}@127.0.0.1:3000/${admin_user}/aios-v23.git"
|
||||
git push "$push_url" main
|
||||
git push "$push_url" --tags
|
||||
git remote remove origin 2>/dev/null || true
|
||||
git remote add origin "https://cnnetmkt.top/git/${admin_user}/aios-v23.git"
|
||||
|
||||
echo "== verify repo page =="
|
||||
curl -fsS "http://127.0.0.1:3000/${admin_user}/aios-v23" | grep -E "aios-v23|AIOS|V1R1C0" | head -30 || true
|
||||
git remote -v
|
||||
git log --oneline -8
|
||||
git status --short
|
||||
echo "GITEA_REPO_PUSH_OK"
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="/data/aios-gitops"
|
||||
WORKSPACE="$ROOT/workspace"
|
||||
LOG="$ROOT/logs/gitops-api-owner-fix-uat.log"
|
||||
mkdir -p "$ROOT/logs"
|
||||
exec > >(tee -a "$LOG") 2>&1
|
||||
|
||||
echo "== fix ownership =="
|
||||
sudo chown -R aiman:aiman "$ROOT/runtime" "$WORKSPACE" "$ROOT/logs" "$ROOT/artifacts"
|
||||
|
||||
echo "== commit sanitized runner =="
|
||||
cd "$WORKSPACE"
|
||||
git add scripts/hermes_gitops_parallel_agents.py
|
||||
git commit -m "fix(gitops): sanitize parallel agent UAT secret handling" || true
|
||||
|
||||
echo "== restart API =="
|
||||
sudo systemctl restart aios-gitops-model-api.service
|
||||
sleep 3
|
||||
systemctl status aios-gitops-model-api.service --no-pager | sed -n '1,100p'
|
||||
curl -fsS http://127.0.0.1:18890/health
|
||||
echo
|
||||
curl -fsS http://127.0.0.1:18890/api/status
|
||||
echo
|
||||
|
||||
echo "== API UAT =="
|
||||
TOKEN="$(head -1 "$ROOT/runtime/secrets/gitops.tokens")"
|
||||
curl -fsS \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H 'X-AIOS-User: agent-uat' \
|
||||
-H 'X-AIOS-Role: owner' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"username":"agent-uat","role":"owner","tier":"ultra"}' \
|
||||
http://127.0.0.1:18890/api/runtime/select
|
||||
echo
|
||||
curl -fsS \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H 'X-AIOS-User: agent-uat' \
|
||||
-H 'X-AIOS-Role: owner' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"provider_name":"agent-local-openai-compatible","base_url":"http://127.0.0.1:13000/v1","model_name":"agent-test-model","display_name":"Agent Test Model","priority":10,"api_key_secret_ref":"secret://llm/agent-uat/pre-provisioned-test"}' \
|
||||
http://127.0.0.1:18890/api/model/custom/add
|
||||
echo
|
||||
curl -fsS \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H 'X-AIOS-User: agent-uat' \
|
||||
-H 'X-AIOS-Role: owner' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"username":"agent-uat"}' \
|
||||
http://127.0.0.1:18890/api/model/route/resolve
|
||||
echo
|
||||
|
||||
echo "== secret scan =="
|
||||
if grep -R 'redacted-test-key\|sk-[A-Za-z0-9]' -n "$WORKSPACE" "$ROOT/logs" 2>/dev/null; then
|
||||
echo "SECRET_SCAN_FAILED"
|
||||
exit 2
|
||||
fi
|
||||
echo "SECRET_SCAN_OK"
|
||||
|
||||
echo "== git status =="
|
||||
git status --short
|
||||
git log --oneline -8
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="/data/aios-gitops"
|
||||
WORKSPACE="$ROOT/workspace"
|
||||
GITEA_HOME="$ROOT/runtime/gitea-bin"
|
||||
GITEA_BIN="$ROOT/runtime/bin/gitea"
|
||||
GITEA_VERSION="1.22.6"
|
||||
GITEA_URL="https://dl.gitea.com/gitea/${GITEA_VERSION}/gitea-${GITEA_VERSION}-linux-amd64"
|
||||
SECRETS="$ROOT/runtime/secrets"
|
||||
LOG="$ROOT/logs/gitea-binary-install.log"
|
||||
|
||||
mkdir -p "$ROOT/logs" "$SECRETS" "$ROOT/runtime/bin" "$GITEA_HOME/custom/conf" "$GITEA_HOME/data" "$GITEA_HOME/log" "$WORKSPACE/deploy/gitea-binary"
|
||||
exec > >(tee -a "$LOG") 2>&1
|
||||
|
||||
cd "$WORKSPACE"
|
||||
|
||||
echo "== write tracked deployment manifests =="
|
||||
cat > deploy/gitea-binary/app.ini.template <<'EOF'
|
||||
APP_NAME = AIOS GitOps
|
||||
RUN_USER = aiman
|
||||
WORK_PATH = /data/aios-gitops/runtime/gitea-bin
|
||||
|
||||
[server]
|
||||
PROTOCOL = http
|
||||
HTTP_ADDR = 127.0.0.1
|
||||
HTTP_PORT = 3000
|
||||
DOMAIN = cnnetmkt.top
|
||||
ROOT_URL = https://cnnetmkt.top/git/
|
||||
SERVE_FROM_SUB_PATH = true
|
||||
DISABLE_SSH = true
|
||||
OFFLINE_MODE = false
|
||||
|
||||
[database]
|
||||
DB_TYPE = sqlite3
|
||||
PATH = /data/aios-gitops/runtime/gitea-bin/data/gitea.db
|
||||
|
||||
[repository]
|
||||
ROOT = /data/aios-gitops/runtime/gitea-bin/data/repositories
|
||||
DEFAULT_BRANCH = main
|
||||
|
||||
[security]
|
||||
INSTALL_LOCK = true
|
||||
SECRET_KEY = __SECRET_KEY__
|
||||
INTERNAL_TOKEN = __INTERNAL_TOKEN__
|
||||
|
||||
[service]
|
||||
DISABLE_REGISTRATION = true
|
||||
REQUIRE_SIGNIN_VIEW = false
|
||||
|
||||
[webhook]
|
||||
ALLOWED_HOST_LIST = *
|
||||
|
||||
[log]
|
||||
MODE = console
|
||||
LEVEL = Info
|
||||
ROOT_PATH = /data/aios-gitops/runtime/gitea-bin/log
|
||||
EOF
|
||||
|
||||
cat > deploy/gitea-binary/aios-gitea.service <<EOF
|
||||
[Unit]
|
||||
Description=AIOS GitOps Gitea
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=aiman
|
||||
Group=aiman
|
||||
WorkingDirectory=$GITEA_HOME
|
||||
ExecStart=$GITEA_BIN web --config $GITEA_HOME/custom/conf/app.ini
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
Environment=USER=aiman
|
||||
Environment=HOME=/home/aiman
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
git add deploy/gitea-binary/app.ini.template deploy/gitea-binary/aios-gitea.service
|
||||
git commit -m "chore(gitops): add binary Gitea deployment manifests" || true
|
||||
|
||||
echo "== download gitea binary =="
|
||||
if [ ! -x "$GITEA_BIN" ]; then
|
||||
tmp="$GITEA_BIN.tmp"
|
||||
curl -fL --retry 3 --connect-timeout 20 -o "$tmp" "$GITEA_URL"
|
||||
chmod 755 "$tmp"
|
||||
mv "$tmp" "$GITEA_BIN"
|
||||
fi
|
||||
"$GITEA_BIN" --version
|
||||
|
||||
echo "== render runtime app.ini =="
|
||||
secret_key_file="$SECRETS/gitea-secret-key"
|
||||
internal_token_file="$SECRETS/gitea-internal-token"
|
||||
admin_pass_file="$SECRETS/gitea-admin-password"
|
||||
api_token_file="$SECRETS/gitea-api-token"
|
||||
for f in "$secret_key_file" "$internal_token_file" "$admin_pass_file"; do
|
||||
if [ ! -s "$f" ]; then
|
||||
openssl rand -hex 32 > "$f"
|
||||
chmod 600 "$f"
|
||||
fi
|
||||
done
|
||||
sed \
|
||||
-e "s#__SECRET_KEY__#$(cat "$secret_key_file")#g" \
|
||||
-e "s#__INTERNAL_TOKEN__#$(cat "$internal_token_file")#g" \
|
||||
deploy/gitea-binary/app.ini.template > "$GITEA_HOME/custom/conf/app.ini"
|
||||
chmod 600 "$GITEA_HOME/custom/conf/app.ini"
|
||||
sudo chown -R aiman:aiman "$ROOT/runtime" "$WORKSPACE/deploy/gitea-binary"
|
||||
|
||||
echo "== install systemd service =="
|
||||
sudo cp deploy/gitea-binary/aios-gitea.service /etc/systemd/system/aios-gitea.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now aios-gitea.service
|
||||
|
||||
echo "== wait gitea =="
|
||||
for i in $(seq 1 90); do
|
||||
if curl -fsS http://127.0.0.1:3000/git/api/healthz >/dev/null 2>&1 || curl -fsS http://127.0.0.1:3000/git/ >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
systemctl is-active aios-gitea.service
|
||||
curl -fsS http://127.0.0.1:3000/git/api/healthz || true
|
||||
echo
|
||||
|
||||
echo "== create admin user and repo =="
|
||||
admin_user="aios"
|
||||
admin_email="gitops-bot@cnnetmkt.top"
|
||||
admin_pass="$(cat "$admin_pass_file")"
|
||||
"$GITEA_BIN" admin user create \
|
||||
--config "$GITEA_HOME/custom/conf/app.ini" \
|
||||
--username "$admin_user" \
|
||||
--password "$admin_pass" \
|
||||
--email "$admin_email" \
|
||||
--admin \
|
||||
--must-change-password=false 2>/dev/null || true
|
||||
|
||||
if [ ! -s "$api_token_file" ]; then
|
||||
"$GITEA_BIN" admin user generate-access-token \
|
||||
--config "$GITEA_HOME/custom/conf/app.ini" \
|
||||
--username "$admin_user" \
|
||||
--token-name aios-gitops-push \
|
||||
--scopes write:repository,read:repository,write:user,read:user \
|
||||
| awk '/Access token was successfully created/ {print $NF}' > "$api_token_file.tmp" || true
|
||||
if [ -s "$api_token_file.tmp" ]; then
|
||||
mv "$api_token_file.tmp" "$api_token_file"
|
||||
chmod 600 "$api_token_file"
|
||||
else
|
||||
rm -f "$api_token_file.tmp"
|
||||
fi
|
||||
fi
|
||||
|
||||
repo_api="http://127.0.0.1:3000/git/api/v1/user/repos"
|
||||
if ! curl -fsS -u "$admin_user:$admin_pass" "http://127.0.0.1:3000/git/api/v1/repos/$admin_user/aios-v23" >/dev/null 2>&1; then
|
||||
curl -fsS -u "$admin_user:$admin_pass" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"aios-v23","description":"AIOS V1R1C0 online GitOps baseline","private":false,"auto_init":false,"default_branch":"main"}' \
|
||||
"$repo_api" >/dev/null
|
||||
fi
|
||||
|
||||
echo "== push repository =="
|
||||
push_url="http://${admin_user}:${admin_pass}@127.0.0.1:3000/git/${admin_user}/aios-v23.git"
|
||||
git push "$push_url" main
|
||||
git push "$push_url" --tags
|
||||
git remote remove origin 2>/dev/null || true
|
||||
git remote add origin "https://cnnetmkt.top/git/${admin_user}/aios-v23.git"
|
||||
|
||||
echo "== verify gitea repo =="
|
||||
curl -fsS "http://127.0.0.1:3000/git/${admin_user}/aios-v23" | grep -E "aios-v23|AIOS" | head -20 || true
|
||||
git status --short
|
||||
git log --oneline -8
|
||||
git remote -v
|
||||
|
||||
echo "GITEA_BINARY_INSTALL_OK version=$GITEA_VERSION url=https://cnnetmkt.top/git/${admin_user}/aios-v23"
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
for v in 1.22.6 1.22.5 1.22.4 1.22.3 1.22.2 1.22.1 1.22.0; do
|
||||
url="https://dl.gitea.com/gitea/${v}/gitea-${v}-linux-amd64"
|
||||
echo "== ${v} ${url} =="
|
||||
curl -I --max-time 20 "$url" 2>&1 | sed -n '1,16p'
|
||||
done
|
||||
@@ -8,5 +8,5 @@
|
||||
"zip_update_mode": "deprecated",
|
||||
"baseline_tag": "V1R1C0-baseline-20260706",
|
||||
"git_url": "https://cnnetmkt.top/git/aios/aios-v23.git",
|
||||
"updated_at": "2026-07-06T07:13:43.274366+00:00"
|
||||
"updated_at": "2026-07-06T07:16:01.842715+00:00"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user