Example #1
0
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()
Example #2
0
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)
Example #3
0
    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'")
Example #4
0
    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'")
Example #5
0
    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'")
Example #6
0
    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)
Example #7
0
    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__()
Example #8
0
 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)
Example #9
0
 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__()
Example #10
0
 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()
Example #11
0
 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()
Example #12
0
 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
Example #13
0
    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()
Example #14
0
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))
Example #15
0
 def __enter__(self):
     client = get_client()
     export_docker_container_to_directory(client, self.container,
                                          self.mount_point)
     return super(DockerContainerViaExportFS, self).__enter__()
Example #16
0
 def create(cls, name, driver):
     client = get_client()
     response = client.create_network(name, driver=driver)
     return cls(response["Id"])
Example #17
0
 def __init__(self, identifier):
     super().__init__(identifier)
     self.d = get_client()