259 lines
22 KiB
Markdown
259 lines
22 KiB
Markdown
# DPL 节点接入执行手册
|
||
|
||
入口:[节点关系与历史验收](NODE_ONBOARDING.md)。本手册定义后续授权任务的步骤。2026-10-16 已补齐本地脚本草稿;用户要求测试交给奶油,本轮未运行脚本、语法检查或功能测试,未触及线上。**新脚本必须先在隔离环境测试,再按Git流程审阅发布;本地存在不代表线上已更新。**已有节点展示命名按原入口的[节点命名与编号](NODE_ONBOARDING.md#节点命名与编号),此处不另建规则。
|
||
|
||
## 先选择变更模式
|
||
|
||
| 模式 | 适用情形 | 允许修改的范围 |
|
||
| --- | --- | --- |
|
||
| initialize | 首次建立 DPL 网关、基础节点组及明确授权的套餐可见范围 | 本次参数单与授权清单逐项列明;订阅地址、套餐/用户关联必须分别确认 |
|
||
| append | 已有网关/正式节点组上增加节点 | 新机器、新节点、新独立中转、节点 DNS/证书和 QA 隔离资源;验收后只把新节点加入指定已有组并禁用 QA |
|
||
|
||
默认判断依据是现有资源与目标,不把“新节点”当作首次初始化。append 保持现有订阅地址、网关、套餐全部字段、正式用户分组及旧节点不变。扩展套餐覆盖另列变更任务。未知已有组/节点状态时先解决该依赖,不能通过重跑初始化猜测。
|
||
|
||
## 统一参数单与冲突检查
|
||
|
||
在本次服务器受保护任务目录保存参数,目录 700、文件 600;非秘密参数也不进公开日志。以下是待填写模板,没有可直接用于新节点的默认值。文件只使用赋值,不含执行命令;人工审阅后才加载。
|
||
|
||
```sh
|
||
MODE='' # initialize 或 append
|
||
KEY='' # 稳定部署 key
|
||
NODE_NAME='' # 按既有命名规则确定;与 VPS 代号独立
|
||
VPS_ID='' # CoDocs 稳定 ID
|
||
NODE_ADDRESS='' # 实际落地地址,按私有资源读取
|
||
LISTEN_PORT=''
|
||
RELAY_HOST=''
|
||
RELAY_PORT=''
|
||
TLS_DOMAIN=''
|
||
FORMAL_GROUP_ID='' # append 必须填已有正式组
|
||
PLAN_IDS='' # 仅 initialize 或另有明确套餐变更授权时填
|
||
BACKUP='' # 绝对路径,每次任务独立,不复用其他节点目录
|
||
QA_DIR='' # 网关本次独立验收目录
|
||
CLIENT_BINARY='' # 已校验摘要的官方客户端绝对路径
|
||
EXPECTED_EXIT=''
|
||
EXPECTED_COUNTRY=''
|
||
LOCAL_SOCKS_PORT='' # 网关上本次隔离客户端空闲端口
|
||
APP_ROOT='' # 面板应用路径,从项目档案核实
|
||
PROVISION_ROOT='' # 面板上本次已确认脚本路径
|
||
NODE_PROVISION='' # 节点上已确认的运维 Git 路径
|
||
GIT_COMMIT='' # 已推送且经过审阅的明确提交
|
||
PANEL_URL='' # 节点回连面板的明确HTTPS地址
|
||
SUBSCRIBE_URL='' # 仅initialize明确修改的订阅地址
|
||
QA_REPORT='' # 本次隔离QA的私有实时验收报告
|
||
FORMAL_EXPECTATIONS='' # 正式多节点预期的私有JSON文件
|
||
FORMAL_REPORT='' # 正式多节点验证报告
|
||
```
|
||
|
||
填写后逐项核对:key/展示名、机器名、面板 ID、VPS、落地监听端口、中转入口的域名+端口、源站目标、SNI、正式组、DNS 现值、备份路径和 QA 端口。相同 key 有 manifest 时,只回读已有对象并确认参数完全一致;新 stage.php 重跑要求 manifest 记录的完整参数一致,并核对节点、机器和中转端点;旧 manifest 没有 parameters 时停止,不能自动采纳。相同资源无 manifest、冲突端口或未授权的覆盖均停止,不自动接管。
|
||
|
||
机密字段单独沿用 stage.php 生成的私密文件;不把机器令牌、QA UUID、订阅令牌写进上述参数单、文档或命令行。参数按角色分发,不把面板 .env 复制到节点。
|
||
|
||
可在审阅参数文件后运行以下本地字段检查;它不验证线上冲突或资源归属:
|
||
|
||
```sh
|
||
set -eu
|
||
: "${MODE:?}" "${KEY:?}" "${NODE_NAME:?}" "${VPS_ID:?}" "${NODE_ADDRESS:?}"
|
||
: "${LISTEN_PORT:?}" "${RELAY_HOST:?}" "${RELAY_PORT:?}" "${TLS_DOMAIN:?}"
|
||
: "${BACKUP:?}" "${QA_DIR:?}" "${CLIENT_BINARY:?}" "${EXPECTED_EXIT:?}" "${EXPECTED_COUNTRY:?}"
|
||
: "${LOCAL_SOCKS_PORT:?}" "${APP_ROOT:?}" "${PROVISION_ROOT:?}" "${NODE_PROVISION:?}" "${GIT_COMMIT:?}"
|
||
: "${PANEL_URL:?}" "${QA_REPORT:?}"
|
||
case "$MODE" in
|
||
append) : "${FORMAL_GROUP_ID:?}"; test -z "$PLAN_IDS" ;;
|
||
initialize) : "${PLAN_IDS:?}" "${SUBSCRIBE_URL:?}" ;;
|
||
*) exit 1 ;;
|
||
esac
|
||
```
|
||
|
||
## 创建面板记录之前完成前置检查
|
||
|
||
只在具体接入任务授权后,通过 CoDocs 白色机跳板及登记的后台反代执行以下检查。本次文档维护没有执行这些动作。
|
||
|
||
| 位置 | 必须确认 | 未通过时 |
|
||
| --- | --- | --- |
|
||
| 面板 | Git 提交、当前组和节点清单、现有订阅设置、套餐/用户分组快照、应用运行环境、脚本实际版本 | 先补证据与备份,不创建机器/节点/QA 记录 |
|
||
| 节点 | OS/架构、内存/磁盘、时间同步、systemd、Git、curl、sha256sum、ss、证书工具,以及命令实际路径 | 先明确缺失工具和安装来源;安装属于接入任务变更,文档整理不安装 |
|
||
| 软件来源 | 发行版源可下载、包版本与依赖可满足;运维仓库和官方二进制来源/摘要可验证 | 不把 apt 索引存在当可安装;不自动换不明镜像或全量升级 |
|
||
| 证书 | 已有 renewal 配置、pre/post/deploy hooks、Certbot 是 apt 还是 Snap、可执行路径、timer/cron 的真实调用参数和运行用户 | 确定新证书隔离方案及可生效调度后再签发;不能仅添加 renewal 文件就视为自动续期完成 |
|
||
| 节点隔离 | 现有 XrayR 等服务的 PID/启动时间、TCP/UDP 监听、防火墙与新端口、旧证书和目录权限 | 冲突先处理;安装脚本只检查 TCP,不能代替全项前检 |
|
||
| 中转 | 后台/登录账户按 CoDocs 读取,当前规则快照、目标落地、隧道及入口端口、Proxy Protocol 两端设置 | 缺入口先问,不改原规则;创建后回读实际值 |
|
||
| 网关 | 容器 ID/启动时间/重启计数、CPU/内存、独立 QA 路径和端口、Python3、官方客户端及其摘要 | 补齐验收依赖后再 stage,不边创建业务记录边找工具 |
|
||
|
||
历史 jp02 接入曾因 Debian11 源包 404 临时使用 Debian 官方 HTTPS 归档安装 Git;这是该次处理记录,不是以后默认改源或安装命令。先核对目标当下发行版与来源,不在本手册固化过期包 URL。
|
||
|
||
前置完成后,保存本次允许改变的对象、每个对象的 before 值、预期 after 值和精确回退依据。不要打印整库快照或秘密。
|
||
|
||
## 脚本能力与边界
|
||
|
||
后续新批次按[正式适配器](NODE_BATCH_RUNTIME.md)准备和执行:动态账号授权集合验收、缺账号时自动创建受限用户、白色机SSH复用及证据有效期续跑。旧命令适配器继续兼容。下文运维提交为上一轮三节点已验收版本,新适配器与PHP验收用户入口尚未部署,不能把旧任务验收视为新版本线上通过。
|
||
|
||
2026-10-17:下列脚本已完成 PHP 语法检查、面板隔离测试(9 tests / 65 assertions)及批量进程测试(11 tests),源码提交并推送 `6af6764`;独立运维快照 `b8d10fac963d63825c97d36d41ff7f525116bbfd` 已部署到本次面板/网关的 `/opt/dpl-batch/provision` 与三台新节点 `/opt/dpl-node/provision`。生产应用代码未随之更新。各阶段现场结果以 [STATUS](STATUS.md) 和 [接入记录](NODE_ONBOARDING.md) 为准;隔离测试中的通知替身不证明生产通知成功。
|
||
|
||
| 工具 | 新行为 | 边界 |
|
||
| --- | --- | --- |
|
||
| stage.php | 明确panel-url、完整参数/对象重跑核对、端点冲突检查;受保护manifest可恢复传输文件 | 旧manifest不自动采纳;依赖与实际资源前检仍由接入任务完成 |
|
||
| promote.php | 强制mode;默认只预览;append只写新节点group_ids及QA banned;initialize显式plans/subscribe-url/可选group-name | 真正写入需apply及15分钟内匹配该QA、端点与SNI的实时验证报告;不根据节点名推导身份 |
|
||
| readiness.php | 只统计显式plans,缺省不统计套餐;可检查给定group的冲突套餐 | 只读快照,不代替真实订阅/计费/界面验收 |
|
||
| verify-node.py | 默认离线结构核对;显式run才启动客户端/联网;可按预期逐一验证多节点、SNI、密码、出口IP及国家 | 正式多节点需要完整预期清单;只证明实际执行的探针,不代替业务/手机/TUN/全路由验收 |
|
||
| rollback.php | 默认预览;基于新promotion-journal逐字段比较after再恢复before;保持QA禁用,隔离本次节点 | 冲突整次停止,不覆盖后续变化;只覆盖面板变更,不停止远程服务或修改DNS/中转;旧before-promotion需专项人工核对 |
|
||
| operations.php | 私有文件锁、原子写日志、事务内记录写前意图、提交后完成标记;中断后按before/after识别已应用或冲突 | 文件与数据库不是同一个事务;状态未知需依据日志恢复,不盲目重新stage |
|
||
| install-node.sh / renew-node.sh | 沿用已登记的独立安装与专用续期hook | 本次未更改,不代表前置工具/安装源/实际timer已经验证 |
|
||
|
||
新脚本不修改已有节点展示名、不自动分配编号。操作日志不包含密码/UUID/机器令牌;脚本不在错误输出中打印数据库异常全文或客户端配置。上述隔离测试覆盖事务、幂等、崩溃恢复与冲突拒绝;缓存/节点通知与用户下发仍按本次现场证据验收。
|
||
|
||
## 统一接入顺序
|
||
|
||
1. 完成参数单、模式确认、前检和恢复点;非秘密运维代码先提交/推送,再更新目标至明确 Git 提交。已有线上差异保留。拉取受限时只能传输已推送提交的 Git bundle 后 fetch/fast-forward,不用归档覆盖。
|
||
2. 在确认的面板应用根目录,用下列统一参数创建隔离资源;创建后把实际 node_id、machine_id、group_id、test_user_id 与 key/VPS 对应写回本次任务 manifest,不能从服务器名推导面板 ID。
|
||
|
||
```sh
|
||
cd "$APP_ROOT"
|
||
php "$PROVISION_ROOT/stage.php" \
|
||
--key="$KEY" --name="$NODE_NAME" \
|
||
--relay-host="$RELAY_HOST" --relay-port="$RELAY_PORT" \
|
||
--listen-port="$LISTEN_PORT" --tls-domain="$TLS_DOMAIN" \
|
||
--panel-url="$PANEL_URL" --backup="$BACKUP"
|
||
```
|
||
|
||
3. 按既有受保护传输方式安装 node-config.yml 和 node-secret.env 至节点的独立目录,文件 600、父目录 700;实际运维 Git 路径使用 NODE_PROVISION,保留二进制固定版本/摘要核验。节点未安装本服务时才运行:
|
||
|
||
```sh
|
||
bash "$NODE_PROVISION/install-node.sh" \
|
||
--listen-port="$LISTEN_PORT" --tls-domain="$TLS_DOMAIN"
|
||
```
|
||
|
||
4. 配置本次 DNS only、证书和隔离续期策略,再启动新服务;中转只新增本次规则,保存后回读入口、目标及诊断结果。Proxy Protocol 默认保持本次参数单记录,不能单端打开。已有网关按 append 复用,不重建网关、NS、旧卷或订阅配置。
|
||
5. 按下节执行隔离验收;不因 service active、内核磁盘无 JSON 或 HTTP 200 单独判断成功/故障。Xboard-Node 可使用内存配置,须按实际版本、启动日志、证书和请求链路判断。
|
||
6. 验收通过后按下方“面板变更命令”预览,再对同一组参数明确apply。append只改新节点与QA;initialize才允许修改明确列出的套餐/用户分组及订阅地址。保存前后日志并回读。未通过隔离测试的新版本不能直接带到生产执行。
|
||
7. 回读正式订阅与原资源,检查 QA 禁用、订阅拒绝、下发集合无 QA,确认旧节点、旧中转、套餐/用户和订阅设置保持预期。同步 CoDocs 对象关系、节点登记及 STATUS;提交/推送/部署/现场验收分别报告。
|
||
|
||
## 证书钩子与演练
|
||
|
||
新证书只挂本项目专用 hook。历史已验证的调用方式为 `/bin/sh /opt/dpl-node/provision/renew-node.sh`;不能假定脚本有执行权限后直接执行。路径实际不同时按当前运维检出路径填写。renew-node.sh 依据 `/etc/dpl-node/certificate-domain` 和 RENEWED_LINEAGE 精确匹配,只操作 dpl-node。
|
||
|
||
目标实际 Certbot 命令路径记为 CERTBOT_BIN;先审计目录钩子、renewal 配置及 Snap/apt timer 的调用方式。经确认的演练入口:
|
||
|
||
```sh
|
||
: "${CERTBOT_BIN:?}"
|
||
"$CERTBOT_BIN" renew --cert-name "$TLS_DOMAIN" --dry-run \
|
||
--no-random-sleep-on-renew --run-deploy-hooks --no-directory-hooks
|
||
```
|
||
|
||
`--no-directory-hooks` 不替代审计 renewal 配置内的显式钩子。必须确认该证书配置仍明确调用专用 `/bin/sh …/renew-node.sh`,并检查演练后的服务状态及旧服务 PID/启动时间。关闭随机等待只用于本次演练可控等待,不等于修改常规定时调度。BrokenPipe/超时只记未确认,回查进程和最终结果后再决定是否重试,不重复发起签发。
|
||
|
||
续期完成条件包括:证书配置正确、调度 enabled/下一次触发可见、调度参数确实覆盖新证书及专用 hook、dry-run 退出状态和旧服务保护证据齐全。证书到期时间引用证书/域名对应记录,不把一次演练日期当作长期验收。
|
||
|
||
## 统一验收入口
|
||
|
||
每次在 QA_DIR 保存 700/600 的 QA 私密文件与完整实际订阅;文件名统一为 qa.json、subscription.json、验收结果和受保护日志,参数与 stage manifest 对照,不使用首节点默认路径。本地浏览器、服务器请求均按各自授权路线执行。
|
||
|
||
在已授权的网关环境,先用本次参数里的官方客户端检查完整配置,再运行完整隔离订阅:
|
||
|
||
```sh
|
||
"$CLIENT_BINARY" check -c "$QA_DIR/subscription.json"
|
||
python3 /opt/dpl-gateway/provision/verify-node.py \
|
||
--qa "$QA_DIR/qa.json" --subscription "$QA_DIR/subscription.json" \
|
||
--binary "$CLIENT_BINARY" --port "$LOCAL_SOCKS_PORT" \
|
||
--expected-exit "$EXPECTED_EXIT" --expected-country "$EXPECTED_COUNTRY" \
|
||
--report "$QA_REPORT" --run
|
||
```
|
||
|
||
上面脚本路径是既有网关检出约定,执行前核对实际 Git 版本与路径,若不同则使用本次确认路径,不复制临时代码替代。QA可按host/port唯一匹配本次节点,冲突时显式target-tag;正式多节点使用下方expectations。验证保留DNS/分流及全部出站,替换临时SOCKS入站,并仅为api.ipify.org与www.cloudflare.com两个诊断目的地添加指定出站规则,从而逐节点验证;不是原订阅所有路由均已验收。
|
||
|
||
| 验收层 | 必须保留的结果 |
|
||
| --- | --- |
|
||
| 参数一致 | 订阅包含本次入口/端口/SNI、严格 TLS 开启;机器/节点与 VPS 对应正确 |
|
||
| 协议/联网 | 官方客户端配置检查与完整启动结果、严格 TLS、目标 HTTPS、出口 IP 与 EXPECTED_EXIT 一致;脚本强制比对 EXPECTED_COUNTRY;仅结构核对不产生live_verified报告 |
|
||
| 订阅 | 有效用户标准/短路径按本次范围检查,JSON/gzip、private/no-store、无 HIT/Age/挑战;不要在日志保存令牌 |
|
||
| 上报 | readiness.php回读节点在线、last_check/last_push及QA上下行;按显式plans/group统计,缺省不选任何套餐 |
|
||
| 正式开放 | 正式有效用户订阅与完整expectations逐一对应,并逐节点验证;不把单节点QA结果扩大成全部可用 |
|
||
| QA 清理 | QA banned、其订阅拒绝、实际下发用户集合无 QA;客户端退出、临时本地秘密副本清理,服务器审计文件保留 |
|
||
| 回归 | 原节点/中转、套餐字段/用户组、订阅 URL、网关容器 ID/启动时间/重启计数与 before 快照对照 |
|
||
| 浏览器 | 正确反代入口,管理列表与保存结果回读;只查看后取消不算提交验收 |
|
||
|
||
面板回读命令入口如下;它只覆盖该脚本实际返回的节点/QA 字段,其他行须另留证据:
|
||
|
||
```sh
|
||
cd "$APP_ROOT"
|
||
php "$PROVISION_ROOT/readiness.php" --backup="$BACKUP" --group="$FORMAL_GROUP_ID"
|
||
```
|
||
|
||
GUI/手机、TUN、多地区、并发及用户明确跳过的测试分别标为未执行或跳过。未确认结果不补成通过;统一表格不替代真实执行。
|
||
|
||
### 正式多节点验证
|
||
|
||
在私有文件 FORMAL_EXPECTATIONS 保存每个AnyTLS出站的明确预期,完整覆盖订阅中的全部AnyTLS标签。每条结构:`tag`、`host`、整数`port`、`sni`、`uuid`、`expected_exit`、`expected_country`;uuid是该正式用户的实际密码,不能复制进普通参数单或文档。标签必须与订阅精确一致;不重命名节点。
|
||
|
||
```sh
|
||
python3 /opt/dpl-gateway/provision/verify-node.py \
|
||
--subscription "$QA_DIR/formal-subscription.json" \
|
||
--expectations "$FORMAL_EXPECTATIONS" --binary "$CLIENT_BINARY" \
|
||
--port "$LOCAL_SOCKS_PORT" --report "$FORMAL_REPORT" --run
|
||
```
|
||
|
||
不加run时只读取私有JSON并核对结构,不启动客户端、不发网络请求;run每次会先将旧报告失效,避免失败后误用旧成功结果。实时报告记录具体结果与时间,面板正式开放仅接受匹配manifest QA及端点、15分钟内的实时QA报告,正式多节点报告不能代替QA报告。
|
||
|
||
### 面板变更命令
|
||
|
||
以下命令默认只预览数据库字段变化;确认输出范围后,对同一命令追加 `--verification="$QA_REPORT" --apply` 才写入。append禁止传plans、subscribe-url和group-name;它不会修改现有套餐/正式用户/订阅地址。initialize对应已有套餐中的无组用户关联也属于实际写入范围,必须先看预览。
|
||
|
||
```sh
|
||
cd "$APP_ROOT"
|
||
php "$PROVISION_ROOT/promote.php" --backup="$BACKUP" --mode=append \
|
||
--group="$FORMAL_GROUP_ID"
|
||
```
|
||
|
||
首次初始化另用以下命令,按任务需要显式传group/group-name;没有这些参数时不自动改组名:
|
||
|
||
```sh
|
||
cd "$APP_ROOT"
|
||
php "$PROVISION_ROOT/promote.php" --backup="$BACKUP" --mode=initialize \
|
||
--plans="$PLAN_IDS" --subscribe-url="$SUBSCRIBE_URL"
|
||
```
|
||
|
||
promotion-journal.json记录允许写入字段、before/after与manifest。相同日志/参数重跑会比较实际字段,已应用则只确认;参数变化、已启动回退、旧promoted.json无新日志或对象冲突时停止。prepared可能意味着数据库未提交、已提交但后续通知/缓存/落盘失败;只有完整before或完整after匹配才恢复,中间/未知状态先人工处理。不要删除日志重新执行。
|
||
|
||
## 精确回退入口与证据契约
|
||
|
||
触发失败先停止正式开放,隔离新节点。回退按本次 manifest 指定对象执行;不恢复整库、不删除原卷、不停止旧节点。执行前取回当前值,只有当前值仍等于本次 after 才恢复 before;存在后续变化时停止本次自动回退,不写任何字段;专项人工恢复另行核对。
|
||
|
||
| 对象 | 必需恢复证据 | 动作及回读 |
|
||
| --- | --- | --- |
|
||
| append 新节点正式组 | 该 node_id 的 before/after group_ids、enabled/show 及实际变动字段 | 新rollback.php按日志恢复本次字段并禁用/隐藏节点;不动已有套餐/用户/订阅地址 |
|
||
| initialize 正式关联 | 新promotion-journal.json、manifest.json;旧before-promotion/promoted仅用于历史专项回退 | 按 ID 逐条恢复本次变动的套餐/用户组、节点组、组名、订阅 URL;缺 after 不盲目回填,以实际变更证据核对 |
|
||
| QA | test_user_id 与实际禁用状态 | 始终保持本次测试账号禁用、订阅拒绝、不下发;不因回退恢复 QA 活跃 |
|
||
| 中转 | 新增规则的真实 ID、入口和目标 before/after | 只停用本次新增规则,再回读;原规则保持 |
|
||
| 节点服务 | 新服务/unit/配置及安装前状态、原服务 PID/启动时间 | 在已授权节点上执行下方停止入口,只停止新 dpl-node,回查旧服务;不删证书/审计目录 |
|
||
| DNS/证书续期 | 本次记录 ID/旧值/新值、renewal/hook/timer 原文件及权限 | 仅撤回本次增改;已共用证书/调度不能直接删除,恢复后核对下一次调度及原服务 |
|
||
| 网关/模板/CF | 对应专项恢复点 | append 不应修改;initialize 或专项变更按原[恢复专题](NODE_ONBOARDING.md#回退与排障)逐项执行 |
|
||
|
||
节点上的停止入口(确认本服务确为本次新增后):
|
||
|
||
```sh
|
||
systemctl stop dpl-node
|
||
systemctl is-active dpl-node || test "$?" -eq 3
|
||
```
|
||
|
||
新日志的面板回退统一入口(默认预览,加apply才执行):
|
||
|
||
```sh
|
||
cd "$APP_ROOT"
|
||
php "$PROVISION_ROOT/rollback.php" --backup="$BACKUP"
|
||
```
|
||
|
||
回退逐字段核对当前值仍等于promotion记录的after,任何冲突整体停止;写回本次before、保持QA禁用,并禁用/隐藏本次节点。rollback-journal.json保存回退本身的意图与完成状态,重复执行也需匹配完整结果。旧日志不能自动补造after或升级成新日志。DNS、中转、远程服务、证书、网关/CF属于其他对象,仍按对应专项步骤和恢复证据处理;该面板脚本不包含跨服务器/服务商变更。
|
||
|
||
## 原交接测试清单与当前证据
|
||
|
||
2026-10-16编写时尚未测试或发布;2026-10-17已执行本节上方所列隔离测试、语法检查和独立运维快照部署,现场任务仍以STATUS区分完成范围。下列保留为完整验证清单,不表示每一项都已有独立用例或实际故障演练;未执行的项不能因部署而记为通过。
|
||
|
||
离线测试应在全新SQLite内存库/隔离应用容器中进行,禁止加载项目本地真实.env、默认数据库/Redis/队列或使用正式凭据:
|
||
|
||
1. append仅改变本次node.group_ids、QA.banned,现有订阅设置/全部套餐/正式用户/旧节点逐字段不变;拒绝append夹带plans/url/group-name。
|
||
2. initialize只修改明确套餐及其无组用户、指定订阅地址/可选组名;拒绝不存在ID、其他组冲突,验证原null订阅设置的创建及回退。
|
||
3. 默认预览无数据库写入;apply要求近期真实QA报告且QA身份、端点/SNI正确;结构报告、过期/错误QA报告不能通过。
|
||
4. 回读仅使用本次显式plans;无plans时不查询/统计隐含套餐集合。
|
||
5. 应用/回退幂等;数据库提交前失败、提交后通知/缓存/日志失败、prepared+完整before/after与混合冲突,不能重复创建或覆盖后续变化;QA始终不复活。
|
||
6. 多节点JSON用虚构身份;缺失/重复标签、端点/SNI/密码/严格TLS/国家/IP错误均失败。模拟子进程和传输,不发公网请求;默认无run绝不启动进程/开socket,失败后不能留下旧成功报告。
|
||
7. stage相同完整参数恢复缺失传输文件;参数变化、旧manifest、现有同名/同中转端点资源或已promote时拒绝接管;检查所有秘密文件权限。
|
||
8. 通过隔离测试之后,线上发布/验收仍需具体任务授权;测试本身不授权生产变更。节点命名按NODE_ONBOARDING执行,不因测试改名或分配编号。
|