[HLCC-ICE-000001][ZY-CONTRIB-20260723-001] feat: 以来光者贡献链启用冰朔第五域个人子频道

This commit is contained in:
光湖代码频道 · 铸渊 2026-07-24 10:39:10 +08:00
commit 5615453e4e
660 changed files with 122355 additions and 0 deletions

View file

@ -0,0 +1,57 @@
# HoloLake Code Channel · 部署与更新边界
本目录保存光湖代码频道HLCC的部署约束与机器可检验配置。
当前状态:
- 上游源码镜像与光湖自主源码基线已在 `BS-SG-003` 建立;
- 固定源码基线为 Forgejo `v16.0.1` / `b3d7e4ac3cbccc220703097a51fa4c16bf302579`
- 国内旧第五域仍由 Gitea 1.23.7 原地承载并作为历史事实源;
- `GLS-0239` 已登记京东个人子频道、`/code/` 正式入口、公开 AI 读取、
`bingshuo` 单身份密码沿用和 `HLCC-ICE-000001` 新 Git 根提交;
- 新频道部署与低权限激活清单已经就绪,正式切换前不覆盖旧第五域;
- `update-policy.json` 中的光湖更新清单地址仍是规划地址,尚未上线。
`jd-candidate/` 是绑定京东主节点固定架构预置器的候选服务包。它只从临时新加坡
中继读取 Forgejo 官方公开二进制、签名、公钥和哈希清单,不公开或下载光湖产品
Git bundle。服务先在 `127.0.0.1:3341` 暴露结构化安装状态;只有固定 SHA-256、
官方发布密钥指纹和 GPG 签名全部通过,且 `127.0.0.1:3340/api/v1/version`
确认版本、单身份迁移和新频道根提交后,状态才会变为 `ready=true`。候选数据与
旧第五域 Gitea 完全隔离;旧访问令牌、仓库、活动和 Git 历史不会迁入。
必须同时满足:
1. Forgejo 内置更新检查器关闭;
2. 官方上游不能自动合并、自动构建或自动部署;
3. 生产更新只认光湖签名清单;
4. 光湖清单不可用时停留在人工发布,不回退官方接口;
5. Gitea 迁移必须并行演练、可恢复、可回滚。
本目录不是服务器凭据库不保存密码、Token、SSH 私钥或数据库转储。
## 隔离候选
`candidate-app.jd.ini``candidate-app.enterprise.ini``install-candidate.sh`
`start-candidate.sh`
`stop-candidate.sh` 用于 `JD-FD-PRIMARY``AW-GZ-001` 上各自独立的隔离候选:
- 只绑定 `127.0.0.1:3340`
- 使用独立 SQLite 和仓库目录;
- 禁止注册、Actions、镜像和 Forgejo 内置更新检查;
- 只接收由 `BS-SG-003` 准备的固定 v16.0.1 二进制、签名与官方公钥材料;
- 在两个国内节点分别再次核验 Forgejo 官方 GPG 指纹和二进制签名;
- 安装和启动分离,安装脚本不注册 systemd、cron 或其他自动任务。
同一份离线包还要在 `AW-GZ-001` 企业服务器使用
`candidate-app.enterprise.ini` 独立部署。京东与企业实例的数据库、仓库、用户、
权限、密钥和回滚目录完全分离;它们只共享经过验签的源码与版本基线。
`BS-SG-003` 只负责海外源码和发布材料下载,不启动代码仓库服务。京东和企业节点都
必须保留 `forgejo-upstream-all.bundle``guanghu-code-channel.bundle`、官方签名、
公钥和 `MANIFEST.sha256`,从而在国内断开海外下载时仍可离线恢复与重装。候选验证
位于各自独立目录,不读取、不迁移、不修改国内现役 Gitea 数据。
`prepare-release-on-sg.sh` 是新加坡中继的唯一准备脚本:它从 Forgejo 官方镜像
下载固定版本二进制和签名、拉取并核对官方 GPG 指纹,并从现有上游镜像和光湖
产品仓生成两个 Git bundle。全部文件写入 `MANIFEST.sha256`。它不会启动服务,
也不会自行向京东或企业服务器传输;两次传输都必须绑定后续受控工单。

View file

@ -0,0 +1,5 @@
; HoloLake Code Channel mandatory Forgejo-base runtime fragment.
; The upstream Forgejo release checker must never control Guanghu production updates.
[cron.update_checker]
ENABLED = false

View file

@ -0,0 +1,35 @@
APP_NAME = HoloLake Code Channel · Enterprise
RUN_USER = guanghu
RUN_MODE = prod
[database]
DB_TYPE = sqlite3
PATH = /var/lib/guanghu/code-channel/candidates/hlcc-v16.0.1/data/hlcc.db
[repository]
ROOT = /var/lib/guanghu/code-channel/candidates/hlcc-v16.0.1/data/repositories
[server]
DOMAIN = 127.0.0.1
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3340
ROOT_URL = http://127.0.0.1:3340/
DISABLE_SSH = true
LFS_START_SERVER = true
OFFLINE_MODE = true
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = true
[security]
INSTALL_LOCK = true
[actions]
ENABLED = false
[mirror]
ENABLED = false
[cron.update_checker]
ENABLED = false

View file

@ -0,0 +1,35 @@
APP_NAME = HoloLake Code Channel · Fifth Domain
RUN_USER = guanghu
RUN_MODE = prod
[database]
DB_TYPE = sqlite3
PATH = /var/lib/guanghu/code-channel/candidates/hlcc-v16.0.1/data/hlcc.db
[repository]
ROOT = /var/lib/guanghu/code-channel/candidates/hlcc-v16.0.1/data/repositories
[server]
DOMAIN = 127.0.0.1
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3340
ROOT_URL = http://127.0.0.1:3340/
DISABLE_SSH = true
LFS_START_SERVER = true
OFFLINE_MODE = true
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = true
[security]
INSTALL_LOCK = true
[actions]
ENABLED = false
[mirror]
ENABLED = false
[cron.update_checker]
ENABLED = false

View file

