修复 API 发布安装外部生成 worker 模板

API deploy 从随包安装外部生成 worker 模板和 controller 单元
安装 worker systemd 单元后自动 daemon-reload
补充 API release 与 deploy 动态门禁覆盖 worker systemd 模板
This commit is contained in:
2026-06-23 01:01:59 +08:00
parent 79257f6e4a
commit 14f8a87ac5
3 changed files with 116 additions and 2 deletions
+52 -2
View File
@@ -209,6 +209,34 @@ function assertDeployCopiesPingoraDirectReleaseDependencies() {
),
'current release 必须包含 Pingora 直连 drop-in 模板。',
);
assertFileExists(
path.join(
releaseDir,
'deploy/systemd/genarrative-external-generation-worker@.service',
),
'current release 必须包含外部生成 worker systemd 模板。',
);
assertFileExists(
path.join(
releaseDir,
'deploy/systemd/genarrative-external-generation-controller.service',
),
'current release 必须包含外部生成 worker controller systemd 单元。',
);
assertFileExists(
path.join(
fixture.systemdUnitDir,
'genarrative-external-generation-worker@.service',
),
'API deploy 必须把随包外部生成 worker 模板安装到 systemd unit 目录。',
);
assertFileExists(
path.join(
fixture.systemdUnitDir,
'genarrative-external-generation-controller.service',
),
'API deploy 必须把随包外部生成 worker controller 单元安装到 systemd unit 目录。',
);
assertFileExists(
path.join(releaseDir, 'deploy/pingora/pingora-gateway.env.example'),
'current release 必须包含 Pingora env 示例。',
@@ -260,6 +288,11 @@ function assertDeployCopiesPingoraDirectReleaseDependencies() {
);
const commandsLog = readFileSync(fixture.commandsLog, 'utf8');
assertIncludes(
commandsLog,
'systemctl daemon-reload',
'安装 worker systemd 单元后必须 daemon-reload。',
);
assertIncludes(
commandsLog,
'systemctl restart genarrative-api.service',
@@ -1136,6 +1169,7 @@ function prepareFixture(name) {
const maintenanceFile = path.join(root, 'maintenance', 'enabled');
const fakeBin = path.join(root, 'bin');
const commandsLog = path.join(root, 'commands.log');
const systemdUnitDir = path.join(root, 'etc', 'systemd', 'system');
const workerStateFile = path.join(root, 'worker-service-enabled');
const pingoraStateFile = path.join(root, 'pingora-service-active');
const version = `20260614-${name}`;
@@ -1299,6 +1333,20 @@ function prepareFixture(name) {
'deploy/systemd/genarrative-pingora-gateway-direct-entry.conf',
),
);
copyFile(
'deploy/systemd/genarrative-external-generation-worker@.service',
path.join(
sourceDir,
'deploy/systemd/genarrative-external-generation-worker@.service',
),
);
copyFile(
'deploy/systemd/genarrative-external-generation-controller.service',
path.join(
sourceDir,
'deploy/systemd/genarrative-external-generation-controller.service',
),
);
copyFile(
'deploy/pingora/pingora-gateway.env.example',
path.join(sourceDir, 'deploy/pingora/pingora-gateway.env.example'),
@@ -1360,11 +1408,11 @@ function prepareFixture(name) {
' fi',
' exit 0',
'fi',
'if [[ "$1 $2" == "enable --now" && "${3:-}" == "genarrative-external-generation-worker@1.service" ]]; then',
'if [[ "$1 ${2:-}" == "enable --now" && "${3:-}" == "genarrative-external-generation-worker@1.service" ]]; then',
' printf "enabled\\n" > "${worker_state_file}"',
' exit 0',
'fi',
'if [[ "$1 $2 ${3:-}" == "is-active --quiet genarrative-pingora-gateway.service" ]]; then',
'if [[ "$1 ${2:-} ${3:-}" == "is-active --quiet genarrative-pingora-gateway.service" ]]; then',
' if [[ "${FAKE_PINGORA_ACTIVE:-true}" == "true" || -f "${pingora_state_file}" ]]; then',
' exit 0',
' fi',
@@ -1443,6 +1491,7 @@ function prepareFixture(name) {
maintenanceFile,
fakeBin,
commandsLog,
systemdUnitDir,
workerStateFile,
pingoraStateFile,
version,
@@ -1534,6 +1583,7 @@ function runDeploy(fixture, options = {}) {
FAKE_RELEASE_ROOT: fixture.releaseRoot,
FAKE_RELEASE_VERSION: fixture.version,
FAKE_WORKER_STATE_FILE: fixture.workerStateFile,
GENARRATIVE_SYSTEMD_UNIT_DIR: fixture.systemdUnitDir,
},
},
);
+14
View File
@@ -244,6 +244,20 @@ function assertApiReleaseContainsPingoraDirectDependencies() {
),
'API release 必须包含 Pingora 直连 drop-in 模板。',
);
assertFileExists(
path.join(
releaseDir,
'deploy/systemd/genarrative-external-generation-worker@.service',
),
'API release 必须包含外部生成 worker systemd 模板。',
);
assertFileExists(
path.join(
releaseDir,
'deploy/systemd/genarrative-external-generation-controller.service',
),
'API release 必须包含外部生成 worker controller systemd 单元。',
);
assertFileExists(
path.join(releaseDir, 'deploy/pingora/pingora-gateway.env.example'),
'API release 必须包含 Pingora env 示例。',
+50
View File
@@ -421,6 +421,54 @@ ensure_default_worker_service() {
systemctl enable --now "${default_service}"
}
install_release_systemd_unit() {
local source_path="$1"
local unit_name="$2"
local label="$3"
local unit_dir="${GENARRATIVE_SYSTEMD_UNIT_DIR:-/etc/systemd/system}"
if [[ ! -f "${source_path}" ]]; then
echo "[production-api-deploy] 发布产物缺少${label}: ${source_path}" >&2
return 1
fi
if [[ "${unit_dir}" != /* ]]; then
echo "[production-api-deploy] systemd unit 目录必须使用绝对路径: ${unit_dir}" >&2
return 1
fi
echo "[production-api-deploy] 安装${label}: ${unit_name}"
run_privileged install -d -m 0755 "${unit_dir}"
run_privileged install -m 0644 "${source_path}" "${unit_dir}/${unit_name}"
}
install_worker_systemd_units() {
local release_dir="$1"
local pattern="$2"
local controller_service="$3"
local installed_any=0
if [[ "${pattern}" == "genarrative-external-generation-worker@*.service" ]]; then
install_release_systemd_unit \
"${release_dir}/deploy/systemd/genarrative-external-generation-worker@.service" \
"genarrative-external-generation-worker@.service" \
"外部生成 worker systemd 模板"
installed_any=1
fi
if [[ "${controller_service}" == "genarrative-external-generation-controller.service" ]]; then
install_release_systemd_unit \
"${release_dir}/deploy/systemd/genarrative-external-generation-controller.service" \
"genarrative-external-generation-controller.service" \
"外部生成 worker controller systemd 单元"
installed_any=1
fi
if [[ "${installed_any}" -eq 1 ]]; then
echo "[production-api-deploy] 重新加载 systemd unit。"
systemctl daemon-reload
fi
}
restart_worker_services() {
local pattern="$1"
local services=()
@@ -917,6 +965,8 @@ if [[ "${PINGORA_INCLUDED}" -eq 1 ]]; then
ensure_pingora_shadow_service "${PINGORA_SERVICE_NAME}" "${PINGORA_SHADOW_ENV_FILE}"
fi
install_worker_systemd_units "${RELEASE_DIR}" "${WORKER_SERVICE_PATTERN}" "${WORKER_CONTROLLER_SERVICE}"
echo "[production-api-deploy] 重启服务: ${SERVICE_NAME}"
systemctl restart "${SERVICE_NAME}"
restart_worker_services "${WORKER_SERVICE_PATTERN}"