github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/test/python/docker/__init__.py (about)

     1  import configparser
     2  import json
     3  import os
     4  import pathlib
     5  import shutil
     6  import subprocess
     7  import tempfile
     8  
     9  from docker import DockerClient
    10  
    11  from test.python.docker import constant
    12  
    13  
    14  class Podman(object):
    15      """
    16      Instances hold the configuration and setup for running podman commands
    17      """
    18  
    19      def __init__(self):
    20          """Initialize a Podman instance with global options"""
    21          binary = os.getenv("PODMAN", "bin/podman")
    22          self.cmd = [binary, "--storage-driver=vfs"]
    23  
    24          cgroupfs = os.getenv("CGROUP_MANAGER", "systemd")
    25          self.cmd.append(f"--cgroup-manager={cgroupfs}")
    26  
    27          # No support for tmpfs (/tmp) or extfs (/var/tmp)
    28          # self.cmd.append("--storage-driver=overlay")
    29  
    30          if os.getenv("DEBUG"):
    31              self.cmd.append("--log-level=debug")
    32              self.cmd.append("--syslog=true")
    33  
    34          self.anchor_directory = tempfile.mkdtemp(prefix="podman_docker_")
    35  
    36          self.image_cache = os.path.join(self.anchor_directory, "cache")
    37          os.makedirs(self.image_cache, exist_ok=True)
    38  
    39          self.cmd.append("--root=" + os.path.join(self.anchor_directory, "crio"))
    40          self.cmd.append("--runroot=" + os.path.join(self.anchor_directory, "crio-run"))
    41  
    42          os.environ["REGISTRIES_CONFIG_PATH"] = os.path.join(self.anchor_directory, "registry.conf")
    43          p = configparser.ConfigParser()
    44          p.read_dict(
    45              {
    46                  "registries.search": {"registries": "['quay.io', 'docker.io']"},
    47                  "registries.insecure": {"registries": "[]"},
    48                  "registries.block": {"registries": "[]"},
    49              }
    50          )
    51          with open(os.environ["REGISTRIES_CONFIG_PATH"], "w") as w:
    52              p.write(w)
    53  
    54          os.environ["CNI_CONFIG_PATH"] = os.path.join(self.anchor_directory, "cni", "net.d")
    55          os.makedirs(os.environ["CNI_CONFIG_PATH"], exist_ok=True)
    56          self.cmd.append("--cni-config-dir=" + os.environ["CNI_CONFIG_PATH"])
    57          cni_cfg = os.path.join(os.environ["CNI_CONFIG_PATH"], "87-podman-bridge.conflist")
    58          # json decoded and encoded to ensure legal json
    59          buf = json.loads(
    60              """
    61              {
    62                "cniVersion": "0.3.0",
    63                "name": "default",
    64                "plugins": [{
    65                    "type": "bridge",
    66                    "bridge": "cni0",
    67                    "isGateway": true,
    68                    "ipMasq": true,
    69                    "ipam": {
    70                      "type": "host-local",
    71                      "subnet": "10.88.0.0/16",
    72                      "routes": [{
    73                        "dst": "0.0.0.0/0"
    74                      }]
    75                    }
    76                  },
    77                  {
    78                    "type": "portmap",
    79                    "capabilities": {
    80                      "portMappings": true
    81                    }
    82                  }
    83                ]
    84              }
    85              """
    86          )
    87          with open(cni_cfg, "w") as w:
    88              json.dump(buf, w)
    89  
    90      def open(self, command, *args, **kwargs):
    91          """Podman initialized instance to run a given command
    92  
    93          :param self: Podman instance
    94          :param command: podman sub-command to run
    95          :param args: arguments and options for command
    96          :param kwargs: See subprocess.Popen() for shell keyword
    97          :return: subprocess.Popen() instance configured to run podman instance
    98          """
    99          cmd = self.cmd.copy()
   100          cmd.append(command)
   101          cmd.extend(args)
   102  
   103          shell = kwargs.get("shell", False)
   104  
   105          return subprocess.Popen(
   106              cmd,
   107              shell=shell,
   108              stdin=subprocess.DEVNULL,
   109              stdout=subprocess.DEVNULL,
   110              stderr=subprocess.DEVNULL,
   111          )
   112  
   113      def run(self, command, *args, **kwargs):
   114          """Podman initialized instance to run a given command
   115  
   116          :param self: Podman instance
   117          :param command: podman sub-command to run
   118          :param args: arguments and options for command
   119          :param kwargs: See subprocess.Popen() for shell and check keywords
   120          :return: subprocess.Popen() instance configured to run podman instance
   121          """
   122          cmd = self.cmd.copy()
   123          cmd.append(command)
   124          cmd.extend(args)
   125  
   126          check = kwargs.get("check", False)
   127          shell = kwargs.get("shell", False)
   128  
   129          return subprocess.run(
   130              cmd,
   131              shell=shell,
   132              check=check,
   133              stdout=subprocess.PIPE,
   134              stderr=subprocess.PIPE,
   135          )
   136  
   137      def tear_down(self):
   138          shutil.rmtree(self.anchor_directory, ignore_errors=True)
   139  
   140      def restore_image_from_cache(self, client: DockerClient):
   141          path = os.path.join(self.image_cache, constant.ALPINE_TARBALL)
   142          if not os.path.exists(path):
   143              img = client.images.pull(constant.ALPINE)
   144              with open(path, mode="wb") as tarball:
   145                  for frame in img.save(named=True):
   146                      tarball.write(frame)
   147          else:
   148              self.run("load", "-i", path, check=True)
   149  
   150      def flush_image_cache(self):
   151          for f in pathlib.Path(self.image_cache).glob("*.tar"):
   152              f.unlink(f)