| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import subprocess
- from pathlib import Path
- class Podman:
- @classmethod
- def run(
- cls,
- image: str,
- name: str,
- *,
- hostname: str,
- env: list,
- volumes: list[str],
- # TODO: Actually a list of Secret but creates a circular dependency
- secrets: list,
- ssh_auth_sock: Path | None = None,
- detach=True,
- ):
- args = ["run"]
- args += ["-h", hostname]
- args += ["--name", name]
- for e in env:
- args += ["-e", e]
- if ssh_auth_sock:
- args += ["-e", "SSH_AUTH_SOCK"]
- volumes += [f"{ssh_auth_sock}:{ssh_auth_sock}:Z"]
- args += ["--security-opt=label=disable"]
- if detach:
- args += ["--detach"]
- args += [a for vol in volumes for a in ["-v", vol]]
- args += [a for s in secrets for a in ["--secret", f"{s.name},mode=0{s.mode:o}"]]
- args += [image]
- cls._check_output(args)
- @classmethod
- def rm(cls, name, *, force=True):
- args = ["rm"]
- if force:
- args += ["-f"]
- args += [name]
- cls._check_output(args)
- @classmethod
- def exec(cls, name, /, *cmd, interactive):
- args = ["exec"]
- common_suffix = [name] + list(cmd)
- if interactive:
- args += ["-ti"] + common_suffix
- cls._run(args)
- else:
- args += common_suffix
- cls._check_output(args)
- @classmethod
- def secret_create(
- cls,
- name: str,
- *,
- replace=True,
- value: bytes | None = None,
- host_path: Path | None = None,
- ):
- if value and host_path:
- raise ValueError("both value and host_path can not be set")
- args = ["secret", "create"]
- kwargs = {}
- if replace:
- args += ["--replace"]
- args += [name]
- if value is not None:
- args += ["-"]
- kwargs["input"] = value
- elif host_path is not None:
- args += [host_path]
- cls._check_output(args, **kwargs)
- @classmethod
- def machine_is_running(cls) -> bool:
- try:
- subprocess.run(["podman", "ps"], capture_output=True, check=True)
- except subprocess.CalledProcessError as e:
- if "Cannot connect to Podman" in e.stderr.decode():
- return False
- return True
- @classmethod
- def machine_start(cls):
- cls._check_output(["machine", "start"])
- @classmethod
- def _run(cls, args: list, **kwargs):
- args = ["podman"] + args
- print(f"Executing `{" ".join(args)}`")
- return subprocess.run(args, **kwargs)
- @classmethod
- def _check_output(cls, args: list, **kwargs):
- args = ["podman"] + args
- print(f"Executing `{" ".join(args)}`")
- def run_and_output():
- out = subprocess.check_output(args, **kwargs)
- print(out.decode())
- try:
- run_and_output()
- except subprocess.CalledProcessError as e:
- if not cls.machine_is_running():
- print("podman not running, starting it")
- cls.machine_start()
- run_and_output()
- else:
- raise e
|