Files
knowledge-adapter-service/deploy/nginx/rollout_test_nginx_adapter.sh
T
姚章浩 693cd952cd feat(asset): 清理被截断的结尾图片引用,修复整单 502
仓库首次入库(此前仅存在于本地工作区与测试服构建产物中,未上传)。

改动(src/knowledge_adapter/asset_content_processor.py):
- 新增 _TRUNCATED_TRAILING_MARKDOWN_RESOURCE_IMAGE 规则,清除 chunk 末尾被截断的
  ![](resource://xxxx 残片(WeKnora 分块在图片引用中间截断时产生,旧逻辑无法匹配完整引用,
  残留 resource:// 触发 ContentProcessingError,导致整单 502)
- 回归测试 tests/test_asset_content_processor.py::
  test_truncated_trailing_markdown_resource_image_is_removed

验证证据:
- 测试服 120.76.217.51,镜像 knowledge-adapter-service:reviewed-test-aeab4b5fca2d
  (release aeab4b5fca2d8661):KB d015d05c-25c8-4d63-b2ab-e8590d3c2dfb 5 个查询全部
  http=200、records=5、残留 resource:// = 0;KB b9dacd62 无退化;容器日志无 error/exception
- 本地:pytest 141 项全通过、ruff 全通过
- 该文件与 258c31e0fe07fd08 源码的差异经逐文件 md5 比对,为唯一变更文件
2026-09-16 10:01:27 +08:00

119 lines
3.9 KiB
Bash

#!/usr/bin/env bash
set -Eeuo pipefail
COMPOSE_FILE=/opt/knowledge-adapter/releases/a842917c69f9ae09/knowledge-adapter-service/deploy/docker-compose.adapter.yml
ENV_FILE=/opt/knowledge-adapter/adapter.env
PROJECT=knowledge-adapter
SERVICE=adapter
NGINX_SOURCE=/tmp/weknora-test-origin.conf
HELPER_SOURCE=/tmp/nginx_adapter_helper.py
APT_SOURCE=/tmp/ubuntu-public-temporary.list
NGINX_AVAILABLE=/etc/nginx/sites-available/weknora-test-origin.conf
NGINX_ENABLED=/etc/nginx/sites-enabled/weknora-test-origin.conf
BACKUP_DIR=/opt/knowledge-adapter/backups/nginx-adapter-$(date -u +%Y%m%dT%H%M%SZ)
POLICY_CREATED=0
ENV_BACKED_UP=0
ENV_CHANGED=0
ADAPTER_RECREATED=0
cleanup_policy() {
if [[ "$POLICY_CREATED" == 1 ]]; then
rm -f /usr/sbin/policy-rc.d
fi
}
rollback_on_error() {
rc=$?
trap - ERR
cleanup_policy
printf 'rollout_error=stage_failed rc=%s\n' "$rc" >&2
if [[ "$ENV_CHANGED" == 1 && "$ENV_BACKED_UP" == 1 ]]; then
install -o root -g root -m 0600 "$BACKUP_DIR/adapter.env" "$ENV_FILE"
if [[ "$ADAPTER_RECREATED" == 1 ]]; then
docker compose -p "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" \
up -d --no-deps --force-recreate --no-build "$SERVICE" || true
fi
printf 'adapter_env_rollback=attempted\n' >&2
fi
exit "$rc"
}
trap rollback_on_error ERR
trap cleanup_policy EXIT
[[ $(id -u) == 0 ]]
[[ -f "$COMPOSE_FILE" ]]
[[ -f "$ENV_FILE" ]]
[[ -f "$NGINX_SOURCE" ]]
[[ -f "$HELPER_SOURCE" ]]
[[ -f "$APT_SOURCE" ]]
[[ $(stat -c '%a' "$ENV_FILE") == 600 ]]
printf '[1/7] baseline and protected backup\n'
mkdir -p -m 0700 "$BACKUP_DIR"
install -o root -g root -m 0600 "$ENV_FILE" "$BACKUP_DIR/adapter.env"
ENV_BACKED_UP=1
docker inspect -f '{{.Image}}' knowledge-adapter-adapter-1 > "$BACKUP_DIR/adapter-image-id.txt"
chmod 0600 "$BACKUP_DIR/adapter-image-id.txt"
printf 'backup_dir=%s\n' "$BACKUP_DIR"
printf '[2/7] install nginx without starting default site\n'
if ! command -v nginx >/dev/null 2>&1; then
if [[ ! -e /usr/sbin/policy-rc.d ]]; then
printf '#!/bin/sh\nexit 101\n' > /usr/sbin/policy-rc.d
chmod 0755 /usr/sbin/policy-rc.d
POLICY_CREATED=1
fi
export DEBIAN_FRONTEND=noninteractive
apt-get \
-o Dir::Etc::sourcelist="$APT_SOURCE" \
-o Dir::Etc::sourceparts="-" \
-o APT::Get::List-Cleanup="0" \
update
apt-get \
-o Dir::Etc::sourcelist="$APT_SOURCE" \
-o Dir::Etc::sourceparts="-" \
install -y nginx
cleanup_policy
POLICY_CREATED=0
fi
nginx -v
printf '[3/7] install test-only Host routing and validate syntax\n'
install -o root -g root -m 0644 "$NGINX_SOURCE" "$NGINX_AVAILABLE"
ln -sfn "$NGINX_AVAILABLE" "$NGINX_ENABLED"
rm -f /etc/nginx/sites-enabled/default
nginx -t
printf '[4/7] atomically update Adapter public base and render Compose\n'
python3 "$HELPER_SOURCE" update-env
ENV_CHANGED=1
docker compose -p "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" config --quiet
printf '[5/7] recreate Adapter only, using existing image\n'
docker compose -p "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" \
up -d --no-deps --force-recreate --no-build "$SERVICE"
ADAPTER_RECREATED=1
for attempt in $(seq 1 30); do
state=$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' knowledge-adapter-adapter-1)
if [[ "$state" == healthy ]]; then
break
fi
if [[ "$state" == unhealthy || "$attempt" == 30 ]]; then
printf 'adapter_health=%s attempt=%s\n' "$state" "$attempt" >&2
false
fi
sleep 2
done
printf 'adapter_health=healthy\n'
printf '[6/7] enable origin Nginx\n'
systemctl enable --now nginx
systemctl is-active --quiet nginx
nginx -t
printf 'nginx=active\n'
printf '[7/7] real Host-route and retrieval acceptance\n'
python3 "$HELPER_SOURCE" accept
ss -ltn '( sport = :80 or sport = :18080 )'
printf 'rollout=success\n'