From 1189e2856fa0e4d091ef5638d167e10302012f9a Mon Sep 17 00:00:00 2001 From: kdletters Date: Fri, 19 Jun 2026 11:00:36 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E9=BD=90=E9=92=B1=E5=8C=85=E9=80=80?= =?UTF-8?q?=E6=AC=BE=E5=87=BA=E7=AE=B1=E9=83=A8=E7=BD=B2=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为容器与生产环境示例补齐钱包退款出箱默认变量 发布脚本自动补齐并创建钱包退款出箱运行目录 server provision 同步写入钱包退款出箱默认配置与目录 修复 production-api-deploy 检查对本地特权命令与负向日志的模拟 --- deploy/container/api-server.Dockerfile | 2 +- deploy/container/api-server.env.example | 5 ++++ deploy/env/api-server.env.example | 5 ++++ scripts/check-production-api-deploy.mjs | 34 +++++++++++++++++++++++-- scripts/deploy/production-api-deploy.sh | 12 ++++++++- scripts/jenkins-server-provision.sh | 7 ++++- 6 files changed, 60 insertions(+), 5 deletions(-) diff --git a/deploy/container/api-server.Dockerfile b/deploy/container/api-server.Dockerfile index 686df1999..ef72a30a9 100644 --- a/deploy/container/api-server.Dockerfile +++ b/deploy/container/api-server.Dockerfile @@ -16,7 +16,7 @@ RUN apt-get update && \ COPY --from=rust-builder /tmp/api-server /usr/local/bin/api-server -RUN mkdir -p /var/lib/genarrative/auth /var/lib/genarrative/tracking-outbox && \ +RUN mkdir -p /var/lib/genarrative/auth /var/lib/genarrative/tracking-outbox /var/lib/genarrative/wallet-refund-outbox && \ chown -R genarrative:genarrative /srv/genarrative /var/lib/genarrative USER genarrative diff --git a/deploy/container/api-server.env.example b/deploy/container/api-server.env.example index 9c95130a4..6bf7a53d4 100644 --- a/deploy/container/api-server.env.example +++ b/deploy/container/api-server.env.example @@ -25,6 +25,11 @@ GENARRATIVE_TRACKING_OUTBOX_DIR=/var/lib/genarrative/tracking-outbox GENARRATIVE_TRACKING_OUTBOX_BATCH_SIZE=500 GENARRATIVE_TRACKING_OUTBOX_FLUSH_INTERVAL_MS=1000 GENARRATIVE_TRACKING_OUTBOX_MAX_BYTES=268435456 +GENARRATIVE_WALLET_REFUND_OUTBOX_ENABLED=true +GENARRATIVE_WALLET_REFUND_OUTBOX_DIR=/var/lib/genarrative/wallet-refund-outbox +GENARRATIVE_WALLET_REFUND_OUTBOX_BATCH_SIZE=100 +GENARRATIVE_WALLET_REFUND_OUTBOX_FLUSH_INTERVAL_MS=1000 +GENARRATIVE_WALLET_REFUND_OUTBOX_MAX_BYTES=67108864 GENARRATIVE_OTEL_ENABLED=true OTEL_SERVICE_NAME=genarrative-api diff --git a/deploy/env/api-server.env.example b/deploy/env/api-server.env.example index b967c534d..dc0b399c2 100644 --- a/deploy/env/api-server.env.example +++ b/deploy/env/api-server.env.example @@ -25,6 +25,11 @@ GENARRATIVE_TRACKING_OUTBOX_DIR=/var/lib/genarrative/tracking-outbox GENARRATIVE_TRACKING_OUTBOX_BATCH_SIZE=500 GENARRATIVE_TRACKING_OUTBOX_FLUSH_INTERVAL_MS=1000 GENARRATIVE_TRACKING_OUTBOX_MAX_BYTES=268435456 +GENARRATIVE_WALLET_REFUND_OUTBOX_ENABLED=true +GENARRATIVE_WALLET_REFUND_OUTBOX_DIR=/var/lib/genarrative/wallet-refund-outbox +GENARRATIVE_WALLET_REFUND_OUTBOX_BATCH_SIZE=100 +GENARRATIVE_WALLET_REFUND_OUTBOX_FLUSH_INTERVAL_MS=1000 +GENARRATIVE_WALLET_REFUND_OUTBOX_MAX_BYTES=67108864 GENARRATIVE_OTEL_ENABLED=true OTEL_SERVICE_NAME=genarrative-api OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318 diff --git a/scripts/check-production-api-deploy.mjs b/scripts/check-production-api-deploy.mjs index 3d6d5cc7a..7292a28c7 100644 --- a/scripts/check-production-api-deploy.mjs +++ b/scripts/check-production-api-deploy.mjs @@ -75,6 +75,13 @@ function main() { assertMissingPingoraCanaryAccessLogParityFails(); } +function readOptionalCommandsLog(fixture) { + if (!existsSync(fixture.commandsLog)) { + return ''; + } + return readFileSync(fixture.commandsLog, 'utf8'); +} + function assertDeployCopiesPingoraDirectReleaseDependencies() { const fixture = prepareFixture('with-direct-checks'); const result = runDeploy(fixture); @@ -361,7 +368,7 @@ function assertDeployRejectsPingoraDirectEntryWhenArtifactIncluded() { 'Pingora systemd 已包含 CAP_NET_BIND_SERVICE', 'direct-entry capability 存在时必须给出明确错误。', ); - const commandsLog = readFileSync(fixture.commandsLog, 'utf8'); + const commandsLog = readOptionalCommandsLog(fixture); if ( commandsLog.includes( 'systemctl restart genarrative-pingora-gateway.service', @@ -394,7 +401,7 @@ function assertDeployRejectsPingoraPublicListenWhenArtifactIncluded() { 'Pingora 自动启动只允许 shadow 监听 127.0.0.1:18081', '公网监听 env 存在时必须给出明确错误。', ); - const commandsLog = readFileSync(fixture.commandsLog, 'utf8'); + const commandsLog = readOptionalCommandsLog(fixture); if ( commandsLog.includes( 'systemctl restart genarrative-pingora-gateway.service', @@ -1152,6 +1159,7 @@ function prepareFixture(name) { apiEnvFile, [ 'GENARRATIVE_TRACKING_OUTBOX_ENABLED=false', + `GENARRATIVE_WALLET_REFUND_OUTBOX_DIR=${path.join(root, 'wallet-refund-outbox')}`, 'GENARRATIVE_API_SHUTDOWN_OUTBOX_FLUSH_TIMEOUT_MS=5000', '', ].join('\n'), @@ -1399,9 +1407,31 @@ function prepareFixture(name) { ].join('\n'), 'utf8', ); + writeFileSync( + path.join(fakeBin, 'sudo'), + [ + '#!/usr/bin/env bash', + 'set -euo pipefail', + 'if [[ "${1:-}" == "-n" ]]; then', + ' shift', + 'fi', + 'if [[ "${1:-}" == "true" ]]; then', + ' exit 0', + 'fi', + 'if [[ "${1:-}" == "install" && "${2:-}" == "-d" ]]; then', + ' path="${@: -1}"', + ' mkdir -p "${path}"', + ' exit 0', + 'fi', + 'exec "$@"', + '', + ].join('\n'), + 'utf8', + ); chmodExecutable(path.join(fakeBin, 'systemctl')); chmodExecutable(path.join(fakeBin, 'curl')); chmodExecutable(path.join(fakeBin, 'cp')); + chmodExecutable(path.join(fakeBin, 'sudo')); return { root, diff --git a/scripts/deploy/production-api-deploy.sh b/scripts/deploy/production-api-deploy.sh index 851d897a2..abbea0b48 100644 --- a/scripts/deploy/production-api-deploy.sh +++ b/scripts/deploy/production-api-deploy.sh @@ -217,7 +217,7 @@ ensure_runtime_dir() { ensure_runtime_env_and_dirs() { local api_env_file="$1" - local tracking_enabled tracking_outbox_dir + local tracking_enabled tracking_outbox_dir wallet_refund_enabled wallet_refund_outbox_dir # 旧生产环境文件会被 server-provision 保留,不一定包含新增的运行态写入路径。 # 发布前只补缺省值,不覆盖线上已经定制过的目录或开关。 @@ -227,12 +227,22 @@ ensure_runtime_env_and_dirs() { ensure_env_value "${api_env_file}" "GENARRATIVE_TRACKING_OUTBOX_BATCH_SIZE" "500" ensure_env_value "${api_env_file}" "GENARRATIVE_TRACKING_OUTBOX_FLUSH_INTERVAL_MS" "1000" ensure_env_value "${api_env_file}" "GENARRATIVE_TRACKING_OUTBOX_MAX_BYTES" "268435456" + ensure_env_value "${api_env_file}" "GENARRATIVE_WALLET_REFUND_OUTBOX_ENABLED" "true" + ensure_env_value "${api_env_file}" "GENARRATIVE_WALLET_REFUND_OUTBOX_DIR" "/var/lib/genarrative/wallet-refund-outbox" + ensure_env_value "${api_env_file}" "GENARRATIVE_WALLET_REFUND_OUTBOX_BATCH_SIZE" "100" + ensure_env_value "${api_env_file}" "GENARRATIVE_WALLET_REFUND_OUTBOX_FLUSH_INTERVAL_MS" "1000" + ensure_env_value "${api_env_file}" "GENARRATIVE_WALLET_REFUND_OUTBOX_MAX_BYTES" "67108864" 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")" if [[ "$(printf "%s" "${tracking_enabled}" | tr '[:upper:]' '[:lower:]')" != "false" ]]; then ensure_runtime_dir "${tracking_outbox_dir}" "0750" fi + wallet_refund_enabled="$(read_env_value "${api_env_file}" "GENARRATIVE_WALLET_REFUND_OUTBOX_ENABLED")" + wallet_refund_outbox_dir="$(read_env_value "${api_env_file}" "GENARRATIVE_WALLET_REFUND_OUTBOX_DIR")" + if [[ "$(printf "%s" "${wallet_refund_enabled}" | tr '[:upper:]' '[:lower:]')" != "false" ]]; then + ensure_runtime_dir "${wallet_refund_outbox_dir}" "0750" + fi } extract_pingora_env_files_from_unit() { diff --git a/scripts/jenkins-server-provision.sh b/scripts/jenkins-server-provision.sh index 454611aa6..fcf78a087 100755 --- a/scripts/jenkins-server-provision.sh +++ b/scripts/jenkins-server-provision.sh @@ -449,6 +449,11 @@ ensure_api_runtime_env_defaults() { ensure_env_value "${API_ENV_FILE}" "GENARRATIVE_TRACKING_OUTBOX_BATCH_SIZE" "500" ensure_env_value "${API_ENV_FILE}" "GENARRATIVE_TRACKING_OUTBOX_FLUSH_INTERVAL_MS" "1000" ensure_env_value "${API_ENV_FILE}" "GENARRATIVE_TRACKING_OUTBOX_MAX_BYTES" "268435456" + ensure_env_value "${API_ENV_FILE}" "GENARRATIVE_WALLET_REFUND_OUTBOX_ENABLED" "true" + ensure_env_value "${API_ENV_FILE}" "GENARRATIVE_WALLET_REFUND_OUTBOX_DIR" "/var/lib/genarrative/wallet-refund-outbox" + ensure_env_value "${API_ENV_FILE}" "GENARRATIVE_WALLET_REFUND_OUTBOX_BATCH_SIZE" "100" + ensure_env_value "${API_ENV_FILE}" "GENARRATIVE_WALLET_REFUND_OUTBOX_FLUSH_INTERVAL_MS" "1000" + ensure_env_value "${API_ENV_FILE}" "GENARRATIVE_WALLET_REFUND_OUTBOX_MAX_BYTES" "67108864" } parse_json_string_field() { @@ -882,7 +887,7 @@ echo "[server-provision] target=${DEPLOY_TARGET}, dry_run=${DRY_RUN}, nginx_conf run_cmd id require_root_for_real_provision install_nginx_brotli_modules -run_cmd mkdir -p "${SPACETIME_ROOT}" "${RELEASE_ROOT}" "$(dirname "${CURRENT_LINK}")" "$(dirname "${WEB_LINK}")" /etc/genarrative /etc/genarrative/pingora /var/lib/genarrative/maintenance /var/lib/genarrative/auth /var/lib/genarrative/tracking-outbox /var/lib/genarrative/database-backups /var/lib/genarrative/health-patrol /var/log/genarrative +run_cmd mkdir -p "${SPACETIME_ROOT}" "${RELEASE_ROOT}" "$(dirname "${CURRENT_LINK}")" "$(dirname "${WEB_LINK}")" /etc/genarrative /etc/genarrative/pingora /var/lib/genarrative/maintenance /var/lib/genarrative/auth /var/lib/genarrative/tracking-outbox /var/lib/genarrative/wallet-refund-outbox /var/lib/genarrative/database-backups /var/lib/genarrative/health-patrol /var/log/genarrative if ! id spacetimedb >/dev/null 2>&1; then run_cmd useradd --system --home-dir "${SPACETIME_ROOT}" --shell /usr/sbin/nologin spacetimedb