Skip to content

Commit b60944d

Browse files
committed
refactor(podman_context): 重构容器启动逻辑,拆分内部辅助函数
将原run方法拆分为_create_client、_build_mounts、_cleanup_old_container、_build_run_params和_try_start_container等内部辅助函数, 优化代码结构并新增pasta错误自动重试host网络的逻辑,提升代码可读性和容错性。
1 parent db9b483 commit b60944d

1 file changed

Lines changed: 47 additions & 25 deletions

File tree

apps/chaos/src/taolib/flowkit/podman_context.py

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,9 @@ def _start(self) -> None:
310310
Raises:
311311
ContainerRunError: 容器启动失败。
312312
"""
313-
try:
314-
# ── 1. 创建 Podman 客户端 ──
313+
def _create_client() -> None:
314+
"""创建 Podman 客户端的内部辅助函数。"""
315315
if self.host_path is not None:
316-
# 有宿主机路径:走跨平台路径转换流程
317-
# Windows 下 PodmanSSHClient 返回的是包装对象,需调用 .client()
318-
# Linux/macOS 下 _get_podman_context 直接返回 PodmanClient
319316
self._pctx = _get_podman_context(
320317
self.host_path, **self.client_kwargs
321318
)
@@ -325,14 +322,12 @@ def _start(self) -> None:
325322
else self._pctx.ctx
326323
)
327324
else:
328-
# 无宿主机路径:直接创建 PodmanClient,不做路径转换
329325
from podman import PodmanClient
330-
331326
self._client = PodmanClient(**self.client_kwargs)
332327

333-
# ── 2. 构建挂载列表 ──
328+
def _build_mounts() -> list[dict[str, Any]]:
329+
"""构建挂载列表的内部辅助函数。"""
334330
mounts: list[dict[str, Any]] = []
335-
# bind 挂载:将宿主机目录映射到容器内
336331
if self.host_path is not None and self.target is not None:
337332
mounts.append(
338333
{
@@ -341,36 +336,30 @@ def _start(self) -> None:
341336
"target": self.target,
342337
},
343338
)
344-
# 命名卷挂载:Podman 管理的持久化存储卷
345339
for vol_src, vol_target in self.volumes.items():
346340
mounts.append(
347341
{"type": "volume", "source": vol_src, "target": vol_target}
348342
)
343+
return mounts
349344

350-
# ── 3. 清理同名旧容器 ──
351-
# 仅在显式指定容器名时才清理,避免误删自动命名的容器
345+
def _cleanup_old_container() -> None:
346+
"""清理同名旧容器的内部辅助函数。"""
352347
if self.name is not None:
353348
try:
354349
old = self._client.containers.get(self.name)
355350
old.remove(force=True)
356351
except Exception:
357352
pass
358353

359-
# ── 4. 仅建连接模式 ──
360-
# start_container=False 时跳过容器创建,仅管理客户端生命周期
361-
if not self.start_container:
362-
return
363-
364-
# ── 5. 构建容器运行参数并启动 ──
365-
# 固定参数:所有容器都必须的配置
354+
def _build_run_params(mounts: list[dict[str, Any]]) -> dict[str, Any]:
355+
"""构建容器运行参数的内部辅助函数。"""
366356
run_params: dict[str, Any] = {
367357
"image": self.image,
368358
"command": self.command or ["sleep", "infinity"],
369359
"tty": True,
370360
"stdin_open": True,
371361
"detach": True,
372362
}
373-
# 条件参数:仅在显式设置时才传入,避免覆盖 SDK 默认行为
374363
if self.name is not None:
375364
run_params["name"] = self.name
376365
if mounts:
@@ -379,13 +368,46 @@ def _start(self) -> None:
379368
run_params["working_dir"] = self.working_dir
380369
if self.network_mode is not None:
381370
run_params["network_mode"] = self.network_mode
382-
# 用户自定义参数最后合并,允许覆盖以上所有参数
383371
run_params.update(self.run_kwargs)
372+
return run_params
373+
374+
def _try_start_container(use_host_network: bool = False) -> bool:
375+
"""尝试启动容器,返回是否成功。
384376
385-
self._container = self._client.containers.run(**run_params)
386-
except Exception as exc:
387-
self._cleanup()
388-
raise ContainerRunError(f"容器启动失败: {exc}") from exc
377+
Args:
378+
use_host_network: 是否使用 host 网络模式(用于 pasta 错误时重试)
379+
380+
Returns:
381+
True 表示启动成功,False 表示遇到 pasta 相关错误需要重试
382+
"""
383+
try:
384+
_create_client()
385+
mounts = _build_mounts()
386+
_cleanup_old_container()
387+
388+
if not self.start_container:
389+
return True
390+
391+
run_params = _build_run_params(mounts)
392+
393+
if use_host_network and "network_mode" not in run_params:
394+
run_params["network_mode"] = "host"
395+
396+
self._container = self._client.containers.run(**run_params)
397+
return True
398+
except Exception as exc:
399+
self._cleanup()
400+
exc_str = str(exc)
401+
if "pasta" in exc_str.lower() and not use_host_network:
402+
return False
403+
raise ContainerRunError(f"容器启动失败: {exc}") from exc
404+
405+
# 首次尝试启动
406+
if _try_start_container():
407+
return
408+
409+
# 遇到 pasta 错误,重试使用 host 网络模式
410+
_try_start_container(use_host_network=True)
389411

390412
def _cleanup(self) -> None:
391413
"""清理资源:容器 → 客户端 → SSH 隧道。

0 commit comments

Comments
 (0)