kiwi-scp/kiwi_scp/service.py

62 lines
1.8 KiB
Python
Raw Normal View History

2021-12-02 17:58:08 +00:00
import logging
2021-12-02 16:08:14 +00:00
import re
import subprocess
2021-12-02 17:58:08 +00:00
from itertools import zip_longest
2021-12-02 16:08:14 +00:00
from pathlib import Path
2021-12-02 17:58:08 +00:00
from typing import TYPE_CHECKING, Generator, Sequence
2021-12-02 16:08:14 +00:00
import attr
from ruamel.yaml import CommentedMap
from .executable import COMPOSE_EXE
2021-12-02 16:12:30 +00:00
if TYPE_CHECKING:
from .project import Project
2021-12-02 16:08:14 +00:00
2021-12-02 17:58:08 +00:00
_logger = logging.getLogger(__name__)
2021-12-02 16:08:14 +00:00
@attr.s
class Service:
name: str = attr.ib()
content: CommentedMap = attr.ib()
2022-01-27 14:26:10 +00:00
parent_project: "Project" = attr.ib()
2021-12-02 16:08:14 +00:00
2022-02-22 13:45:24 +00:00
_RE_KIWI_CONFIG = re.compile(r"^\s*\$(?:KIWI_CONFIG|{KIWI_CONFIG})/+(.*)$", flags=re.UNICODE)
2021-12-02 16:08:14 +00:00
@property
def configs(self) -> Generator[Path, None, None]:
if "volumes" not in self.content:
return
for volume in self.content["volumes"]:
host_part = volume.split(":")[0]
2022-02-22 13:45:24 +00:00
cd_match = Service._RE_KIWI_CONFIG.match(host_part)
2021-12-02 16:08:14 +00:00
if cd_match:
yield Path(cd_match.group(1))
def has_executable(self, exe_name: str) -> bool:
try:
# test if desired executable exists
COMPOSE_EXE.run(
["exec", "-T", self.name, "/bin/sh", "-c", f"command -v {exe_name}"],
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
2022-01-27 14:26:10 +00:00
**self.parent_project.process_kwargs,
2021-12-02 16:08:14 +00:00
)
return True
except subprocess.CalledProcessError:
2021-12-02 16:12:30 +00:00
return False
2021-12-02 17:58:08 +00:00
def existing_executables(self, exe_names: Sequence[str]) -> Generator[str, None, None]:
for cur, nxt in zip_longest(exe_names, exe_names[1:]):
if self.has_executable(cur):
# found working shell
_logger.debug(f"Found executable '{cur}'")
yield cur
elif nxt is not None:
# try next in list
_logger.info(f"Executable '{cur}' not found in container, trying '{nxt}'")