@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -euo pipefail
readonly HLCC_VERSION="16.0.1"
readonly HLCC_ROOT="/var/lib/guanghu/code-channel/candidates/hlcc-v${HLCC_VERSION}"
readonly HLCC_SOURCE_ARCHIVE="/var/lib/guanghu/code-channel/offline-source/hlcc-v${HLCC_VERSION}"
readonly HLCC_RELEASE_KEY="EB114F5E6C0DC2BCDD183550A4B61A2DC5923710"
readonly HLCC_PACKAGE_SOURCE="${1:-}"
readonly HLCC_CONFIG_SOURCE="${2:-}"
readonly HLCC_BINARY_NAME="forgejo-${HLCC_VERSION}-linux-amd64"
readonly HLCC_BINARY_SOURCE="${HLCC_PACKAGE_SOURCE}/${HLCC_BINARY_NAME}"
readonly HLCC_SIGNATURE_SOURCE="${HLCC_BINARY_SOURCE}.asc"
readonly HLCC_PUBLIC_KEY_SOURCE="${HLCC_PACKAGE_SOURCE}/forgejo-release-key.asc"
readonly HLCC_MANIFEST_SOURCE="${HLCC_PACKAGE_SOURCE}/MANIFEST.sha256"
readonly HLCC_UPSTREAM_BUNDLE_SOURCE="${HLCC_PACKAGE_SOURCE}/forgejo-upstream-all.bundle"
readonly HLCC_PRODUCT_BUNDLE_SOURCE="${HLCC_PACKAGE_SOURCE}/guanghu-code-channel.bundle"
if [[ "$(id -un)" != "guanghu" ]]; then
echo "Refusing to install a domestic isolated candidate as any user other than guanghu." >&2
exit 2
fi
if [[ \
-z "${HLCC_PACKAGE_SOURCE}" || ! -d "${HLCC_PACKAGE_SOURCE}" || \
! -f "${HLCC_BINARY_SOURCE}" || \
! -f "${HLCC_SIGNATURE_SOURCE}" || \
! -f "${HLCC_PUBLIC_KEY_SOURCE}" || \
! -f "${HLCC_MANIFEST_SOURCE}" || \
! -f "${HLCC_UPSTREAM_BUNDLE_SOURCE}" || \
! -f "${HLCC_PRODUCT_BUNDLE_SOURCE}" || \
-z "${HLCC_CONFIG_SOURCE}" || ! -f "${HLCC_CONFIG_SOURCE}" \
]]; then
echo "Usage: $0 /absolute/path/to/offline-package candidate-app.<target>.ini" >&2
exit 2
fi
for command_name in gpg sha256sum git; do
if ! command -v "${command_name}" >/dev/null 2>&1; then
echo "Missing required command: ${command_name}" >&2
exit 3
fi
done
umask 077
mkdir -p \
"${HLCC_ROOT}/bin" \
"${HLCC_ROOT}/config" \
"${HLCC_ROOT}/data/repositories" \
"${HLCC_ROOT}/logs" \
"${HLCC_ROOT}/tmp" \
"${HLCC_SOURCE_ARCHIVE}"
readonly gpg_home="${HLCC_ROOT}/tmp/gpg"
mkdir -p "${gpg_home}"
chmod 700 "${gpg_home}"
(
cd "${HLCC_PACKAGE_SOURCE}"
sha256sum --check MANIFEST.sha256
)
GNUPGHOME="${gpg_home}" gpg --batch --import "${HLCC_PUBLIC_KEY_SOURCE}"
if ! GNUPGHOME="${gpg_home}" gpg \
--batch \
--with-colons \
--fingerprint "${HLCC_RELEASE_KEY}" \
| grep -Fq "fpr:::::::::${HLCC_RELEASE_KEY}:"; then
echo "Forgejo release key fingerprint mismatch." >&2
exit 4
fi
GNUPGHOME="${gpg_home}" gpg \
--batch \
--verify "${HLCC_SIGNATURE_SOURCE}" "${HLCC_BINARY_SOURCE}"
install -m 0755 "${HLCC_BINARY_SOURCE}" "${HLCC_ROOT}/bin/hlcc"
install -m 0600 "${HLCC_CONFIG_SOURCE}" "${HLCC_ROOT}/config/app.ini"
install -m 0600 "${HLCC_MANIFEST_SOURCE}" "${HLCC_SOURCE_ARCHIVE}/MANIFEST.sha256"
install -m 0755 "${HLCC_BINARY_SOURCE}" "${HLCC_SOURCE_ARCHIVE}/${HLCC_BINARY_NAME}"
install -m 0600 "${HLCC_UPSTREAM_BUNDLE_SOURCE}" "${HLCC_SOURCE_ARCHIVE}/forgejo-upstream-all.bundle"
install -m 0600 "${HLCC_PRODUCT_BUNDLE_SOURCE}" "${HLCC_SOURCE_ARCHIVE}/guanghu-code-channel.bundle"
install -m 0600 "${HLCC_PUBLIC_KEY_SOURCE}" "${HLCC_SOURCE_ARCHIVE}/forgejo-release-key.asc"
install -m 0600 "${HLCC_SIGNATURE_SOURCE}" "${HLCC_SOURCE_ARCHIVE}/${HLCC_BINARY_NAME}.asc"
install -m 0600 "${HLCC_CONFIG_SOURCE}" "${HLCC_SOURCE_ARCHIVE}/candidate-app.ini"
(
cd "${HLCC_SOURCE_ARCHIVE}"
sha256sum --check MANIFEST.sha256
)
sha256sum "${HLCC_ROOT}/bin/hlcc" > "${HLCC_ROOT}/RELEASE.sha256"
"${HLCC_ROOT}/bin/hlcc" --version
echo "HLCC isolated candidate installed at ${HLCC_ROOT}"
echo "Offline source and release material retained at ${HLCC_SOURCE_ARCHIVE}"
echo "No service was started and no automatic update job was installed."

View file

