From 676c546cbbc1caee300baca382c9267130549a50 Mon Sep 17 00:00:00 2001 From: ThearchyHelios Date: Mon, 19 Oct 2026 16:10:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=8D=E6=A0=B8=20R-d3=EF=BC=88=E5=8D=B8?= =?UTF-8?q?=E8=BD=BD=E6=97=B6=E4=B8=8D=E7=9C=8B=E7=BD=91=E7=BB=9C=E6=98=AF?= =?UTF-8?q?=E4=B8=8D=E6=98=AF=E8=87=AA=E5=B7=B1=E5=BB=BA=E7=9A=84=E5=B0=B1?= =?UTF-8?q?=E5=88=A0=EF=BC=89=EF=BC=9A=E5=BB=BA=E7=BD=91=E7=BB=9C=E6=97=B6?= =?UTF-8?q?=E6=89=93=E4=B8=8A=20agentlab.role=3Dnetwork=20=E5=92=8C?= =?UTF-8?q?=E8=BF=99=E4=B8=AA=E9=83=A8=E7=BD=B2=E7=9A=84=20agentlab.deploy?= =?UTF-8?q?ment=20=E6=A0=87=E7=AD=BE=EF=BC=9B=E5=8D=B8=E8=BD=BD=E6=97=B6?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E5=92=8C=E9=83=A8=E7=BD=B2=E7=BC=96=E5=8F=B7?= =?UTF-8?q?=E5=AF=B9=E5=BE=97=E4=B8=8A=E6=89=8D=E5=88=A0=EF=BC=8C=E6=97=A9?= =?UTF-8?q?=E5=85=88=E5=BB=BA=E7=9A=84=E6=B2=A1=E6=9C=89=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E7=9A=84=E6=8C=89=E6=95=B0=E6=8D=AE=E7=9B=AE=E5=BD=95=E9=87=8C?= =?UTF-8?q?=E8=AE=B0=E7=9D=80=E7=9A=84=E7=BD=91=E7=BB=9C=E5=90=8D=E8=AE=A4?= =?UTF-8?q?=EF=BC=8C=E9=83=BD=E4=B8=8D=E6=98=AF=E5=B0=B1=E5=8F=AA=E6=89=93?= =?UTF-8?q?=E5=8D=B0=E4=B8=80=E5=8F=A5=E3=80=81=E4=B8=8D=E5=88=A0=E3=80=82?= =?UTF-8?q?=E5=81=87=20docker=20=E5=8D=95=E6=B5=8B=EF=BC=9A=E5=88=AB?= =?UTF-8?q?=E4=BA=BA=E7=9A=84=E5=90=8C=E5=90=8D=E7=BD=91=E7=BB=9C=E3=80=81?= =?UTF-8?q?=E6=B2=A1=E6=A0=87=E7=AD=BE=E5=8F=88=E6=B2=A1=E8=AE=B0=E7=9D=80?= =?UTF-8?q?=E7=9A=84=E4=B8=8D=E5=88=A0=EF=BC=8C=E8=87=AA=E5=B7=B1=E7=9A=84?= =?UTF-8?q?=EF=BC=88=E5=90=AB=E6=97=A9=E5=85=88=E6=B2=A1=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E7=9A=84=EF=BC=89=E5=88=A0=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/tests/test_deploy_script.py | 29 +++++++++++++++++++++++++++++ deploy/deploy.sh | 22 +++++++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/backend/tests/test_deploy_script.py b/backend/tests/test_deploy_script.py index a179f475..77dcc803 100644 --- a/backend/tests/test_deploy_script.py +++ b/backend/tests/test_deploy_script.py @@ -701,6 +701,35 @@ def test_an_unlabelled_container_is_recognised_by_its_password_mount(tmp_path): assert PG in a.containers() and "没有删它" in out.stderr +def test_uninstall_removes_only_its_own_network(tmp_path): + """复核 R-d3:网络带着部署编号的标签,卸载时只删自己建的;早先建的没标签,按数据目录里记着的网络名认。""" + a = Deploy(tmp_path / "a") + a("install", "--postgres") + dep = a.state_values()["id"] + assert a.state()["networks"][NET] == {"agentlab.role": "network", "agentlab.deployment": dep} + # 别人建的、名字正好一样的网络(没有这个部署的标签):不删 + state = a.state() + state["networks"][NET] = {"agentlab.role": "network", "agentlab.deployment": "someone-else"} + a.state_file.write_text(json.dumps(state)) + out = a("uninstall") + assert NET in a.state()["networks"] and "不是这个部署建的" in out.stdout + # 早先建的、没标签的:数据目录里记着这个名字就是自己的 + state = a.state() + state["networks"][NET] = {} + a.state_file.write_text(json.dumps(state)) + a("install") + a("uninstall") + assert NET not in a.state()["networks"] + # 没标签、数据目录里也没记着的(比如这是个 SQLite 部署,同名网络是别人的):不删 + b = Deploy(tmp_path / "b", name="agl-b", share=a) + b("install") + state = b.state() + state["networks"]["agl-b-net"] = {} + b.state_file.write_text(json.dumps(state)) + b("uninstall") + assert "agl-b-net" in b.state()["networks"] + + def test_upgrade_with_a_new_image_does_not_recreate_another_deployments_container(tmp_path): a = Deploy(tmp_path / "a") a("install", "--postgres") diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 41d4497d..dd0cd98a 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -766,7 +766,19 @@ ensure_pg_image() { ensure_network() { docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1 && return 0 say "创建 docker 网络 ${DOCKER_NETWORK}(PostgreSQL 只在这个网络里可见,端口不对外)" - docker network create "$DOCKER_NETWORK" >/dev/null + docker network create --label agentlab.role=network --label "agentlab.deployment=$DEPLOY_ID" "$DOCKER_NETWORK" >/dev/null +} + +# 网络是不是这个部署建的:标签和部署编号对得上;早先建的没有标签,按数据目录里记着的网络名认 +network_is_ours() { + local role dep + role="$(docker network inspect -f '{{index .Labels "agentlab.role"}}' "$DOCKER_NETWORK" 2>/dev/null || true)" + dep="$(docker network inspect -f '{{index .Labels "agentlab.deployment"}}' "$DOCKER_NETWORK" 2>/dev/null || true)" + if [ -n "$role$dep" ]; then + [ "$role" = network ] && [ -n "$DEPLOY_ID" ] && [ "$dep" = "$DEPLOY_ID" ] + else + [ -n "$DATA_ABS" ] && [ "$(state_value network)" = "$DOCKER_NETWORK" ] + fi } pg_secrets() { @@ -1271,8 +1283,12 @@ cmd_uninstall() { fi fi if docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1; then - docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 && say "删除 docker 网络 $DOCKER_NETWORK" \ - || warn "docker 网络 $DOCKER_NETWORK 没删掉(可能还有别的容器连着)" + if network_is_ours; then + docker network rm "$DOCKER_NETWORK" >/dev/null 2>&1 && say "删除 docker 网络 $DOCKER_NETWORK" \ + || warn "docker 网络 $DOCKER_NETWORK 没删掉(可能还有别的容器连着)" + else + echo "docker 网络 $DOCKER_NETWORK 不是这个部署建的(没有这个部署的标签,数据目录里也没记着它),没有删" + fi fi if [ -n "$PURGE_IMAGE" ]; then if image_present; then