mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 22:31:59 +00:00
复核 R-d2(起不来的库容器回退后还在一遍遍重启):stop_pg 对在跑的和在重启的(restarting)都停;migrate-to-postgres 回退时先 docker update --restart=no 再停,再起库时(start_pg)恢复 --restart unless-stopped;./deploy.sh stop 用同一个函数一起好。假 docker 单测:镜像起不来、容器一直 restarting 时回退后停在 exited、重启策略是 no,换回能起的镜像重跑照常,stop 也停得下在重启的
This commit is contained in:
@@ -11,6 +11,7 @@ FAKE_COPY_FAIL 成功或失败。
|
||||
FAKE_PSQL_FAIL=1 docker exec … psql 失败
|
||||
FAKE_UNHEALTHY_ENV=<变量名> 带这个环境变量(-e)起的容器健康检查不过
|
||||
FAKE_UNHEALTHY_IMAGE=<镜像> 用这个镜像起的容器健康检查不过
|
||||
FAKE_RESTARTING_IMAGE=<镜像> 用这个镜像起的容器一直在重启(restarting)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -272,14 +273,29 @@ def main(argv: list[str]) -> int:
|
||||
fail(f'docker: Error response from daemon: Conflict. The container name "/{name}" is already in use.', 125)
|
||||
for vol in opts["volumes"]:
|
||||
state["volumes"].setdefault(vol, {})
|
||||
flapping = os.environ.get("FAKE_RESTARTING_IMAGE") == image
|
||||
state["containers"][name] = {
|
||||
"image": image, "state": "running", "env": opts["env"], "labels": opts["labels"],
|
||||
"mounts": opts["mounts"], "ports": opts["ports"], "network": network or "bridge",
|
||||
"image": image, "state": "restarting" if flapping else "running", "env": opts["env"],
|
||||
"labels": opts["labels"], "mounts": opts["mounts"], "ports": opts["ports"], "network": network or "bridge",
|
||||
"restart": opts.get("--restart", "no"),
|
||||
}
|
||||
save(state)
|
||||
print("f" * 64)
|
||||
return 0
|
||||
|
||||
if cmd == "update":
|
||||
name = args[-1]
|
||||
c = state["containers"].get(name)
|
||||
if c is None:
|
||||
fail(f"Error response from daemon: No such container: {name}")
|
||||
for i, a in enumerate(args[:-1]):
|
||||
if a.startswith("--restart="):
|
||||
c["restart"] = a.split("=", 1)[1]
|
||||
elif a == "--restart":
|
||||
c["restart"] = args[i + 1]
|
||||
save(state)
|
||||
return 0
|
||||
|
||||
if cmd in ("start", "stop", "restart"):
|
||||
names = [a for a in args if not a.startswith("-") and not a.isdigit()]
|
||||
for name in names:
|
||||
|
||||
@@ -560,6 +560,30 @@ def test_a_failed_copy_leaves_the_sqlite_service_as_it_was_and_rerunning_works(d
|
||||
assert deploy.mode() == "builtin"
|
||||
|
||||
|
||||
def test_a_database_that_keeps_restarting_is_stopped_and_left_without_a_restart_policy(deploy):
|
||||
"""复核 R-d2:库的镜像起不来、容器一遍遍重启(restarting)时,回退要真停下它、关掉重启策略;再起时恢复。"""
|
||||
_sqlite_deployment(deploy)
|
||||
(deploy.pkg / "postgres-image.tar").write_text(f"alpine:latest \n{PG_IMAGE} \n")
|
||||
out = deploy("migrate-to-postgres", ok=False, DEPLOY_POSTGRES_IMAGE="alpine:latest", FAKE_RESTARTING_IMAGE="alpine:latest")
|
||||
assert "没有切换,仍用 SQLite" in out.stderr
|
||||
pg = deploy.containers()[PG]
|
||||
assert pg["state"] == "exited" and pg["restart"] == "no", "停下了、不会再被拉起来"
|
||||
calls = deploy.calls()
|
||||
assert index_of(calls, lambda a: a == ["update", "--restart=no", PG]) < index_of(calls, is_cmd("stop", PG))
|
||||
# 换回能起的镜像重跑:库的容器按新镜像重建,重启策略照常
|
||||
deploy("migrate-to-postgres")
|
||||
assert deploy.containers()[PG]["restart"] == "unless-stopped" and deploy.mode() == "builtin"
|
||||
# ./deploy.sh stop 同一个函数:在重启的也停
|
||||
state = deploy.state()
|
||||
state["containers"][PG]["state"] = "restarting"
|
||||
deploy.state_file.write_text(json.dumps(state))
|
||||
deploy("stop")
|
||||
assert deploy.containers()[PG]["state"] == "exited"
|
||||
deploy("start")
|
||||
calls = deploy.calls()
|
||||
assert index_of(calls, lambda a: a == ["update", "--restart", "unless-stopped", PG]) < index_of(calls, is_cmd("start", PG))
|
||||
|
||||
|
||||
def test_a_stopped_service_stays_stopped_after_a_failed_migration(deploy):
|
||||
_sqlite_deployment(deploy)
|
||||
deploy("stop")
|
||||
|
||||
+10
-2
@@ -873,6 +873,8 @@ start_pg() {
|
||||
fi
|
||||
if [ "$(container_state "$POSTGRES_CONTAINER")" != running ]; then
|
||||
say "启动内置 PostgreSQL(${POSTGRES_CONTAINER})"
|
||||
# 回退时关掉过重启策略(stop_pg --no-restart),起的时候恢复
|
||||
docker update --restart unless-stopped "$POSTGRES_CONTAINER" >/dev/null 2>&1 || true
|
||||
docker start "$POSTGRES_CONTAINER" >/dev/null || die "内置 PostgreSQL 的容器起不来,见上面 docker 的报错"
|
||||
fi
|
||||
else
|
||||
@@ -885,9 +887,15 @@ start_pg() {
|
||||
fi
|
||||
}
|
||||
|
||||
# 在跑的、在反复重启的(镜像起不来、--restart unless-stopped 一遍遍拉)都停。--no-restart:再关掉重启策略(回退时用:
|
||||
# 一个起不来的库容器不该在后台一直重启),下次 start_pg 起它时恢复
|
||||
stop_pg() {
|
||||
container_exists "$POSTGRES_CONTAINER" || return 0
|
||||
[ "$(container_state "$POSTGRES_CONTAINER")" = running ] || return 0
|
||||
[ "${1:-}" != --no-restart ] || docker update --restart=no "$POSTGRES_CONTAINER" >/dev/null 2>&1 || true
|
||||
case "$(container_state "$POSTGRES_CONTAINER")" in
|
||||
running|restarting) ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
say "停止内置 PostgreSQL(${POSTGRES_CONTAINER},数据保留)"
|
||||
docker stop "$POSTGRES_CONTAINER" >/dev/null
|
||||
}
|
||||
@@ -1040,7 +1048,7 @@ migrate_rollback() {
|
||||
docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
stop_pg
|
||||
stop_pg --no-restart
|
||||
die "没有切换,仍用 SQLite(数据目录里的 agentlab.db 没动过)。照上面的报错处理好之后重新运行 ./deploy.sh migrate-to-postgres,
|
||||
重复执行是安全的:内置库里这次导了一半的会先清空再导"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user