71 lines
2.2 KiB
Python
71 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import logging
|
|
|
|
from .compose_manager import ComposeManager
|
|
from .models import CommandResult
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class RegistryLoginManager:
|
|
def __init__(
|
|
self,
|
|
*,
|
|
enabled: bool,
|
|
server: str,
|
|
username: str,
|
|
password: str,
|
|
timeout_seconds: int,
|
|
compose_manager: ComposeManager,
|
|
) -> None:
|
|
self.enabled = enabled
|
|
self.server = server
|
|
self.username = username
|
|
self.password = password
|
|
self.timeout_seconds = timeout_seconds
|
|
self.compose_manager = compose_manager
|
|
|
|
async def login_if_needed(self) -> CommandResult:
|
|
if not self.enabled:
|
|
return CommandResult(success=True, stdout="registry login skipped", returncode=0)
|
|
|
|
command = [
|
|
"docker",
|
|
"login",
|
|
self.server,
|
|
"-u",
|
|
self.username,
|
|
"-p",
|
|
self.password,
|
|
]
|
|
logger.info("开始执行私有仓库登录: %s", self.server)
|
|
result = await self._run_command(command)
|
|
if result.success:
|
|
logger.info("私有仓库登录成功: %s", self.server)
|
|
else:
|
|
logger.error("私有仓库登录失败: %s", result.stderr or result.stdout)
|
|
return result
|
|
|
|
async def _run_command(self, command: list[str]) -> CommandResult:
|
|
process = await asyncio.create_subprocess_exec(
|
|
*command,
|
|
cwd=str(self.compose_manager.working_dir),
|
|
stdout=asyncio.subprocess.PIPE,
|
|
stderr=asyncio.subprocess.PIPE,
|
|
)
|
|
try:
|
|
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=self.timeout_seconds)
|
|
except asyncio.TimeoutError:
|
|
process.kill()
|
|
await process.wait()
|
|
return CommandResult(success=False, stderr=f"registry login timeout after {self.timeout_seconds}s", returncode=-1)
|
|
|
|
return CommandResult(
|
|
success=process.returncode == 0,
|
|
stdout=stdout.decode("utf-8", errors="ignore"),
|
|
stderr=stderr.decode("utf-8", errors="ignore"),
|
|
returncode=process.returncode or 0,
|
|
)
|