落地 BgFilter 单实例受限资源 Worker
新增私有 BgFilter worker,提供内部鉴权、并发限流、超时、顺序重试、flat 熔断和图片校验。 父生成流程改为通过内部二进制 HTTP 原地等待,并保留 flat 降级与 complex 失败语义。 接入本地开发、systemd、生产部署、Provision、健康巡检和配置漂移门禁。 补充动画、部署与运维测试、Linux fixture 隔离以及对应架构文档。
This commit is contained in:
@@ -5,11 +5,11 @@ set -euo pipefail
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
用法:
|
||||
./scripts/deploy/production-api-deploy.sh --source-dir build/<version> [--version <version>] [--release-root /opt/genarrative/releases] [--current-link /opt/genarrative/current] [--service genarrative-api.service] [--pingora-service genarrative-pingora-gateway.service] [--require-pingora-gateway] [--worker-service-pattern 'genarrative-external-generation-worker@*.service'] [--no-worker-services] [--worker-controller-service genarrative-external-generation-controller.service] [--no-worker-controller] [--health-url http://127.0.0.1:8082/readyz] [--api-env-file /etc/genarrative/api-server.env] [--worker-env-file /etc/genarrative/external-generation-worker.env] [--database genarrative-prod] [--spacetime-server-url http://127.0.0.1:3101] [--keep-maintenance-mode]
|
||||
./scripts/deploy/production-api-deploy.sh --source-dir build/<version> [--version <version>] [--release-root /opt/genarrative/releases] [--current-link /opt/genarrative/current] [--service genarrative-api.service] [--pingora-service genarrative-pingora-gateway.service] [--require-pingora-gateway] [--bgfilter-worker-service genarrative-bgfilter-worker.service] [--bgfilter-worker-health-url http://127.0.0.1:8083/readyz] [--bgfilter-worker-env-file /etc/genarrative/bgfilter-worker.env] [--no-bgfilter-worker] [--worker-service-pattern 'genarrative-external-generation-worker@*.service'] [--no-worker-services] [--worker-controller-service genarrative-external-generation-controller.service] [--no-worker-controller] [--health-url http://127.0.0.1:8082/readyz] [--api-env-file /etc/genarrative/api-server.env] [--worker-env-file /etc/genarrative/external-generation-worker.env] [--database genarrative-prod] [--spacetime-server-url http://127.0.0.1:3101] [--keep-maintenance-mode]
|
||||
|
||||
说明:
|
||||
进入维护模式,校验并发布 api-server 单文件,更新 current 链接,重启 systemd 服务并执行 readiness 检查。
|
||||
默认同时重启外部生成 worker controller 和已加载的 worker 实例;未启用 worker 单元时会自动跳过。
|
||||
默认先停止、启动并验活唯一 BgFilter worker,再重启 API、外部生成 worker controller 和已加载的 worker 实例。
|
||||
若传入 --database,会在重启前把 GENARRATIVE_SPACETIME_DATABASE 写入 api-server 环境文件,避免服务继续读取旧库。
|
||||
若发布包包含 pingora-gateway,或传入 --require-pingora-gateway,部署脚本会要求 release manifest、二进制与 checksum 一致,再在 current 链接切换后先复核 systemd/env 仍是本机高端口 shadow 配置,启动或重启 Pingora 影子服务并复核 active。
|
||||
默认在 readiness 通过后退出维护模式;传入 --keep-maintenance-mode 时保留维护文件,供人工验收后再恢复公网。
|
||||
@@ -175,6 +175,81 @@ if matched_value is not None:
|
||||
fi
|
||||
}
|
||||
|
||||
env_contains_nonempty_assignment() {
|
||||
local file_path="$1"
|
||||
local key="$2"
|
||||
|
||||
if [[ ! -f "${file_path}" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local python_script='
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
path = Path(sys.argv[1])
|
||||
key = sys.argv[2]
|
||||
for raw_line in path.read_text(encoding="utf-8").splitlines():
|
||||
line = raw_line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
current_key, value = line.split("=", 1)
|
||||
if current_key.strip() != key:
|
||||
continue
|
||||
value = value.strip()
|
||||
if len(value) >= 2 and value[0] == value[-1] and value[0] in ("\"", chr(39)):
|
||||
value = value[1:-1]
|
||||
if value.strip():
|
||||
raise SystemExit(0)
|
||||
raise SystemExit(1)
|
||||
'
|
||||
|
||||
if [[ -r "${file_path}" ]]; then
|
||||
python3 -c "${python_script}" "${file_path}" "${key}"
|
||||
else
|
||||
if ! sudo -n true >/dev/null 2>&1; then
|
||||
echo "[production-api-deploy] 当前用户无权读取 ${file_path},且 sudo -n 不可用;无法检查运行态环境变量。" >&2
|
||||
exit 1
|
||||
fi
|
||||
sudo -n python3 -c "${python_script}" "${file_path}" "${key}"
|
||||
fi
|
||||
}
|
||||
|
||||
env_has_assignment() {
|
||||
local file_path="$1"
|
||||
local key="$2"
|
||||
|
||||
if [[ ! -f "${file_path}" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
local python_script='
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
path = Path(sys.argv[1])
|
||||
key = sys.argv[2]
|
||||
for raw_line in path.read_text(encoding="utf-8").splitlines():
|
||||
line = raw_line.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
current_key, _ = line.split("=", 1)
|
||||
if current_key.strip() == key:
|
||||
raise SystemExit(0)
|
||||
raise SystemExit(1)
|
||||
'
|
||||
|
||||
if [[ -r "${file_path}" ]]; then
|
||||
python3 -c "${python_script}" "${file_path}" "${key}"
|
||||
else
|
||||
if ! sudo -n true >/dev/null 2>&1; then
|
||||
echo "[production-api-deploy] 当前用户无权读取 ${file_path},且 sudo -n 不可用;无法检查运行态环境变量。" >&2
|
||||
exit 1
|
||||
fi
|
||||
sudo -n python3 -c "${python_script}" "${file_path}" "${key}"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_env_value() {
|
||||
local file_path="$1"
|
||||
local key="$2"
|
||||
@@ -303,10 +378,11 @@ ensure_runtime_env_and_dirs() {
|
||||
ensure_env_value_migrates_old_default "${api_env_file}" "GENARRATIVE_EXTERNAL_GENERATION_WORKER_LEASE_SECONDS" "3600" "600"
|
||||
ensure_env_value "${api_env_file}" "GENARRATIVE_EXTERNAL_GENERATION_WORKER_JOB_TIMEOUT_SECONDS" "900"
|
||||
ensure_env_value "${api_env_file}" "GENARRATIVE_EXTERNAL_GENERATION_WORKER_LONG_JOB_TIMEOUT_SECONDS" "1800"
|
||||
ensure_env_value "${api_env_file}" "GENARRATIVE_BGFILTER_WORKER_BASE_URL" "http://127.0.0.1:8083"
|
||||
ensure_env_value "${api_env_file}" "GENARRATIVE_BGFILTER_INTERNAL_TOKEN_FILE" "/etc/genarrative/secrets/bgfilter-worker.token"
|
||||
ensure_env_value "${api_env_file}" "GENARRATIVE_BGFILTER_WORKER_CONNECT_TIMEOUT_MS" "2000"
|
||||
ensure_runtime_bootstrap_secret_file_env "${api_env_file}"
|
||||
ensure_env_value_migrates_old_default "${api_env_file}" "GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS" "45000" "180000"
|
||||
ensure_env_value "${api_env_file}" "GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_FAILURE_THRESHOLD" "3"
|
||||
ensure_env_value "${api_env_file}" "GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_COOLDOWN_SECONDS" "300"
|
||||
|
||||
tracking_enabled="$(read_env_value "${api_env_file}" "GENARRATIVE_TRACKING_OUTBOX_ENABLED")"
|
||||
tracking_outbox_dir="$(read_env_value "${api_env_file}" "GENARRATIVE_TRACKING_OUTBOX_DIR")"
|
||||
@@ -351,6 +427,186 @@ ensure_worker_runtime_env_defaults() {
|
||||
ensure_runtime_bootstrap_secret_file_env "${worker_env_file}"
|
||||
}
|
||||
|
||||
ensure_bgfilter_worker_runtime_env_defaults() {
|
||||
local bgfilter_env_file="$1"
|
||||
|
||||
if [[ -z "${bgfilter_env_file}" ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ ! -f "${bgfilter_env_file}" ]]; then
|
||||
echo "[production-api-deploy] BgFilter worker 环境文件不存在: ${bgfilter_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
ensure_env_value "${bgfilter_env_file}" "GENARRATIVE_BGFILTER_WORKER_HOST" "127.0.0.1"
|
||||
ensure_env_value "${bgfilter_env_file}" "GENARRATIVE_BGFILTER_WORKER_PORT" "8083"
|
||||
ensure_env_value "${bgfilter_env_file}" "GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_FAILURE_THRESHOLD" "3"
|
||||
ensure_env_value "${bgfilter_env_file}" "GENARRATIVE_EDITOR_BGFILTER_CIRCUIT_COOLDOWN_SECONDS" "300"
|
||||
}
|
||||
|
||||
validate_bgfilter_shared_runtime_env() {
|
||||
local api_env_file="$1"
|
||||
local request_timeout_ms connect_timeout_ms
|
||||
|
||||
request_timeout_ms="$(read_env_value "${api_env_file}" "GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS")"
|
||||
if [[ ! "${request_timeout_ms}" =~ ^[1-9][0-9]*$ ]]; then
|
||||
echo "[production-api-deploy] GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS 必须在共享 API env 中配置为正整数毫秒: ${api_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
connect_timeout_ms="$(read_env_value "${api_env_file}" "GENARRATIVE_BGFILTER_WORKER_CONNECT_TIMEOUT_MS")"
|
||||
if [[ ! "${connect_timeout_ms}" =~ ^[1-9][0-9]*$ ]]; then
|
||||
echo "[production-api-deploy] GENARRATIVE_BGFILTER_WORKER_CONNECT_TIMEOUT_MS 必须在共享 API env 中配置为正整数毫秒: ${api_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_bgfilter_worker_capacity() {
|
||||
local bgfilter_env_file="$1"
|
||||
local concurrency max_requests
|
||||
|
||||
concurrency="$(read_env_value "${bgfilter_env_file}" "GENARRATIVE_BGFILTER_WORKER_CONCURRENCY")"
|
||||
max_requests="$(read_env_value "${bgfilter_env_file}" "GENARRATIVE_BGFILTER_WORKER_MAX_REQUESTS")"
|
||||
if [[ ! "${concurrency}" =~ ^[1-9][0-9]{0,8}$ ]]; then
|
||||
echo "[production-api-deploy] GENARRATIVE_BGFILTER_WORKER_CONCURRENCY 必须是正整数: ${bgfilter_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ ! "${max_requests}" =~ ^[1-9][0-9]{0,8}$ ]]; then
|
||||
echo "[production-api-deploy] GENARRATIVE_BGFILTER_WORKER_MAX_REQUESTS 必须是正整数: ${bgfilter_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
if (( 10#${max_requests} < 10#${concurrency} )); then
|
||||
echo "[production-api-deploy] GENARRATIVE_BGFILTER_WORKER_MAX_REQUESTS 必须大于或等于 CONCURRENCY: ${bgfilter_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_bgfilter_worker_shared_env_alignment() {
|
||||
local api_env_file="$1"
|
||||
local bgfilter_env_file="$2"
|
||||
local key shared_value dedicated_value
|
||||
|
||||
for key in \
|
||||
GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS \
|
||||
GENARRATIVE_EDITOR_BGFILTER_BASE_URL \
|
||||
GENARRATIVE_EDITOR_BGFILTER_TOKEN \
|
||||
GENARRATIVE_BGFILTER_INTERNAL_TOKEN_FILE \
|
||||
ALIYUN_OSS_BUCKET \
|
||||
ALIYUN_OSS_ENDPOINT \
|
||||
ALIYUN_OSS_ACCESS_KEY_ID \
|
||||
ALIYUN_OSS_ACCESS_KEY_SECRET \
|
||||
ALIYUN_OSS_READ_EXPIRE_SECONDS; do
|
||||
if ! env_has_assignment "${bgfilter_env_file}" "${key}"; then
|
||||
continue
|
||||
fi
|
||||
dedicated_value="$(read_env_value "${bgfilter_env_file}" "${key}")"
|
||||
shared_value="$(read_env_value "${api_env_file}" "${key}")"
|
||||
if [[ "${dedicated_value}" != "${shared_value}" ]]; then
|
||||
echo "[production-api-deploy] BgFilter 专属 env 中的共享配置与 API env 不一致: ${key};请迁移到 ${api_env_file} 并从 ${bgfilter_env_file} 删除重复项。" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
validate_external_generation_worker_bgfilter_env_alignment() {
|
||||
local api_env_file="$1"
|
||||
local worker_env_file="$2"
|
||||
local key shared_value worker_value
|
||||
|
||||
if [[ -z "${worker_env_file}" || ! -f "${worker_env_file}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
for key in \
|
||||
GENARRATIVE_EDITOR_BGFILTER_REQUEST_TIMEOUT_MS \
|
||||
GENARRATIVE_BGFILTER_WORKER_BASE_URL \
|
||||
GENARRATIVE_BGFILTER_INTERNAL_TOKEN_FILE \
|
||||
GENARRATIVE_BGFILTER_WORKER_CONNECT_TIMEOUT_MS \
|
||||
ALIYUN_OSS_BUCKET \
|
||||
ALIYUN_OSS_ENDPOINT; do
|
||||
if ! env_has_assignment "${worker_env_file}" "${key}"; then
|
||||
continue
|
||||
fi
|
||||
worker_value="$(read_env_value "${worker_env_file}" "${key}")"
|
||||
shared_value="$(read_env_value "${api_env_file}" "${key}")"
|
||||
if [[ "${worker_value}" != "${shared_value}" ]]; then
|
||||
echo "[production-api-deploy] 外部生成 worker env 中的 BgFilter 共享配置与 API env 不一致: ${key};${worker_env_file} 会在 systemd 中后加载并覆盖父侧有效值。" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
validate_bgfilter_loopback_endpoint_alignment() {
|
||||
local api_env_file="$1"
|
||||
local bgfilter_env_file="$2"
|
||||
local health_url="$3"
|
||||
local base_url host port expected_base_url expected_health_url
|
||||
|
||||
base_url="$(read_env_value "${api_env_file}" "GENARRATIVE_BGFILTER_WORKER_BASE_URL")"
|
||||
host="$(read_env_value "${bgfilter_env_file}" "GENARRATIVE_BGFILTER_WORKER_HOST")"
|
||||
port="$(read_env_value "${bgfilter_env_file}" "GENARRATIVE_BGFILTER_WORKER_PORT")"
|
||||
|
||||
if [[ "${host}" != "127.0.0.1" ]]; then
|
||||
echo "[production-api-deploy] BgFilter worker 首版必须监听 127.0.0.1,当前 GENARRATIVE_BGFILTER_WORKER_HOST=${host:-<empty>}: ${bgfilter_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ ! "${port}" =~ ^[1-9][0-9]{0,4}$ ]] || (( 10#${port} > 65535 )); then
|
||||
echo "[production-api-deploy] GENARRATIVE_BGFILTER_WORKER_PORT 必须是 1-65535 的有效端口: ${bgfilter_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
expected_base_url="http://${host}:${port}"
|
||||
if [[ "${base_url%/}" != "${expected_base_url}" ]]; then
|
||||
echo "[production-api-deploy] 父进程 GENARRATIVE_BGFILTER_WORKER_BASE_URL 必须与 BgFilter worker 有效监听地址一致: expected=${expected_base_url}, actual=${base_url:-<empty>}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
expected_health_url="${expected_base_url}/readyz"
|
||||
if [[ "${health_url}" != "${expected_health_url}" ]]; then
|
||||
echo "[production-api-deploy] --bgfilter-worker-health-url 必须与父进程 base URL 和子 worker listener 指向同一 loopback endpoint: expected=${expected_health_url}, actual=${health_url:-<empty>}" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_no_bgfilter_internal_token_plaintext() {
|
||||
local env_file
|
||||
|
||||
for env_file in "$@"; do
|
||||
if [[ -z "${env_file}" ]]; then
|
||||
continue
|
||||
fi
|
||||
if env_contains_nonempty_assignment "${env_file}" "GENARRATIVE_BGFILTER_INTERNAL_TOKEN"; then
|
||||
echo "[production-api-deploy] ${env_file} 不得保存 GENARRATIVE_BGFILTER_INTERNAL_TOKEN 明文;生产环境只允许使用 GENARRATIVE_BGFILTER_INTERNAL_TOKEN_FILE。" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
validate_bgfilter_internal_token_file() {
|
||||
local api_env_file="$1"
|
||||
local token_file token_metadata
|
||||
|
||||
token_file="$(read_env_value "${api_env_file}" "GENARRATIVE_BGFILTER_INTERNAL_TOKEN_FILE")"
|
||||
if [[ -z "${token_file}" || "${token_file}" != /* ]]; then
|
||||
echo "[production-api-deploy] GENARRATIVE_BGFILTER_INTERNAL_TOKEN_FILE 必须指向绝对路径: ${api_env_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ -L "${token_file}" || ! -f "${token_file}" || ! -s "${token_file}" ]]; then
|
||||
echo "[production-api-deploy] BgFilter 内部 Token 必须是非空普通文件且不能是符号链接: ${token_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
if ! run_privileged grep -q '[^[:space:]]' -- "${token_file}"; then
|
||||
echo "[production-api-deploy] BgFilter 内部 Token 文件必须至少包含一个非空白字符: ${token_file}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
token_metadata="$(run_privileged stat -c '%U:%G:%a' -- "${token_file}")"
|
||||
if [[ "${token_metadata}" != "root:genarrative:440" ]]; then
|
||||
echo "[production-api-deploy] BgFilter 内部 Token 权限必须为 root:genarrative 0440,且必须是普通文件: ${token_file} (${token_metadata})" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
extract_pingora_env_files_from_unit() {
|
||||
local service_name="$1"
|
||||
local unit_content
|
||||
@@ -572,8 +828,17 @@ install_worker_systemd_units() {
|
||||
local release_dir="$1"
|
||||
local pattern="$2"
|
||||
local controller_service="$3"
|
||||
local bgfilter_service="$4"
|
||||
local installed_any=0
|
||||
|
||||
if [[ "${bgfilter_service}" == "genarrative-bgfilter-worker.service" ]]; then
|
||||
install_release_systemd_unit \
|
||||
"${release_dir}/deploy/systemd/genarrative-bgfilter-worker.service" \
|
||||
"genarrative-bgfilter-worker.service" \
|
||||
"BgFilter worker systemd 单元"
|
||||
installed_any=1
|
||||
fi
|
||||
|
||||
if [[ "${pattern}" == "genarrative-external-generation-worker@*.service" ]]; then
|
||||
install_release_systemd_unit \
|
||||
"${release_dir}/deploy/systemd/genarrative-external-generation-worker@.service" \
|
||||
@@ -688,6 +953,38 @@ wait_for_worker_controller_service() {
|
||||
return 1
|
||||
}
|
||||
|
||||
restart_and_wait_for_bgfilter_worker() {
|
||||
local service="$1"
|
||||
local health_url="$2"
|
||||
|
||||
if [[ -z "${service}" ]]; then
|
||||
echo "[production-api-deploy] 跳过 BgFilter worker 启动。"
|
||||
return 0
|
||||
fi
|
||||
if ! systemctl cat "${service}" >/dev/null 2>&1; then
|
||||
echo "[production-api-deploy] 缺少 BgFilter worker systemd 单元: ${service}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "[production-api-deploy] 停止旧 BgFilter worker 并等待在途请求排空: ${service}"
|
||||
systemctl stop "${service}"
|
||||
systemctl enable "${service}"
|
||||
echo "[production-api-deploy] 启动唯一 BgFilter worker: ${service}"
|
||||
systemctl start "${service}"
|
||||
|
||||
for _ in {1..30}; do
|
||||
if systemctl is-active --quiet "${service}" && curl -fsS --max-time 2 "${health_url}" >/dev/null; then
|
||||
echo "[production-api-deploy] BgFilter worker readiness 通过: ${health_url}"
|
||||
return 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
systemctl --no-pager --full status "${service}" || true
|
||||
echo "[production-api-deploy] BgFilter worker readiness 检查超时: ${health_url}" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
SOURCE_DIR=""
|
||||
VERSION=""
|
||||
@@ -697,6 +994,9 @@ SERVICE_NAME="genarrative-api.service"
|
||||
PINGORA_SERVICE_NAME="genarrative-pingora-gateway.service"
|
||||
WORKER_SERVICE_PATTERN="genarrative-external-generation-worker@*.service"
|
||||
WORKER_CONTROLLER_SERVICE="genarrative-external-generation-controller.service"
|
||||
BGFILTER_WORKER_SERVICE="genarrative-bgfilter-worker.service"
|
||||
BGFILTER_WORKER_HEALTH_URL="http://127.0.0.1:8083/readyz"
|
||||
BGFILTER_WORKER_ENV_FILE="/etc/genarrative/bgfilter-worker.env"
|
||||
HEALTH_URL="http://127.0.0.1:8082/readyz"
|
||||
API_ENV_FILE="/etc/genarrative/api-server.env"
|
||||
WORKER_ENV_FILE="/etc/genarrative/external-generation-worker.env"
|
||||
@@ -766,6 +1066,23 @@ while [[ $# -gt 0 ]]; do
|
||||
WORKER_CONTROLLER_SERVICE=""
|
||||
shift
|
||||
;;
|
||||
--bgfilter-worker-service)
|
||||
BGFILTER_WORKER_SERVICE="${2:?缺少 --bgfilter-worker-service 的值}"
|
||||
shift 2
|
||||
;;
|
||||
--bgfilter-worker-health-url)
|
||||
BGFILTER_WORKER_HEALTH_URL="${2:?缺少 --bgfilter-worker-health-url 的值}"
|
||||
shift 2
|
||||
;;
|
||||
--bgfilter-worker-env-file)
|
||||
BGFILTER_WORKER_ENV_FILE="${2:?缺少 --bgfilter-worker-env-file 的值}"
|
||||
shift 2
|
||||
;;
|
||||
--no-bgfilter-worker)
|
||||
BGFILTER_WORKER_SERVICE=""
|
||||
BGFILTER_WORKER_ENV_FILE=""
|
||||
shift
|
||||
;;
|
||||
--health-url)
|
||||
HEALTH_URL="${2:?缺少 --health-url 的值}"
|
||||
shift 2
|
||||
@@ -801,6 +1118,9 @@ require_absolute_path "${API_ENV_FILE}" "--api-env-file"
|
||||
if [[ -n "${WORKER_ENV_FILE}" ]]; then
|
||||
require_absolute_path "${WORKER_ENV_FILE}" "--worker-env-file"
|
||||
fi
|
||||
if [[ -n "${BGFILTER_WORKER_ENV_FILE}" ]]; then
|
||||
require_absolute_path "${BGFILTER_WORKER_ENV_FILE}" "--bgfilter-worker-env-file"
|
||||
fi
|
||||
|
||||
if [[ -n "${DATABASE}" ]]; then
|
||||
validate_spacetime_database_name "${DATABASE}"
|
||||
@@ -1127,8 +1447,20 @@ if [[ -n "${SPACETIME_SERVER_URL}" ]]; then
|
||||
fi
|
||||
|
||||
ensure_runtime_env_and_dirs "${API_ENV_FILE}"
|
||||
validate_bgfilter_shared_runtime_env "${API_ENV_FILE}"
|
||||
validate_real_wechat_pay_refund_reconciliation "${API_ENV_FILE}"
|
||||
ensure_worker_runtime_env_defaults "${WORKER_ENV_FILE}"
|
||||
ensure_bgfilter_worker_runtime_env_defaults "${BGFILTER_WORKER_ENV_FILE}"
|
||||
validate_external_generation_worker_bgfilter_env_alignment "${API_ENV_FILE}" "${WORKER_ENV_FILE}"
|
||||
validate_no_bgfilter_internal_token_plaintext "${API_ENV_FILE}" "${WORKER_ENV_FILE}" "${BGFILTER_WORKER_ENV_FILE}"
|
||||
if [[ -n "${BGFILTER_WORKER_SERVICE}" ]]; then
|
||||
validate_bgfilter_internal_token_file "${API_ENV_FILE}"
|
||||
validate_bgfilter_loopback_endpoint_alignment "${API_ENV_FILE}" "${BGFILTER_WORKER_ENV_FILE}" "${BGFILTER_WORKER_HEALTH_URL}"
|
||||
fi
|
||||
if [[ -n "${BGFILTER_WORKER_ENV_FILE}" ]]; then
|
||||
validate_bgfilter_worker_capacity "${BGFILTER_WORKER_ENV_FILE}"
|
||||
validate_bgfilter_worker_shared_env_alignment "${API_ENV_FILE}" "${BGFILTER_WORKER_ENV_FILE}"
|
||||
fi
|
||||
migrate_legacy_editor_generation_pricing_override "${CURRENT_LINK}"
|
||||
|
||||
if [[ "${PINGORA_INCLUDED}" -eq 1 ]]; then
|
||||
@@ -1149,7 +1481,9 @@ 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}"
|
||||
install_worker_systemd_units "${RELEASE_DIR}" "${WORKER_SERVICE_PATTERN}" "${WORKER_CONTROLLER_SERVICE}" "${BGFILTER_WORKER_SERVICE}"
|
||||
|
||||
restart_and_wait_for_bgfilter_worker "${BGFILTER_WORKER_SERVICE}" "${BGFILTER_WORKER_HEALTH_URL}"
|
||||
|
||||
echo "[production-api-deploy] 重启服务: ${SERVICE_NAME}"
|
||||
systemctl restart "${SERVICE_NAME}"
|
||||
|
||||
Reference in New Issue
Block a user