693cd952cd
仓库首次入库(此前仅存在于本地工作区与测试服构建产物中,未上传)。 改动(src/knowledge_adapter/asset_content_processor.py): - 新增 _TRUNCATED_TRAILING_MARKDOWN_RESOURCE_IMAGE 规则,清除 chunk 末尾被截断的  - 回归测试 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 比对,为唯一变更文件
119 lines
3.9 KiB
Bash
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'
|