github.com/AbhinandanKurakure/podman/v3@v3.4.10/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 .compat 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("PODMAN_PYTHON_TEST_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["CONTAINERS_REGISTRIES_CONF"] = os.path.join( 43 self.anchor_directory, "registry.conf" 44 ) 45 p = configparser.ConfigParser() 46 p.read_dict( 47 { 48 "registries.search": {"registries": "['quay.io', 'docker.io']"}, 49 "registries.insecure": {"registries": "[]"}, 50 "registries.block": {"registries": "[]"}, 51 } 52 ) 53 with open(os.environ["CONTAINERS_REGISTRIES_CONF"], "w") as w: 54 p.write(w) 55 56 os.environ["CNI_CONFIG_PATH"] = os.path.join( 57 self.anchor_directory, "cni", "net.d" 58 ) 59 os.makedirs(os.environ["CNI_CONFIG_PATH"], exist_ok=True) 60 self.cmd.append("--cni-config-dir=" + os.environ["CNI_CONFIG_PATH"]) 61 cni_cfg = os.path.join( 62 os.environ["CNI_CONFIG_PATH"], "87-podman-bridge.conflist" 63 ) 64 # json decoded and encoded to ensure legal json 65 buf = json.loads( 66 """ 67 { 68 "cniVersion": "0.3.0", 69 "name": "default", 70 "plugins": [{ 71 "type": "bridge", 72 "bridge": "cni0", 73 "isGateway": true, 74 "ipMasq": true, 75 "ipam": { 76 "type": "host-local", 77 "subnet": "10.88.0.0/16", 78 "routes": [{ 79 "dst": "0.0.0.0/0" 80 }] 81 } 82 }, 83 { 84 "type": "portmap", 85 "capabilities": { 86 "portMappings": true 87 } 88 } 89 ] 90 } 91 """ 92 ) 93 with open(cni_cfg, "w") as w: 94 json.dump(buf, w) 95 96 def open(self, command, *args, **kwargs): 97 """Podman initialized instance to run a given command 98 99 :param self: Podman instance 100 :param command: podman sub-command to run 101 :param args: arguments and options for command 102 :param kwargs: See subprocess.Popen() for shell keyword 103 :return: subprocess.Popen() instance configured to run podman instance 104 """ 105 cmd = self.cmd.copy() 106 cmd.append(command) 107 cmd.extend(args) 108 109 shell = kwargs.get("shell", False) 110 111 return subprocess.Popen( 112 cmd, 113 shell=shell, 114 stdin=subprocess.DEVNULL, 115 stdout=subprocess.DEVNULL, 116 stderr=subprocess.DEVNULL, 117 ) 118 119 def run(self, command, *args, **kwargs): 120 """Podman initialized instance to run a given command 121 122 :param self: Podman instance 123 :param command: podman sub-command to run 124 :param args: arguments and options for command 125 :param kwargs: See subprocess.Popen() for shell and check keywords 126 :return: subprocess.Popen() instance configured to run podman instance 127 """ 128 cmd = self.cmd.copy() 129 cmd.append(command) 130 cmd.extend(args) 131 132 check = kwargs.get("check", False) 133 shell = kwargs.get("shell", False) 134 135 return subprocess.run( 136 cmd, 137 shell=shell, 138 check=check, 139 stdout=subprocess.PIPE, 140 stderr=subprocess.PIPE, 141 ) 142 143 def tear_down(self): 144 shutil.rmtree(self.anchor_directory, ignore_errors=True) 145 146 def restore_image_from_cache(self, client: DockerClient): 147 path = os.path.join(self.image_cache, constant.ALPINE_TARBALL) 148 if not os.path.exists(path): 149 img = client.images.pull(constant.ALPINE) 150 with open(path, mode="wb") as tarball: 151 for frame in img.save(named=True): 152 tarball.write(frame) 153 else: 154 self.run("load", "-i", path, check=True) 155 156 def flush_image_cache(self): 157 for f in pathlib.Path(self.image_cache).glob("*.tar"): 158 f.unlink(f)