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)