def test_pull_never(): with DockerBackend() as backend: with pytest.raises(docker.errors.DockerException): get_client().inspect_image("docker.io/library/busybox:1.25.1") image = backend.ImageClass("docker.io/library/busybox", tag="1.25.1", pull_policy=DockerImagePullPolicy.NEVER) assert not image.is_present()
def test_pull_if_not_present(): with DockerBackend() as backend: with pytest.raises(docker.errors.DockerException): get_client().inspect_image("docker.io/library/busybox:1.25.1") image = backend.ImageClass("docker.io/library/busybox", tag="1.25.1") try: assert image.is_present() finally: image.rmi(force=True)
def __init__(self, repository, tag="latest", identifier=None, pull_policy=DockerImagePullPolicy.IF_NOT_PRESENT, short_metadata=None): """ :param repository: str, image name, examples: "fedora", "registry.fedoraproject.org/fedora", "tomastomecek/sen", "docker.io/tomastomecek/sen" :param tag: str, tag of the image, when not specified, "latest" is implied :param identifier: str, unique identifier for this image :param pull_policy: enum, strategy to apply for pulling the image :param short_metadata: dict, metadata obtained from `docker.APIClient.images()` """ super(DockerImage, self).__init__(repository, tag=tag) if not isinstance(tag, (six.string_types, None.__class__)): raise ConuException("'tag' is not a string type") if not isinstance(pull_policy, DockerImagePullPolicy): raise ConuException("'pull_policy' is not an instance of DockerImagePullPolicy") self.tag = self.tag if identifier: self._id = identifier self.d = get_client() self.pull_policy = pull_policy # metadata obtained when doing `docker.APIClient().images()` self.short_metadata = short_metadata if self.pull_policy == DockerImagePullPolicy.ALWAYS: logger.debug("pull policy set to 'always', pulling the image") self.pull() elif self.pull_policy == DockerImagePullPolicy.IF_NOT_PRESENT and not self.is_present(): logger.debug("pull policy set to 'if_not_present' and image is not present, " "pulling the image") self.pull() elif self.pull_policy == DockerImagePullPolicy.NEVER: logger.debug("pull policy set to 'never'")
def __init__(self, repository, tag="latest", identifier=None, pull_policy=DockerImagePullPolicy.IF_NOT_PRESENT): """ :param repository: str, image name, examples: "fedora", "registry.fedoraproject.org/fedora", "tomastomecek/sen", "docker.io/tomastomecek/sen" :param tag: str, tag of the image, when not specified, "latest" is implied :param identifier: str, unique identifier for this image :param pull_policy: enum, strategy to apply for pulling the image """ super(DockerImage, self).__init__(repository, tag=tag) if not isinstance(tag, (six.string_types, None.__class__)): raise ConuException("'tag' is not a string type") if not isinstance(pull_policy, DockerImagePullPolicy): raise ConuException("'pull_policy' is not an instance of DockerImagePullPolicy") if identifier: self._id = identifier self.d = get_client() self.pull_policy = pull_policy self._inspect_data = None self.metadata = ImageMetadata() self.transport = SkopeoTransport.DOCKER if pull_policy == DockerImagePullPolicy.NEVER \ else SkopeoTransport.DOCKER_DAEMON self.path = None if self.pull_policy == DockerImagePullPolicy.ALWAYS: logger.debug("pull policy set to 'always', pulling the image") self.pull() elif self.pull_policy == DockerImagePullPolicy.IF_NOT_PRESENT and not self.is_present(): logger.debug("pull policy set to 'if_not_present' and image is not present, " "pulling the image") self.pull() elif self.pull_policy == DockerImagePullPolicy.NEVER: logger.debug("pull policy set to 'never'")
def __init__(self, repository, tag="latest", pull_policy=DockerImagePullPolicy.IF_NOT_PRESENT): """ :param repository: str, image name, examples: "fedora", "registry.fedoraproject.org/fedora", "tomastomecek/sen", "docker.io/tomastomecek/sen" :param tag: str, tag of the image, when not specified, "latest" is implied :param pull_policy: enum, strategy to apply for pulling the image """ super(DockerImage, self).__init__(repository, tag=tag) if not isinstance(tag, six.string_types): raise ConuException("'tag' is not a string type") if not isinstance(pull_policy, DockerImagePullPolicy): raise ConuException( "'pull_policy' is not an instance of DockerImagePullPolicy") self.tag = self.tag self.d = get_client() self.pull_policy = pull_policy if self.pull_policy == DockerImagePullPolicy.ALWAYS: logger.debug("pull policy set to 'always', pulling the image") self.pull() elif self.pull_policy == DockerImagePullPolicy.IF_NOT_PRESENT and not self.is_present( ): logger.debug( "pull policy set to 'if_not_present' and image is not present, " "pulling the image") self.pull() elif self.pull_policy == DockerImagePullPolicy.NEVER: logger.debug("pull policy set to 'never'")
def build(cls, path, tag=None, dockerfile=None): """ Build the image from the provided dockerfile in path :param path : str, path to the directory containing the Dockerfile :param tag: str, A tag to add to the final image :param dockerfile: str, path within the build context to the Dockerfile :return: instance of DockerImage """ if not path: raise ConuException('Please specify path to the directory containing the Dockerfile') client = get_client() response = [line for line in client.build(path, rm=True, tag=tag, dockerfile=dockerfile, quiet=True)] if not response: raise ConuException('Failed to get ID of image') # The expected output is just one line with image ID if len(response) > 1: raise ConuException('Build failed: ' + str(response)) # get ID from output # b'{"stream":"sha256:39c7bac4e2da37983203df4fcf612a02de9e6f6456a7f3434d1fccbc9ad639a5\\n"}\r\n' response_utf = response[0].decode('utf-8') if response_utf[:11] != '{"stream":"' or response_utf[-6:] != '\\n"}\r\n': raise ConuException('Failed to parse ID from ' + response_utf) image_id = response_utf[11:-6] return cls(None, identifier=image_id)
def __enter__(self): client = get_client() c = client.create_container(self.image.get_id()) try: stream, _ = client.get_archive(c, "/") try: os.mkdir(self.mount_point, 0o0700) except OSError as ex: if ex.errno == errno.EEXIST: logger.debug("mount point %s exists already", self.mount_point) pass else: logger.error("mount point %s can't be created: %s", self.mount_point, ex) raise logger.debug("about to untar the image") # we can't use tarfile because of --no-same-owner: files in containers are owned # by root and tarfile is trying to `chown 0 file` when running as an unpriv user p = subprocess.Popen( ["tar", "--no-same-owner", "-C", self.mount_point, "-x"], stdin=subprocess.PIPE, stderr=subprocess.PIPE, ) for x in stream: p.stdin.write(x) p.stdin.close() p.wait() if p.returncode: logger.error(p.stderr.read()) raise ConuException("Failed to unpack the archive.") logger.debug("image is unpacked") finally: client.remove_container(c, force=True) return super(DockerImageViaArchiveFS, self).__enter__()
def cleanup_containers(): client = get_client() conu_containers = client.containers(filters={'label': CONU_ARTIFACT_TAG}, all=True) for c in conu_containers: id = c['Id'] logger.debug("Removing container %s created by conu", id) client.stop(id) client.remove_container(id)
def __enter__(self): client = get_client() c = client.create_container(self.image.get_id()) container = DockerContainer(self.image, c["Id"]) try: export_docker_container_to_directory(client, container, self.mount_point) finally: container.delete(force=True) return super(DockerImageViaArchiveFS, self).__enter__()
def __init__(self, repository, tag="latest"): """ :param repository: str, image name, examples: "fedora", "registry.fedoraproject.org/fedora", "tomastomecek/sen", "docker.io/tomastomecek/sen" :param tag: str, tag of the image, when not specified, "latest" is implied """ super(DockerImage, self).__init__(repository, tag=tag) self.tag = self.tag self.d = get_client()
def __init__(self, image, container_id, name=None, popen_instance=None): """ :param image: DockerImage instance :param container_id: str, unique identifier of this container :param name: str, pretty container name :param popen_instance: instance of Popen (if container was created using method `via_binary`, this is the docker client process) """ super(DockerContainer, self).__init__(image, container_id, name) self.popen_instance = popen_instance self.d = get_client()
def __init__(self, image, container_id, name=None, popen_instance=None, short_metadata=None): """ :param image: DockerImage instance (if None, it will be found from the container itself) :param container_id: str, unique identifier of this container :param name: str, pretty container name :param popen_instance: instance of Popen (if container was created using method `via_binary`, this is the docker client process) :param short_metadata: dict, metadata obtained from `docker.APIClient.containers()` """ self.d = get_client() super(DockerContainer, self).__init__(image, container_id, name) self.popen_instance = popen_instance # metadata obtained when doing `docker.APIClient().containers()` self.short_metadata = short_metadata
def __init__(self, logging_level=logging.INFO, logging_kwargs=None, cleanup=None): """ This method serves as a configuration interface for conu. :param logging_level: int, control logger verbosity: see logging.{DEBUG,INFO,ERROR} :param logging_kwargs: dict, additional keyword arguments for logger set up, for more info see docstring of set_logging function :param cleanup: list, list of cleanup policy values, examples: - [CleanupPolicy.EVERYTHING] - [CleanupPolicy.VOLUMES, CleanupPolicy.TMP_DIRS] - [CleanupPolicy.NOTHING] """ super(DockerBackend, self).__init__( logging_level=logging_level, logging_kwargs=logging_kwargs, cleanup=cleanup) self.d = get_client()
def test_cleanup_containers(): with DockerBackend(logging_level=logging.DEBUG) as backend: # cleaning up from previous runs backend.cleanup_containers() client = get_client() container_sum = len(client.containers(all=True)) image = DockerImage(FEDORA_MINIMAL_REPOSITORY, tag=FEDORA_MINIMAL_REPOSITORY_TAG) command = ["ls"] additional_opts = ["-i", "-t"] for i in range(3): image.run_via_binary(command=command, additional_opts=additional_opts) assert container_sum+3 == len(client.containers(all=True)) backend.cleanup_containers() assert container_sum == len(client.containers(all=True))
def __enter__(self): client = get_client() export_docker_container_to_directory(client, self.container, self.mount_point) return super(DockerContainerViaExportFS, self).__enter__()
def create(cls, name, driver): client = get_client() response = client.create_network(name, driver=driver) return cls(response["Id"])
def __init__(self, identifier): super().__init__(identifier) self.d = get_client()