Source code for projspec.artifact.container

from projspec.proj.base import Project, ProjectExtra
from projspec.artifact import BaseArtifact
from projspec.utils import run_subprocess


[docs] class DockerImage(BaseArtifact): """Filesystem snapshot as created by bocker-build, which can be instantiated into a container.""" icon = "🐳" def __init__(self, proj: Project, cmd=None, tag=None): if tag: cmd = ["docker", "build", ".", "-t", tag] else: cmd = ["docker", "build", "."] self.tag = tag super().__init__(proj, cmd=cmd)
[docs] class DockerRuntime(DockerImage): """Running container in Docker, tied to a certain image and command.""" icon = "▶️" # Note: there are many optional arguments to docker; we could surface the most common # ones (-it, -d, -p). This does the simplest thing. def _make(self, *args, **kwargs) -> None: """ :param args: added to the docker run command :param kwargs: affect the docker run subprocess call """ out = run_subprocess(self.cmd, cwd=self.proj.url, **kwargs).stdout if self.tag: run_subprocess(["docker", "run", self.tag], cwd=self.proj.url, output=False) else: lines = [ l for l in out.splitlines() if l.startswith(b"Successfully built ") ] img = lines[-1].split()[-1] run_subprocess( ["docker", "run", img.decode()] + list(args), cwd=self.proj.url, output=False, **kwargs, )
[docs] class Docker(ProjectExtra): """A Dockerfile in a project directory, which defines how to build an image.""" icon = "🐳" def match(self): return "Dockerfile" in self.proj.basenames def parse(self) -> None: self._artifacts["docker_image"] = DockerImage(self.proj) self._artifacts["docker_runtime"] = DockerRuntime(self.proj)