@ -0,0 +1,58 @@
#!/usr/bin/env python3
"""Activate the reviewed full-offline HLCC candidate unit without root shell."""
from __future__ import annotations
import json
import os
import pathlib
import signal
import subprocess
import time
import urllib.request
SERVICE = "hlcc-jd-candidate.service"
HEALTH_URL = "http://127.0.0.1:3341/health"
def main() -> None:
result = subprocess.run(
["/usr/bin/systemctl", "show", "--property=MainPID", "--value", SERVICE],
check=True,
capture_output=True,
text=True,
)
pid = int(result.stdout.strip())
if pid <= 1:
raise RuntimeError("HLCC candidate bootstrap has no active main process")
process_root = pathlib.Path("/proc") / str(pid)
if process_root.stat().st_uid != os.getuid():
raise RuntimeError("refusing to signal a process owned by another user")
command = (process_root / "cmdline").read_bytes().replace(b"\0", b" ").decode("utf-8", "replace")
if "/hololake-code-channel/jd-candidate/hlcc-bootstrap.py" not in command:
raise RuntimeError("refusing to signal an unexpected process")
os.kill(pid, signal.SIGTERM)
for _attempt in range(40):
try:
with urllib.request.urlopen(HEALTH_URL, timeout=2) as response:
payload = json.load(response)
if (
payload.get("ok") is True
and payload.get("mode") == "isolated-candidate"
and payload.get("version") == "16.0.1"
and payload.get("package_profile") == "full-offline-v16.0.1"
and payload.get("ready") is True
and payload.get("stage") == "ready"
):
return
except Exception:
pass
time.sleep(1)
raise RuntimeError("full-offline HLCC personal channel did not become ready")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,28 @@
#!/usr/bin/env node
const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const root = __dirname;
const script = fs.readFileSync(path.join(root, "activate-staged-candidate.py"), "utf8");
const unit = fs.readFileSync(path.join(root, "hlcc-jd-candidate-activator.service"), "utf8");
const bootstrap = fs.readFileSync(path.join(root, "hlcc-bootstrap.py"), "utf8");
assert.match(bootstrap, /hlcc-offline\/16\.0\.1/);
assert.match(bootstrap, /forgejo-upstream-all\.bundle/);
assert.match(bootstrap, /guanghu-code-channel\.bundle/);
assert.match(bootstrap, /full-offline-v16\.0\.1/);
assert.match(script, /systemctl", "show", "--property=MainPID"/);
assert.match(script, /process_root\.stat\(\)\.st_uid != os\.getuid\(\)/);
assert.match(script, /"\/hololake-code-channel\/jd-candidate\/hlcc-bootstrap\.py" not in command/);
assert.match(script, /os\.kill\(pid, signal\.SIGTERM\)/);
assert.match(script, /payload\.get\("mode"\) == "isolated-candidate"/);
assert.match(script, /payload\.get\("ready"\) is True/);
assert.match(script, /payload\.get\("stage"\) == "ready"/);
assert.doesNotMatch(script, /shell=True|systemctl", "(?:restart|stop|start)"/);
assert.match(unit, /^User=guanghu$/m);
assert.match(unit, /^NoNewPrivileges=true$/m);
assert.match(unit, /^ProtectSystem=strict$/m);
console.log("HLCC full-offline candidate activator: PASS");

View file

@ -0,0 +1,40 @@
APP_NAME = 光湖代码频道
RUN_USER = guanghu
RUN_MODE = prod
[database]
DB_TYPE = sqlite3
PATH = /var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/hlcc.db
[repository]
ROOT = /var/lib/guanghu/personas/guanghu/hlcc-v16.0.1/data/repositories
[server]
DOMAIN = guanghulab.com
HTTP_ADDR = 127.0.0.1
HTTP_PORT = 3340
ROOT_URL = https://guanghulab.com/code/
DISABLE_SSH = true
LFS_START_SERVER = true
OFFLINE_MODE = true
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
[security]
INSTALL_LOCK = true
[actions]
ENABLED = false
[mirror]
ENABLED = false
[other]
SHOW_FOOTER_BRANDING = false
SHOW_FOOTER_VERSION = false
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
[cron.update_checker]
ENABLED = false

View file

@ -0,0 +1,528 @@
#!/usr/bin/env python3
"""Verify and start the isolated JD HoloLake Code Channel candidate."""
from __future__ import annotations
import hashlib
import http.server
import json
import os
import pathlib
import re
import shutil
import sqlite3
import subprocess
import tempfile
import threading
import time
import urllib.error
import urllib.parse
import urllib.request
VERSION = "16.0.1"
UPSTREAM_FINGERPRINT = "EB114F5E6C0DC2BCDD183550A4B61A2DC5923710"
STATE_ROOT = pathlib.Path("/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1")
LEGACY_DB = STATE_ROOT / "data" / "owner-identity-source.db"
OWNER_NAME = "bingshuo"
CHANNEL_REPOSITORY = "fifth-domain"
LEGACY_REPOSITORY_URL = "https://guanghulab.com/fifth-domain/bingshuo/fifth-domain.git"
SEED_COMMIT_NUMBER = "HLCC-ICE-000001"
SEED_CONTRIBUTION_NUMBER = "ZY-CONTRIB-20260723-001"
RELAY_ROOT = "https://guanghubingshuo.com/hlcc-offline/16.0.1"
BINARY_NAME = f"forgejo-{VERSION}-linux-amd64"
EXPECTED = {
BINARY_NAME: "7a4c568136650c10498a9d3d62c7fd630a0cf09c166293ebd78708248f6398fc",
f"{BINARY_NAME}.asc": "1c0ca36df3adb0a7692b6bdc84d7886001ca0c6d0408e67c9d232d2f33cecc71",
"forgejo-release-key.asc": "6fae8894c671ce2397cb35fe40c324f73deade6b4cb3cd6cedd1d2b248e0e3ea",
"forgejo-upstream-all.bundle": "c33bd074d9b2896259e86ebe03ad31ccdd8ff71897beed4320081fa03b15381f",
"guanghu-code-channel.bundle": "fc53740259d108128e69f5a809cec438ecf3158175617574ba55b8612c5eaa6c",
"MANIFEST.sha256": "d564c3b600d4b7a199d8a04ce505ceabf81993ca74fa440805601d55e550f185",
}
STATUS = {
"ok": True,
"mode": "bootstrap",
"version": VERSION,
"code": "HLCC-JD-CANDIDATE-01",
"ready": False,
"stage": "starting",
"package_profile": "full-offline-v16.0.1",
}
STATUS_LOCK = threading.Lock()
def set_status(**values: object) -> None:
with STATUS_LOCK:
STATUS.update(values)
class HealthHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self) -> None: # noqa: N802 - BaseHTTPRequestHandler API
if self.path != "/health":
self.send_error(404)
return
with STATUS_LOCK:
payload = json.dumps(STATUS, ensure_ascii=False).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json; charset=utf-8")
self.send_header("Cache-Control", "no-store")
self.send_header("Content-Length", str(len(payload)))
self.end_headers()
self.wfile.write(payload)
def log_message(self, _format: str, *_args: object) -> None:
return
def sha256(path: pathlib.Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def download_verified(name: str) -> pathlib.Path:
destination = STATE_ROOT / "release" / name
if destination.is_file() and sha256(destination) == EXPECTED[name]:
return destination
destination.parent.mkdir(parents=True, exist_ok=True)
temporary = destination.with_suffix(destination.suffix + ".partial")
temporary.unlink(missing_ok=True)
request = urllib.request.Request(
f"{RELAY_ROOT}/{name}",
headers={"User-Agent": "HoloLake-Code-Channel/16.0.1"},
)
with urllib.request.urlopen(request, timeout=45) as response, temporary.open("wb") as output:
shutil.copyfileobj(response, output, length=1024 * 1024)
if sha256(temporary) != EXPECTED[name]:
temporary.unlink(missing_ok=True)
raise RuntimeError(f"sha256 mismatch: {name}")
temporary.replace(destination)
return destination
def verify_release(files: dict[str, pathlib.Path]) -> None:
manifest = files["MANIFEST.sha256"].read_text(encoding="utf-8")
for name in (
BINARY_NAME,
f"{BINARY_NAME}.asc",
"forgejo-release-key.asc",
"forgejo-upstream-all.bundle",
"guanghu-code-channel.bundle",
):
expected_line = f"{EXPECTED[name]} {name}"
if expected_line not in manifest.splitlines():
raise RuntimeError(f"manifest entry mismatch: {name}")
gpg_home = STATE_ROOT / "gpg"
gpg_home.mkdir(parents=True, exist_ok=True)
gpg_home.chmod(0o700)
environment = {**os.environ, "GNUPGHOME": str(gpg_home)}
subprocess.run(
["gpg", "--batch", "--import", str(files["forgejo-release-key.asc"])],
check=True,
env=environment,
stdout=subprocess.DEVNULL,
)
fingerprint = subprocess.run(
["gpg", "--batch", "--with-colons", "--fingerprint", UPSTREAM_FINGERPRINT],
check=True,
env=environment,
text=True,
capture_output=True,
).stdout
if f"fpr:::::::::{UPSTREAM_FINGERPRINT}:" not in fingerprint:
raise RuntimeError("release key fingerprint mismatch")
subprocess.run(
[
"gpg",
"--batch",
"--verify",
str(files[f"{BINARY_NAME}.asc"]),
str(files[BINARY_NAME]),
],
check=True,
env=environment,
stdout=subprocess.DEVNULL,
)
def wait_for_candidate(process: subprocess.Popen[bytes]) -> None:
url = "http://127.0.0.1:3340/api/healthz"
for _attempt in range(90):
if process.poll() is not None:
raise RuntimeError(f"candidate exited with code {process.returncode}")
try:
with urllib.request.urlopen(url, timeout=2) as response:
payload = json.load(response)
if payload.get("status") == "pass":
return
except Exception: # Candidate is still starting.
pass
time.sleep(1)
raise RuntimeError("candidate readiness timeout")
def immutable_source_commit(script_path: pathlib.Path | None = None) -> str:
source = (script_path or pathlib.Path(__file__)).resolve()
matches = [part for part in source.parts if re.fullmatch(r"[0-9a-f]{40}", part)]
if len(matches) != 1:
raise RuntimeError("immutable release commit unavailable")
return matches[0]
def owner_identity_columns(connection: sqlite3.Connection) -> list[str]:
return [row[1] for row in connection.execute("pragma table_info(user)")]
def migrate_owner_identity(
legacy_db: pathlib.Path = LEGACY_DB,
channel_db: pathlib.Path | None = None,
receipt_path: pathlib.Path | None = None,
) -> str:
target = channel_db or STATE_ROOT / "data" / "hlcc.db"
receipt = receipt_path or STATE_ROOT / "data" / "owner-migration-receipt.json"
if not legacy_db.is_file() or not target.is_file():
raise RuntimeError("owner migration database unavailable")
legacy = sqlite3.connect(f"file:{legacy_db}?mode=ro", uri=True, timeout=15)
channel = sqlite3.connect(target, timeout=15)
try:
existing = channel.execute(
"select is_active, is_admin from user where lower_name = ?",
(OWNER_NAME,),
).fetchall()
if existing:
if len(existing) != 1 or existing[0] != (1, 1):
raise RuntimeError("channel owner identity mismatch")
return "already-present"
source_rows = legacy.execute(
"select * from user where lower_name = ?",
(OWNER_NAME,),
).fetchall()
if len(source_rows) != 1:
raise RuntimeError("legacy owner identity mismatch")
old_columns = owner_identity_columns(legacy)
new_info = list(channel.execute("pragma table_info(user)"))
new_columns = {row[1] for row in new_info}
missing = [
row[1]
for row in new_info
if row[3] and row[4] is None and row[1] != "id" and row[1] not in old_columns
]
if missing:
raise RuntimeError("channel owner schema has unsupported required columns")
copied_columns = [name for name in old_columns if name in new_columns and name != "id"]
values = dict(zip(old_columns, source_rows[0]))
for counter in ("num_repos", "num_stars", "num_followers", "num_following"):
if counter in values:
values[counter] = 0
if "use_custom_avatar" in values:
values["use_custom_avatar"] = 0
if "prohibit_login" in values:
values["prohibit_login"] = 0
backup_dir = target.parent / "backups"
backup_dir.mkdir(parents=True, exist_ok=True)
backup_path = backup_dir / "hlcc-before-owner-migration.db"
backup = sqlite3.connect(backup_path)
try:
channel.backup(backup)
finally:
backup.close()
backup_path.chmod(0o600)
placeholders = ",".join("?" for _name in copied_columns)
column_sql = ",".join(f'"{name}"' for name in copied_columns)
with channel:
channel.execute(
f"insert into user ({column_sql}) values ({placeholders})",
[values[name] for name in copied_columns],
)
verified = channel.execute(
"select id, is_active, is_admin from user where lower_name = ?",
(OWNER_NAME,),
).fetchall()
if len(verified) != 1 or verified[0][1:] != (1, 1):
raise RuntimeError("channel owner migration verification failed")
receipt.write_text(
json.dumps(
{
"schema": "guanghu.hlcc-owner-migration/v1",
"owner": OWNER_NAME,
"identity_only": True,
"password_hash_preserved": True,
"access_tokens_migrated": False,
"repositories_migrated": False,
"result": "VERIFIED",
},
ensure_ascii=False,
indent=2,
)
+ "\n",
encoding="utf-8",
)
receipt.chmod(0o600)
return "migrated"
finally:
channel.close()
legacy.close()
def api_json(
method: str,
path: str,
token: str = "",
body: dict[str, object] | None = None,
) -> tuple[int, dict[str, object]]:
headers = {"Accept": "application/json"}
data = None
if token:
headers["Authorization"] = f"token {token}"
if body is not None:
headers["Content-Type"] = "application/json"
data = json.dumps(body).encode("utf-8")
request = urllib.request.Request(
f"http://127.0.0.1:3340{path}",
data=data,
headers=headers,
method=method,
)
try:
with urllib.request.urlopen(request, timeout=15) as response:
raw = response.read()
return response.status, json.loads(raw or b"{}")
except urllib.error.HTTPError as error:
raw = error.read()
try:
payload = json.loads(raw or b"{}")
except json.JSONDecodeError:
payload = {}
return error.code, payload
def delete_bootstrap_token(channel_db: pathlib.Path, token_name: str) -> None:
connection = sqlite3.connect(channel_db, timeout=15)
try:
with connection:
owner = connection.execute(
"select id from user where lower_name = ?",
(OWNER_NAME,),
).fetchone()
if owner:
connection.execute(
"delete from access_token where uid = ? and name = ?",
(owner[0], token_name),
)
finally:
connection.close()
def generate_bootstrap_token(binary: pathlib.Path, token_name: str) -> str:
channel_db = STATE_ROOT / "data" / "hlcc.db"
delete_bootstrap_token(channel_db, token_name)
result = subprocess.run(
[
str(binary),
"admin",
"user",
"generate-access-token",
"--username",
OWNER_NAME,
"--token-name",
token_name,
"--scopes",
"write:repository",
"--raw",
"--config",
str(STATE_ROOT / "config" / "app.ini"),
"--work-path",
str(STATE_ROOT / "data"),
],
check=True,
capture_output=True,
text=True,
)
token = result.stdout.strip().splitlines()[-1]
if not re.fullmatch(r"[A-Za-z0-9_-]{32,160}", token):
raise RuntimeError("bootstrap access token format invalid")
return token
def seed_fifth_domain_channel(binary: pathlib.Path) -> str:
status, repository = api_json("GET", f"/api/v1/repos/{OWNER_NAME}/{CHANNEL_REPOSITORY}")
if status == 200:
if repository.get("private") is not False:
raise RuntimeError("existing channel repository is not public")
if repository.get("empty") is False and repository.get("default_branch") == "main":
return "already-present"
if repository.get("empty") is not True:
raise RuntimeError("existing channel repository state invalid")
elif status != 404:
raise RuntimeError("channel repository lookup failed")
token_name = "hlcc-fifth-domain-bootstrap"
token = generate_bootstrap_token(binary, token_name)
channel_db = STATE_ROOT / "data" / "hlcc.db"
try:
if status == 404:
created_status, _created = api_json(
"POST",
"/api/v1/user/repos",
token,
{
"name": CHANNEL_REPOSITORY,
"description": "光湖代码频道 · 冰朔第五域个人子频道 · 2026-07-23 新起点",
"private": False,
"auto_init": False,
"default_branch": "main",
},
)
if created_status != 201:
raise RuntimeError("channel repository creation failed")
source_commit = immutable_source_commit()
with tempfile.TemporaryDirectory(prefix="hlcc-seed-") as temporary:
root = pathlib.Path(temporary)
snapshot = root / "snapshot"
subprocess.run(
["git", "clone", "--depth=1", "--branch", "main", LEGACY_REPOSITORY_URL, str(snapshot)],
check=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
)
actual_commit = subprocess.run(
["git", "-C", str(snapshot), "rev-parse", "HEAD"],
check=True,
capture_output=True,
text=True,
).stdout.strip()
if actual_commit != source_commit:
raise RuntimeError("legacy snapshot commit mismatch")
shutil.rmtree(snapshot / ".git")
subprocess.run(["git", "-C", str(snapshot), "init", "-b", "main"], check=True, capture_output=True)
subprocess.run(
["git", "-C", str(snapshot), "config", "user.name", "光湖代码频道 · 铸渊"],
check=True,
)
subprocess.run(
["git", "-C", str(snapshot), "config", "user.email", "hlcc@guanghulab.invalid"],
check=True,
)
subprocess.run(["git", "-C", str(snapshot), "add", "-A"], check=True)
subprocess.run(
[
"git",
"-C",
str(snapshot),
"commit",
"-m",
(
f"[{SEED_COMMIT_NUMBER}][{SEED_CONTRIBUTION_NUMBER}] "
"feat: 以来光者贡献链启用冰朔第五域个人子频道"
),
],
check=True,
capture_output=True,
)
credential = root / "credentials"
encoded = urllib.parse.quote(token, safe="")
credential.write_text(
f"http://{OWNER_NAME}:{encoded}@127.0.0.1:3340\n",
encoding="utf-8",
)
credential.chmod(0o600)
subprocess.run(
[
"git",
"-C",
str(snapshot),
"-c",
f"credential.helper=store --file {credential}",
"push",
"http://127.0.0.1:3340/bingshuo/fifth-domain.git",
"main:main",
],
check=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
)
credential.unlink(missing_ok=True)
verified_status, verified = api_json(
"GET",
f"/api/v1/repos/{OWNER_NAME}/{CHANNEL_REPOSITORY}",
)
if (
verified_status != 200
or verified.get("private") is not False
or verified.get("empty") is not False
or verified.get("default_branch") != "main"
):
raise RuntimeError("channel repository verification failed")
return "seeded"
finally:
delete_bootstrap_token(channel_db, token_name)
def bootstrap() -> None:
process: subprocess.Popen[bytes] | None = None
try:
for directory in ("config", "data", "logs", "release", "tmp"):
(STATE_ROOT / directory).mkdir(parents=True, exist_ok=True)
set_status(stage="downloading")
files = {name: download_verified(name) for name in EXPECTED}
set_status(stage="verifying")
verify_release(files)
binary = files[BINARY_NAME]
binary.chmod(0o755)
config_source = pathlib.Path(__file__).with_name("app.ini")
config_target = STATE_ROOT / "config" / "app.ini"
shutil.copyfile(config_source, config_target)
config_target.chmod(0o600)
set_status(stage="launching")
log_path = STATE_ROOT / "logs" / "hlcc.log"
log_handle = log_path.open("ab", buffering=0)
process = subprocess.Popen(
[
str(binary),
"web",
"--work-path",
str(STATE_ROOT / "data"),
"--config",
str(config_target),
],
stdout=log_handle,
stderr=subprocess.STDOUT,
)
wait_for_candidate(process)
set_status(stage="migrating-owner")
migrate_owner_identity()
set_status(stage="seeding-fifth-domain-channel")
seed_fifth_domain_channel(binary)
set_status(mode="isolated-candidate", ready=True, stage="ready")
return_code = process.wait()
raise RuntimeError(f"candidate stopped with code {return_code}")
except Exception as error:
if process and process.poll() is None:
process.terminate()
set_status(ok=False, ready=False, stage="failed", error=str(error)[:180])
def main() -> None:
thread = threading.Thread(target=bootstrap, name="hlcc-bootstrap", daemon=True)
thread.start()
server = http.server.ThreadingHTTPServer(("127.0.0.1", 3341), HealthHandler)
server.serve_forever()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,26 @@
[Unit]
Description=Activate the staged full-offline HoloLake Code Channel JD candidate
After=hlcc-jd-candidate.service
Requires=hlcc-jd-candidate.service
[Service]
Type=oneshot
User=guanghu
Group=guanghu
ExecStart=/usr/bin/python3 __RELEASE_ROOT__/server-tools/hololake-code-channel/jd-candidate/activate-staged-candidate.py
RemainAfterExit=true
TimeoutStartSec=60
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true
ReadOnlyPaths=__RELEASE_ROOT__
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,29 @@
[Unit]
Description=HoloLake Code Channel isolated JD candidate
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=guanghu
Group=guanghu
UMask=0077
StateDirectory=guanghu/personas/guanghu/hlcc-v16.0.1
ExecStart=/usr/bin/python3 __RELEASE_ROOT__/server-tools/hololake-code-channel/jd-candidate/hlcc-bootstrap.py
Restart=always
RestartSec=5
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true
ReadOnlyPaths=__RELEASE_ROOT__
ReadWritePaths=/var/lib/guanghu/personas/guanghu/hlcc-v16.0.1
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,26 @@
[Unit]
Description=Activate the HoloLake Code Channel Fifth Domain personal subchannel
After=hlcc-jd-candidate.service
Requires=hlcc-jd-candidate.service
[Service]
Type=oneshot
User=guanghu
Group=guanghu
ExecStart=/usr/bin/python3 __RELEASE_ROOT__/server-tools/hololake-code-channel/jd-candidate/activate-staged-candidate.py
RemainAfterExit=true
TimeoutStartSec=180
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true
ReadOnlyPaths=__RELEASE_ROOT__
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,84 @@
#!/usr/bin/env node
const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const root = __dirname;
const bootstrap = fs.readFileSync(path.join(root, "hlcc-bootstrap.py"), "utf8");
const ini = fs.readFileSync(path.join(root, "app.ini"), "utf8");
const unit = fs.readFileSync(path.join(root, "hlcc-jd-candidate.service"), "utf8");
const manifest = JSON.parse(
fs.readFileSync(
path.join(
root,
"../../../deployment/requests/HLCC-JD-CANDIDATE-INITIAL-PROVISION-20260723.json",
),
"utf8",
),
);
const offlineReceipt = JSON.parse(
fs.readFileSync(
path.join(
root,
"../../../deployment/receipts/HLCC-BS-SG-003-OFFLINE-PACK-20260723.json",
),
"utf8",
),
);
assert.match(bootstrap, /VERSION = "16\.0\.1"/);
assert.match(bootstrap, /EB114F5E6C0DC2BCDD183550A4B61A2DC5923710/);
assert.match(bootstrap, /MANIFEST\.sha256/);
assert.match(bootstrap, /gpg"[\s\S]*"--verify"/);
assert.match(bootstrap, /127\.0\.0\.1", 3341/);
assert.match(bootstrap, /127\.0\.0\.1:3340\/api\/healthz/);
assert.match(bootstrap, /payload\.get\("status"\) == "pass"/);
assert.doesNotMatch(bootstrap, /127\.0\.0\.1:3340\/api\/v1\/version/);
assert.match(bootstrap, /forgejo-upstream-all\.bundle/);
assert.match(bootstrap, /guanghu-code-channel\.bundle/);
assert.match(bootstrap, /package_profile": "full-offline-v16\.0\.1"/);
assert.match(bootstrap, /OWNER_NAME = "bingshuo"/);
assert.match(bootstrap, /SEED_COMMIT_NUMBER = "HLCC-ICE-000001"/);
assert.match(bootstrap, /SEED_CONTRIBUTION_NUMBER = "ZY-CONTRIB-20260723-001"/);
assert.match(bootstrap, /以来光者贡献链启用冰朔第五域个人子频道/);
assert.match(bootstrap, /owner-identity-source\.db/);
assert.match(bootstrap, /password_hash_preserved/);
assert.match(bootstrap, /access_tokens_migrated": False/);
assert.match(bootstrap, /repositories_migrated": False/);
assert.match(bootstrap, /delete from access_token/);
assert.doesNotMatch(
bootstrap,
/print\s*\([^)]*token|stderr\.write\s*\([^)]*token|stdout\.write\s*\([^)]*token/,
);
for (const artifact of offlineReceipt.artifacts) {
assert.match(artifact.sha256, /^[0-9a-f]{64}$/);
assert.match(
bootstrap,
new RegExp(`: "${artifact.sha256}"`),
);
}
assert.match(offlineReceipt.release.manifest_sha256, /^[0-9a-f]{64}$/);
assert.match(
bootstrap,
new RegExp(`"MANIFEST\\.sha256": "${offlineReceipt.release.manifest_sha256}"`),
);
assert.match(ini, /APP_NAME = 光湖代码频道/);
assert.match(ini, /ROOT_URL = https:\/\/guanghulab\.com\/code\//);
assert.match(ini, /REQUIRE_SIGNIN_VIEW = false/);
assert.match(ini, /SHOW_FOOTER_BRANDING = false/);
assert.match(ini, /SHOW_FOOTER_VERSION = false/);
assert.match(ini, /\[cron\.update_checker\][\s\S]*ENABLED = false/);
assert.match(unit, /^User=guanghu$/m);
assert.match(unit, /^ProtectSystem=strict$/m);
assert.match(unit, /^ReadOnlyPaths=__RELEASE_ROOT__$/m);
assert.match(
unit,
/^ReadWritePaths=\/var\/lib\/guanghu\/personas\/guanghu\/hlcc-v16\.0\.1$/m,
);
assert.equal(manifest.target_node, "JD-FD-PRIMARY");
assert.equal(manifest.runtime_check.url, "http://127.0.0.1:3341/health");
assert.equal(manifest.module.unit, "hlcc-jd-candidate.service");
assert.equal(manifest.module.run_user, "guanghu");
console.log("HoloLake Code Channel JD candidate package: PASS");

View file

@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""Create a one-user SQLite handoff without exposing the legacy database to HLCC."""
from __future__ import annotations
import argparse
import json
import os
import pathlib
import pwd
import sqlite3
import tempfile
OWNER_NAME = "bingshuo"
def prepare(source: pathlib.Path, destination: pathlib.Path, owner: str) -> None:
if not source.is_file():
raise RuntimeError("legacy database unavailable")
destination.parent.mkdir(parents=True, exist_ok=True)
legacy = sqlite3.connect(f"file:{source}?mode=ro", uri=True, timeout=15)
try:
schema = legacy.execute(
"select sql from sqlite_master where type = 'table' and name = 'user'"
).fetchone()
row = legacy.execute(
"select * from user where lower_name = ?",
(OWNER_NAME,),
).fetchall()
if not schema or not schema[0] or len(row) != 1:
raise RuntimeError("legacy owner identity mismatch")
file_descriptor, temporary_name = tempfile.mkstemp(
prefix=".owner-identity-source.",
suffix=".db",
dir=destination.parent,
)
os.close(file_descriptor)
temporary = pathlib.Path(temporary_name)
try:
handoff = sqlite3.connect(temporary)
try:
handoff.execute(schema[0])
columns = [item[1] for item in legacy.execute("pragma table_info(user)")]
placeholders = ",".join("?" for _column in columns)
column_sql = ",".join(f'"{column}"' for column in columns)
handoff.execute(
f"insert into user ({column_sql}) values ({placeholders})",
row[0],
)
handoff.commit()
finally:
handoff.close()
temporary.chmod(0o600)
identity = pwd.getpwnam(owner)
os.chown(temporary, identity.pw_uid, identity.pw_gid)
temporary.replace(destination)
finally:
temporary.unlink(missing_ok=True)
finally:
legacy.close()
receipt = destination.with_suffix(".receipt.json")
receipt.write_text(
json.dumps(
{
"schema": "guanghu.hlcc-owner-identity-handoff/v1",
"owner": OWNER_NAME,
"rows": 1,
"contains_repository_data": False,
"contains_access_tokens": False,
"result": "PREPARED",
},
ensure_ascii=False,
indent=2,
)
+ "\n",
encoding="utf-8",
)
identity = pwd.getpwnam(owner)
os.chown(receipt, identity.pw_uid, identity.pw_gid)
receipt.chmod(0o600)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--source", required=True, type=pathlib.Path)
parser.add_argument("--destination", required=True, type=pathlib.Path)
parser.add_argument("--owner", default="guanghu")
arguments = parser.parse_args()
prepare(arguments.source, arguments.destination, arguments.owner)
print("OWNER_IDENTITY_SOURCE_PREPARED rows=1 tokens=0 repositories=0")
if __name__ == "__main__":
main()

View file

@ -0,0 +1,142 @@
#!/usr/bin/env python3
from __future__ import annotations
import importlib.util
import json
import pathlib
import sqlite3
import tempfile
import unittest
MODULE_PATH = pathlib.Path(__file__).with_name("hlcc-bootstrap.py")
SPEC = importlib.util.spec_from_file_location("hlcc_bootstrap", MODULE_PATH)
assert SPEC and SPEC.loader
MODULE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(MODULE)
SCHEMA = """
create table user (
id integer primary key autoincrement,
lower_name text not null,
name text not null,
email text not null,
passwd text not null,
salt text,
passwd_hash_algo text,
avatar text not null,
avatar_email text not null,
type integer default 0,
is_active integer default 1,
is_admin integer default 0,
num_repos integer default 0,
num_stars integer default 0,
num_followers integer default 0,
num_following integer default 0,
use_custom_avatar integer default 0,
prohibit_login integer default 0
);
create table repository (
id integer primary key autoincrement,
owner_id integer not null,
name text not null
);
create table access_token (
id integer primary key autoincrement,
uid integer not null,
name text not null,
token_hash text not null
);
"""
class OwnerMigrationTests(unittest.TestCase):
def setUp(self) -> None:
self.temporary = tempfile.TemporaryDirectory()
root = pathlib.Path(self.temporary.name)
self.old = root / "old.db"
self.new = root / "new.db"
self.receipt = root / "receipt.json"
for database in (self.old, self.new):
connection = sqlite3.connect(database)
connection.executescript(SCHEMA)
connection.commit()
connection.close()
connection = sqlite3.connect(self.old)
connection.execute(
"""
insert into user (
lower_name, name, email, passwd, salt, passwd_hash_algo,
avatar, avatar_email, is_active, is_admin, num_repos,
num_stars, num_followers, num_following, use_custom_avatar
) values (?, ?, ?, ?, ?, ?, ?, ?, 1, 1, 12, 4, 3, 2, 1)
""",
(
"bingshuo",
"bingshuo",
"owner@example.invalid",
"preserved-password-hash",
"preserved-salt",
"pbkdf2$50000$50",
"legacy-avatar",
"avatar@example.invalid",
),
)
connection.execute(
"insert into repository (owner_id, name) values (1, 'legacy-repo')"
)
connection.execute(
"insert into access_token (uid, name, token_hash) values (1, 'legacy-token', 'secret-hash')"
)
connection.commit()
connection.close()
def tearDown(self) -> None:
self.temporary.cleanup()
def test_migrates_only_owner_identity_and_preserves_password_hash(self) -> None:
result = MODULE.migrate_owner_identity(self.old, self.new, self.receipt)
self.assertEqual(result, "migrated")
connection = sqlite3.connect(self.new)
owner = connection.execute(
"""
select lower_name, passwd, salt, passwd_hash_algo, is_active,
is_admin, num_repos, num_stars, num_followers,
num_following, use_custom_avatar
from user
"""
).fetchone()
self.assertEqual(
owner,
(
"bingshuo",
"preserved-password-hash",
"preserved-salt",
"pbkdf2$50000$50",
1,
1,
0,
0,
0,
0,
0,
),
)
self.assertEqual(connection.execute("select count(*) from repository").fetchone()[0], 0)
self.assertEqual(connection.execute("select count(*) from access_token").fetchone()[0], 0)
connection.close()
receipt = json.loads(self.receipt.read_text(encoding="utf-8"))
self.assertTrue(receipt["identity_only"])
self.assertFalse(receipt["access_tokens_migrated"])
self.assertFalse(receipt["repositories_migrated"])
def test_is_idempotent(self) -> None:
self.assertEqual(MODULE.migrate_owner_identity(self.old, self.new, self.receipt), "migrated")
self.assertEqual(MODULE.migrate_owner_identity(self.old, self.new, self.receipt), "already-present")
if __name__ == "__main__":
unittest.main()

View file

@ -0,0 +1,107 @@
#!/usr/bin/env node
const fs = require("node:fs");
const path = require("node:path");
const assert = require("node:assert/strict");
const root = __dirname;
const ini = fs.readFileSync(path.join(root, "app.ini.fragment"), "utf8");
const jdCandidateIni = fs.readFileSync(
path.join(root, "candidate-app.jd.ini"),
"utf8",
);
const enterpriseCandidateIni = fs.readFileSync(
path.join(root, "candidate-app.enterprise.ini"),
"utf8",
);
const installer = fs.readFileSync(
path.join(root, "install-candidate.sh"),
"utf8",
);
const relayPreparer = fs.readFileSync(
path.join(root, "prepare-release-on-sg.sh"),
"utf8",
);
const policy = JSON.parse(
fs.readFileSync(path.join(root, "update-policy.json"), "utf8"),
);
assert.match(ini, /\[cron\.update_checker\][\s\S]*ENABLED\s*=\s*false/i);
assert.match(jdCandidateIni, /HoloLake Code Channel · Fifth Domain/);
assert.match(enterpriseCandidateIni, /HoloLake Code Channel · Enterprise/);
for (const candidateIni of [jdCandidateIni, enterpriseCandidateIni]) {
assert.match(
candidateIni,
/\[server\][\s\S]*HTTP_ADDR\s*=\s*127\.0\.0\.1[\s\S]*HTTP_PORT\s*=\s*3340/i,
);
assert.match(candidateIni, /RUN_USER\s*=\s*guanghu/i);
assert.match(
candidateIni,
/\/var\/lib\/guanghu\/code-channel\/candidates\/hlcc-v16\.0\.1/,
);
assert.match(
candidateIni,
/\[cron\.update_checker\][\s\S]*ENABLED\s*=\s*false/i,
);
assert.match(candidateIni, /\[actions\][\s\S]*ENABLED\s*=\s*false/i);
assert.match(candidateIni, /\[mirror\][\s\S]*ENABLED\s*=\s*false/i);
}
assert.match(
installer,
/\/var\/lib\/guanghu\/code-channel\/offline-source\/hlcc-v/,
);
assert.match(installer, /HLCC_VERSION="16\.0\.1"/);
assert.doesNotMatch(installer, /curl|wget|keyserver/);
assert.match(
installer,
/HLCC_RELEASE_KEY="EB114F5E6C0DC2BCDD183550A4B61A2DC5923710"/,
);
assert.match(installer, /gpg[\s\S]*--verify/);
assert.match(installer, /HLCC_SOURCE_ARCHIVE[\s\S]*sha256sum --check MANIFEST\.sha256/);
assert.match(installer, /candidate-app\.ini/);
assert.match(installer, /No service was started/);
assert.match(relayPreparer, /RELEASE_URL="https:\/\/code\.forgejo\.org\//);
assert.match(relayPreparer, /id -un\)" != "ubuntu"/);
assert.match(relayPreparer, /forgejo-upstream-all\.bundle/);
assert.match(relayPreparer, /guanghu-code-channel\.bundle/);
assert.match(relayPreparer, /MANIFEST\.sha256/);
assert.match(
relayPreparer,
/No service was started and no transfer to a domestic node was attempted/,
);
assert.equal(policy.product_id, "HLP-MOD-CODE-CHANNEL");
assert.equal(policy.official_upstream.automatic_fetch, false);
assert.equal(policy.official_upstream.automatic_merge, false);
assert.equal(policy.official_upstream.automatic_build, false);
assert.equal(policy.official_upstream.automatic_deploy, false);
assert.equal(policy.official_upstream.push_enabled, false);
assert.equal(policy.forgejo_builtin_update_checker.enabled, false);
assert.equal(
policy.guanghu_update_channel.manifest_url,
"https://guanghulab.com/api/code-channel/updates/v1/manifest.json",
);
assert.equal(policy.guanghu_update_channel.require_signature, true);
assert.equal(policy.guanghu_update_channel.require_artifact_sha256, true);
assert.equal(policy.guanghu_update_channel.require_rollback_release, true);
assert.equal(
policy.guanghu_update_channel.fallback_when_unavailable,
"MANUAL_RELEASE_ONLY",
);
assert.equal(
policy.source_baseline.upstream_commit,
"b3d7e4ac3cbccc220703097a51fa4c16bf302579",
);
assert.deepEqual(policy.offline_distribution.domestic_archive_nodes, [
"JD-FD-PRIMARY",
"AW-GZ-001",
]);
assert.deepEqual(policy.offline_distribution.runtime_nodes, [
"JD-FD-PRIMARY",
"AW-GZ-001",
]);
assert.equal(policy.offline_distribution.require_manifest_sha256, true);
assert.equal(policy.offline_distribution.require_domestic_gpg_reverification, true);
assert.equal(policy.offline_distribution.shared_runtime_data, false);
assert.equal(policy.offline_distribution.automatic_transfer, false);
console.log("HoloLake Code Channel update boundary: PASS");

View file

@ -0,0 +1,87 @@
#!/usr/bin/env bash
set -euo pipefail
readonly HLCC_VERSION="16.0.1"
readonly RELAY_ROOT="/home/ubuntu/guanghu/release-relay/hlcc-v${HLCC_VERSION}"
readonly BINARY_NAME="forgejo-${HLCC_VERSION}-linux-amd64"
readonly RELEASE_URL="https://code.forgejo.org/forgejo/forgejo/releases/download/v${HLCC_VERSION}/${BINARY_NAME}"
readonly RELEASE_KEY="EB114F5E6C0DC2BCDD183550A4B61A2DC5923710"
readonly GPG_HOME="${RELAY_ROOT}/gpg"
readonly UPSTREAM_REPOSITORY="/home/ubuntu/guanghu/upstream-parts/forgejo-official.git"
readonly PRODUCT_REPOSITORY="/home/ubuntu/guanghu/products/guanghu-code-channel"
if [[ "$(id -un)" != "ubuntu" ]]; then
echo "Refusing to prepare overseas release material as any user other than ubuntu." >&2
exit 2
fi
for command_name in curl git gpg sha256sum; do
if ! command -v "${command_name}" >/dev/null 2>&1; then
echo "Missing required command: ${command_name}" >&2
exit 3
fi
done
if [[ ! -d "${UPSTREAM_REPOSITORY}" || ! -d "${PRODUCT_REPOSITORY}/.git" ]]; then
echo "Required Forgejo upstream mirror or Guanghu product worktree is missing." >&2
exit 3
fi
umask 077
mkdir -p "${RELAY_ROOT}" "${GPG_HOME}"
chmod 700 "${GPG_HOME}"
curl --fail --location --proto '=https' --tlsv1.2 \
--output "${RELAY_ROOT}/${BINARY_NAME}" \
"${RELEASE_URL}"
curl --fail --location --proto '=https' --tlsv1.2 \
--output "${RELAY_ROOT}/${BINARY_NAME}.asc" \
"${RELEASE_URL}.asc"
GNUPGHOME="${GPG_HOME}" gpg \
--batch \
--keyserver hkps://keys.openpgp.org \
--recv-keys "${RELEASE_KEY}"
if ! GNUPGHOME="${GPG_HOME}" gpg \
--batch \
--with-colons \
--fingerprint "${RELEASE_KEY}" \
| grep -Fq "fpr:::::::::${RELEASE_KEY}:"; then
echo "Forgejo release key fingerprint mismatch." >&2
exit 4
fi
GNUPGHOME="${GPG_HOME}" gpg \
--batch \
--verify "${RELAY_ROOT}/${BINARY_NAME}.asc" "${RELAY_ROOT}/${BINARY_NAME}"
GNUPGHOME="${GPG_HOME}" gpg \
--batch \
--armor \
--export "${RELEASE_KEY}" > "${RELAY_ROOT}/forgejo-release-key.asc"
git -C "${UPSTREAM_REPOSITORY}" bundle create \
"${RELAY_ROOT}/forgejo-upstream-all.bundle" \
--all
git -C "${PRODUCT_REPOSITORY}" bundle create \
"${RELAY_ROOT}/guanghu-code-channel.bundle" \
guanghu/main
git -C "${UPSTREAM_REPOSITORY}" bundle verify \
"${RELAY_ROOT}/forgejo-upstream-all.bundle"
git -C "${PRODUCT_REPOSITORY}" bundle verify \
"${RELAY_ROOT}/guanghu-code-channel.bundle"
(
cd "${RELAY_ROOT}"
sha256sum \
"${BINARY_NAME}" \
"${BINARY_NAME}.asc" \
forgejo-release-key.asc \
forgejo-upstream-all.bundle \
guanghu-code-channel.bundle \
> MANIFEST.sha256
)
echo "Verified HLCC release material prepared at ${RELAY_ROOT}"
echo "The offline package contains full upstream and Guanghu product Git bundles."
echo "No service was started and no transfer to a domestic node was attempted."

View file

@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -euo pipefail
readonly HLCC_ROOT="/var/lib/guanghu/code-channel/candidates/hlcc-v16.0.1"
readonly HLCC_PID_FILE="${HLCC_ROOT}/hlcc.pid"
readonly HLCC_LOG_FILE="${HLCC_ROOT}/logs/hlcc.log"
if [[ "$(id -un)" != "guanghu" ]]; then
echo "Refusing to start a domestic isolated candidate as any user other than guanghu." >&2
exit 2
fi
if ! command -v curl >/dev/null 2>&1; then
echo "Missing required command: curl" >&2
exit 3
fi
if [[ -f "${HLCC_PID_FILE}" ]]; then
readonly existing_pid="$(cat "${HLCC_PID_FILE}")"
if kill -0 "${existing_pid}" 2>/dev/null; then
echo "HLCC candidate is already running as PID ${existing_pid}."
exit 0
fi
fi
nohup "${HLCC_ROOT}/bin/hlcc" web \
--work-path "${HLCC_ROOT}/data" \
--config "${HLCC_ROOT}/config/app.ini" \
>>"${HLCC_LOG_FILE}" 2>&1 &
readonly candidate_pid="$!"
echo "${candidate_pid}" > "${HLCC_PID_FILE}"
sleep 2
if ! kill -0 "${candidate_pid}" 2>/dev/null; then
echo "HLCC candidate failed to remain running." >&2
tail -n 80 "${HLCC_LOG_FILE}" >&2
exit 5
fi
curl --fail --silent --show-error \
"http://127.0.0.1:3340/api/v1/version"
echo
echo "HLCC isolated candidate is running on loopback only."

View file

@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail
readonly HLCC_ROOT="/var/lib/guanghu/code-channel/candidates/hlcc-v16.0.1"
readonly HLCC_PID_FILE="${HLCC_ROOT}/hlcc.pid"
if [[ "$(id -un)" != "guanghu" ]]; then
echo "Refusing to stop a domestic isolated candidate as any user other than guanghu." >&2
exit 2
fi
if [[ ! -f "${HLCC_PID_FILE}" ]]; then
echo "HLCC candidate PID file does not exist."
exit 0
fi
readonly candidate_pid="$(cat "${HLCC_PID_FILE}")"
if kill -0 "${candidate_pid}" 2>/dev/null; then
kill "${candidate_pid}"
fi
rm "${HLCC_PID_FILE}"
echo "HLCC isolated candidate stopped."

View file

@ -0,0 +1,47 @@
{
"schema": "guanghu.code-channel.update-policy/v1",
"product_id": "HLP-MOD-CODE-CHANNEL",
"name_zh": "光湖代码频道",
"name_en": "HoloLake Code Channel",
"official_upstream": {
"source": "https://code.forgejo.org/forgejo/forgejo.git",
"role": "review-only-parts-source",
"automatic_fetch": false,
"automatic_merge": false,
"automatic_build": false,
"automatic_deploy": false,
"push_enabled": false
},
"forgejo_builtin_update_checker": {
"enabled": false,
"forbidden_endpoint": "release.forgejo.org"
},
"guanghu_update_channel": {
"manifest_url": "https://guanghulab.com/api/code-channel/updates/v1/manifest.json",
"state": "PLANNED_NOT_LIVE",
"require_signature": true,
"require_artifact_sha256": true,
"require_rollback_release": true,
"fallback_when_unavailable": "MANUAL_RELEASE_ONLY"
},
"source_baseline": {
"upstream_tag": "v16.0.1",
"upstream_commit": "b3d7e4ac3cbccc220703097a51fa4c16bf302579",
"guanghu_branch": "guanghu/main"
},
"offline_distribution": {
"download_and_bundle_node": "BS-SG-003",
"domestic_archive_nodes": [
"JD-FD-PRIMARY",
"AW-GZ-001"
],
"runtime_nodes": [
"JD-FD-PRIMARY",
"AW-GZ-001"
],
"require_manifest_sha256": true,
"require_domestic_gpg_reverification": true,
"shared_runtime_data": false,
"automatic_transfer": false
}
}