Exemplo n.º 1
0
    def list(self, filters: Dict[str, str] = {}) -> List[Image]:
        """Returns the list of Docker images present on the machine.

        Alias: `docker.images()`

        Note that each image may have multiple tags.

        # Returns
            A `List[python_on_whales.Image]` object.
        """
        full_cmd = self.docker_cmd + [
            "image",
            "list",
            "--quiet",
            "--no-trunc",
        ]
        full_cmd.add_args_list("--filter", format_dict_for_cli(filters))

        ids = run(full_cmd).splitlines()
        # the list of tags is bigger than the number of images. We uniquify
        ids = set(ids)

        return [
            Image(self.client_config, x, is_immutable_id=True) for x in ids
        ]
Exemplo n.º 2
0
    def create(
        self,
        name: str,
        file: Union[str, Path],
        labels: Dict[str, str] = {},
        template_driver: Optional[str] = None,
    ) -> Config:
        """Create a config from a file

        See [the docker docs](https://docs.docker.com/engine/swarm/configs/)
        for more information about swarm configs.

        # Arguments
            name: The config name.
            file: Tbe file to be used as config.
            labels: The labels to add to the config
            template_driver: The template driver

        # Returns
            A `python_on_whales.Config` object.
        """
        full_cmd = self.docker_cmd + ["config", "create"]
        full_cmd.add_args_list("--label", format_dict_for_cli(labels))
        full_cmd.add_simple_arg("--template-driver", template_driver)
        full_cmd += [name, file]
        return Config(self.client_config, run(full_cmd), is_immutable_id=True)
Exemplo n.º 3
0
    def create(
        self,
        name: str,
        attachable: bool = False,
        driver: Optional[str] = None,
        gateway: Optional[str] = None,
        subnet: Optional[str] = None,
        labels: Dict[str, str] = {},
        options: List[str] = [],
    ) -> Network:
        """Creates a Docker network.

        # Arguments
            name: The name of the network

        # Returns
            A `python_on_whales.Network`.
        """
        full_cmd = self.docker_cmd + ["network", "create"]
        full_cmd.add_flag("--attachable", attachable)
        full_cmd.add_simple_arg("--driver", driver)
        full_cmd.add_simple_arg("--gateway", gateway)
        full_cmd.add_simple_arg("--subnet", subnet)
        full_cmd.add_args_list("--label", format_dict_for_cli(labels))
        full_cmd.add_args_list("--opt", options)
        full_cmd.append(name)
        return Network(self.client_config, run(full_cmd), is_immutable_id=True)
Exemplo n.º 4
0
 def list(self, filters: Dict[str, str] = {}) -> List[Secret]:
     """Returns all secrets as a `List[python_on_whales.Secret]`."""
     full_cmd = self.docker_cmd + ["secret", "list", "--quiet"]
     full_cmd.add_args_list("--filter", format_dict_for_cli(filters))
     ids = run(full_cmd).splitlines()
     return [
         Secret(self.client_config, id_, is_immutable_id=True)
         for id_ in ids
     ]
Exemplo n.º 5
0
    def prune(self, all: bool = False, filter: Dict[str, str] = {}) -> None:
        """Remove unused images

        # Arguments
            all: Remove all unused images, not just dangling ones
            filter: Provide filter values (e.g. `{"until": "<timestamp>"}`)
        """
        full_cmd = self.docker_cmd + ["image", "prune", "--force"]
        full_cmd.add_flag("--all", all)
        full_cmd.add_args_list("--filter", format_dict_for_cli(filter))
        run(full_cmd)
Exemplo n.º 6
0
    def prune(self, all: bool = False, filters: Dict[str, str] = {}) -> None:
        """Remove build cache on the current builder.

        # Arguments
            all: Remove all cache, not just dangling layers
            filters: Filters to use, for example `filters=dict(until="24h")`
        """
        full_cmd = self.docker_cmd + ["buildx", "prune", "--force"]
        full_cmd.add_flag("--all", all)
        full_cmd.add_args_list("--filter", format_dict_for_cli(filters))
        run(full_cmd)
Exemplo n.º 7
0
    def list(self, filters: Dict[str, str] = {}) -> List[Network]:
        full_cmd = self.docker_cmd + [
            "network", "list", "--no-trunc", "--quiet"
        ]
        full_cmd.add_args_list("--filter", format_dict_for_cli(filters))

        ids = run(full_cmd).splitlines()
        return [
            Network(self.client_config, id_, is_immutable_id=True)
            for id_ in ids
        ]
Exemplo n.º 8
0
    def list(self, filters: Dict[str, str] = {}) -> List[Config]:
        """List all config available in the swarm.

        # Arguments
            filters: If you want to filter the results based on a given condition.
                For example, `docker.config.list(filters=dict(label="my_label=hello"))`.

        # Returns
            A `List[python_on_whales.Config]`.
        """
        full_cmd = self.docker_cmd + ["config", "list", "--quiet"]
        full_cmd.add_args_list("--filter", format_dict_for_cli(filters))
        output = run(full_cmd)
        ids = output.splitlines()
        return [
            Config(self.client_config, id_, is_immutable_id=True)
            for id_ in ids
        ]
Exemplo n.º 9
0
    def prune(self,
              all: bool = False,
              volumes: bool = False,
              filters: Dict[str, str] = {}) -> None:
        """Remove unused docker data

        # Arguments
            all: Remove all unused images not just dangling ones
            volumes: Prune volumes
            filters: See the [Docker documentation page about filtering
                ](https://docs.docker.com/engine/reference/commandline/system_prune/#filtering).
                For example, `filters=dict(until="24h")`.
        """
        full_cmd = self.docker_cmd + ["system", "prune", "--force"]
        full_cmd.add_flag("--all", all)
        full_cmd.add_flag("--volumes", volumes)
        full_cmd.add_args_list("--filter", format_dict_for_cli(filters))
        run(full_cmd)
Exemplo n.º 10
0
    def create(
        self,
        name: str,
        file: ValidPath,
        driver: Optional[str] = None,
        labels: Dict[str, str] = {},
        template_driver: Optional[str] = None,
    ) -> Secret:
        """Creates a `python_on_whales.Secret`.

        # Returns
            A `python_on_whales.Secret` object.
        """
        full_cmd = self.docker_cmd + ["secret", "create"]
        full_cmd.add_simple_arg("--driver", driver)
        full_cmd.add_args_list("--label", format_dict_for_cli(labels))
        full_cmd.add_simple_arg("--template-driver", template_driver)
        full_cmd += [name, file]
        return Secret(self.client_config, run(full_cmd), is_immutable_id=True)
Exemplo n.º 11
0
 def prune(self, filters: Dict[str, str] = {}):
     full_cmd = self.docker_cmd + ["network", "prune", "--force"]
     full_cmd.add_args_list("--filter", format_dict_for_cli(filters))
     run(full_cmd)
Exemplo n.º 12
0
    def bake(
        self,
        targets: Union[str, List[str]] = [],
        builder: Optional[ValidBuilder] = None,
        files: Union[ValidPath, List[ValidPath]] = [],
        load: bool = False,
        cache: bool = True,
        print: bool = False,
        progress: Union[str, bool] = "auto",
        pull: bool = False,
        push: bool = False,
        set: Dict[str, str] = {},
        variables: Dict[str, str] = {},
    ) -> Dict[str, Dict[str, Dict[str, Any]]]:
        """Bake is similar to make, it allows you to build things declared in a file.

        For example it allows you to build multiple docker image in parallel.

        The CLI docs is [here](https://github.com/docker/buildx#buildx-bake-options-target)
        and it contains a lot more information.

        # Arguments
            targets: Targets or groups of targets to build.
            builder: The builder to use.
            files: Build definition file(s)
            load: Shorthand for `set=["*.output=type=docker"]`
            cache: Whether to use the cache or not.
            print: Do nothing, just returns the config.
            progress: Set type of progress output (`"auto"`, `"plain"`, `"tty"`,
                or `False`). Use plain to keep the container output on screen
            pull: Always try to pull the newer version of the image
            push: Shorthand for `set=["*.output=type=registry"]`
            set: A list of overrides in the form `"targetpattern.key=value"`.
            variables: A dict containing the values of the variables defined in the
                hcl file. See <https://github.com/docker/buildx#hcl-variables-and-functions>

        # Returns
            The configuration used for the bake (files merged + override with
            the arguments used in the function). It's the loaded json you would
            obtain by running `docker buildx bake --print --load my_target` if
            your command was `docker buildx bake --load my_target`. Some example here.


        ```python
        from python_on_whales import docker

        # returns the config used and runs the builds
        config = docker.buildx.bake(["my_target1", "my_target2"], load=True)
        assert config == {
            "target": {
                "my_target1": {
                    "context": "./",
                    "dockerfile": "Dockerfile",
                    "tags": ["pretty_image1:1.0.0"],
                    "target": "out1",
                    "output": ["type=docker"]
                },
                "my_target2": {
                    "context": "./",
                    "dockerfile": "Dockerfile",
                    "tags": ["pretty_image2:1.0.0"],
                    "target": "out2",
                    "output": ["type=docker"]
                }
            }
        }

        # returns the config only, doesn't run the builds
        config = docker.buildx.bake(["my_target1", "my_target2"], load=True, print=True)
        ```
        """
        full_cmd = self.docker_cmd + ["buildx", "bake"]

        full_cmd.add_flag("--no-cache", not cache)
        full_cmd.add_simple_arg("--builder", builder)
        full_cmd.add_flag("--load", load)
        full_cmd.add_flag("--pull", pull)
        full_cmd.add_flag("--push", push)
        full_cmd.add_flag("--print", print)
        if progress != "auto" and isinstance(progress, str):
            full_cmd += ["--progress", progress]
        for file in to_list(files):
            full_cmd.add_simple_arg("--file", file)
        full_cmd.add_args_list("--set", format_dict_for_cli(set))
        targets = to_list(targets)
        env = dict(os.environ)
        env.update(variables)
        if print:
            return json.loads(run(full_cmd + targets, env=env))
        else:
            run(full_cmd + targets, capture_stderr=progress is False, env=env)
            return json.loads(run(full_cmd + ["--print"] + targets, env=env))
Exemplo n.º 13
0
def format_dict_for_buildx(options: Dict[str, str]) -> str:
    return ",".join(format_dict_for_cli(options, separator="="))
Exemplo n.º 14
0
    def build(
        self,
        context_path: ValidPath,
        add_hosts: Dict[str, str] = {},
        allow: List[str] = [],
        build_args: Dict[str, str] = {},
        builder: Optional[ValidBuilder] = None,
        cache: bool = True,
        cache_from: Union[str, Dict[str, str], None] = None,
        cache_to: Union[str, Dict[str, str], None] = None,
        file: Optional[ValidPath] = None,
        labels: Dict[str, str] = {},
        load: bool = False,
        network: Optional[str] = None,
        output: Dict[str, str] = {},
        platforms: Optional[List[str]] = None,
        progress: Union[str, bool] = "auto",
        pull: bool = False,
        push: bool = False,
        secrets: Union[str, List[str]] = [],
        ssh: Optional[str] = None,
        tags: Union[str, List[str]] = [],
        target: Optional[str] = None,
    ) -> Optional[python_on_whales.components.image.Image]:
        """Build a Docker image with builkit as backend.

        Alias: `docker.build(...)`

        A `python_on_whales.Image` is returned, even when using multiple tags.
        That is because it will produce a single image with multiple tags.
        If no image is loaded into the Docker daemon (if `push=True` for ex),
        then `None` is returned.

        # Arguments
            context_path: The path of the build context.
            add_hosts: Hosts to add. `add_hosts={"my_host1": "192.168.32.35"}`
            allow: List of extra privileges.
                Eg `allow=["network.host", "security.insecure"]`
            build_args: The build arguments.
                ex `build_args={"PY_VERSION": "3.7.8", "UBUNTU_VERSION": "20.04"}`.
            builder: Specify which builder to use.
            cache: Whether or not to use the cache
            cache_from: Works only with the container driver. Loads the cache
                (if needed) from a registry `cache_from="user/app:cache"`  or
                a directory on the client `cache_from="type=local,src=path/to/dir"`.
                It's also possible to use a dict form for this argument. e.g.
                `cache_from=dict(type="local", src="path/to/dir")`
            cache_to: Works only with the container driver. Sends the resulting
                docker cache either to a registry `cache_to="user/app:cache"`,
                or to a local directory `cache_to="type=local,dest=path/to/dir"`.
                It's also possible to use a dict form for this argument. e.g.
                `cache_to=dict(type="local", dest="path/to/dir", mode="max")`
            file: The path of the Dockerfile
            labels: Dict of labels to add to the image.
                `labels={"very-secure": "1", "needs-gpu": "0"}` for example.
            load: Shortcut for `output=dict(type="docker")` If `True`,
                `docker.buildx.build` will return a `python_on_whales.Image`.
            network: which network to use when building the Docker image
            output: Output destination
                (format: `output={"type": "local", "dest": "path"}`
                Possible output types are
                `["local", "tar", "oci", "docker", "image", "registry"]`.
                See [this link](https://github.com/docker/buildx#-o---outputpath-typetypekeyvalue)
                for more details about each exporter.
            platforms: List of target platforms when building the image. Ex:
                `platforms=["linux/amd64", "linux/arm64"]`
            progress: Set type of progress output (auto, plain, tty, or False).
                Use plain to keep the container output on screen
            pull: Always attempt to pull a newer version of the image
            push: Shorthand for `output=dict(type="registry")`.
            secrets: One or more secrets passed as string(s). For example
                `secrets="id=aws,src=/home/my_user/.aws/credentials"`
            ssh: SSH agent socket or keys to expose to the build
                (format is `default|<id>[=<socket>|<key>[,<key>]]` as a string)
            tags: Tag or tags to put on the resulting image.
            target: Set the target build stage to build.

        # Returns
            A `python_on_whales.Image` if a Docker image is loaded
            in the daemon after the build (the default behavior when
            calling `docker.build(...)`). Otherwise, `None`.
        """
        tags = to_list(tags)
        full_cmd = self.docker_cmd + ["buildx", "build"]

        if progress != "auto" and isinstance(progress, str):
            full_cmd += ["--progress", progress]

        full_cmd.add_args_list("--add-host",
                               format_dict_for_cli(add_hosts, separator=":"))
        full_cmd.add_args_list("--allow", allow)
        full_cmd.add_args_list("--build-arg", format_dict_for_cli(build_args))
        full_cmd.add_simple_arg("--builder", builder)
        full_cmd.add_args_list("--label", format_dict_for_cli(labels))

        full_cmd.add_simple_arg("--ssh", ssh)

        full_cmd.add_flag("--pull", pull)
        full_cmd.add_flag("--push", push)
        full_cmd.add_flag("--load", load)
        full_cmd.add_simple_arg("--file", file)
        full_cmd.add_simple_arg("--target", target)
        if isinstance(cache_from, dict):
            full_cmd.add_simple_arg("--cache-from",
                                    format_dict_for_buildx(cache_from))
        else:
            full_cmd.add_simple_arg("--cache-from", cache_from)
        if isinstance(cache_to, dict):
            full_cmd.add_simple_arg("--cache-to",
                                    format_dict_for_buildx(cache_to))
        else:
            full_cmd.add_simple_arg("--cache-to", cache_to)
        full_cmd.add_args_list("--secret", to_list(secrets))
        if output != {}:
            full_cmd += ["--output", format_dict_for_buildx(output)]
        if platforms is not None:
            full_cmd += ["--platform", ",".join(platforms)]
        full_cmd.add_simple_arg("--network", network)
        full_cmd.add_flag("--no-cache", not cache)
        full_cmd.add_args_list("--tag", tags)

        will_load_image = self._build_will_load_image(builder, push, load,
                                                      output)
        # very special_case, must be fixed https://github.com/docker/buildx/issues/420
        if (will_load_image and not tags
                and self.inspect(builder).driver == "docker-container"):
            # we have no way of fetching the image because iidfile is wrong in this case.
            will_load_image = False

        if not will_load_image:
            full_cmd.append(context_path)
            run(full_cmd, capture_stderr=progress is False)
            return

        docker_image = python_on_whales.components.image.ImageCLI(
            self.client_config)
        if self._method_to_get_image(builder) == GetImageMethod.TAG:
            full_cmd.append(context_path)
            run(full_cmd, capture_stderr=progress is False)
            return docker_image.inspect(tags[0])
        else:
            with tempfile.TemporaryDirectory() as tmp_dir:
                tmp_dir = Path(tmp_dir)
                iidfile = tmp_dir / "id_file.txt"
                full_cmd.add_simple_arg("--iidfile", iidfile)
                full_cmd.append(context_path)
                run(full_cmd, capture_stderr=progress is False)
                image_id = iidfile.read_text()
                return docker_image.inspect(image_id)
Exemplo n.º 15
0
    def create(
        self,
        image: str,
        command: Union[str, List[str], None],
        cap_add: List[str] = [],
        cap_drop: List[str] = [],
        constraints: List[str] = [],
        detach: bool = False,
        dns: List[str] = [],
        dns_options: List[str] = [],
        dns_search: List[str] = [],
        endpoint_mode: Optional[str] = None,
        entrypoint: Optional[str] = None,
        envs: Dict[str, str] = {},
        env_files: Union[ValidPath, List[ValidPath]] = [],
        generic_resources: List[str] = [],
        groups: List[str] = [],
        healthcheck: bool = True,
        health_cmd: Optional[str] = None,
        health_interval: Union[None, int, timedelta] = None,
        health_retries: Optional[int] = None,
        health_start_period: Union[None, int, timedelta] = None,
        health_timeout: Union[None, int, timedelta] = None,
        hosts: Dict[str, str] = {},
        hostname: Optional[str] = None,
        init: bool = False,
        isolation: Optional[str] = None,
        labels: Dict[str, str] = {},
        limit_cpu: Optional[float] = None,
        limit_memory: Optional[str] = None,
        limit_pids: Optional[int] = None,
        log_driver: Optional[str] = None,
    ):
        """Creates a Docker swarm service.

        Consider using 'docker stack deploy' instead as it's idempotent and
        easier to read for complex applications.
        docker stack deploy is basically docker compose for swarm clusters.

        # Arguments:
            image: The image to use as the base for the service.
            command: The command to execute in the container(s).
        """
        full_cmd = self.docker_cmd + ["service", "create", "--quiet"]

        full_cmd.add_args_list("--cap-add", cap_add)
        full_cmd.add_args_list("--cap-drop", cap_drop)
        full_cmd.add_args_list("--constraint", constraints)

        full_cmd.add_flag("--detach", detach)
        full_cmd.add_args_list("--dns", dns)
        full_cmd.add_args_list("--dns-option", dns_options)
        full_cmd.add_args_list("--dns-search", dns_search)
        full_cmd.add_simple_arg("--endpoint-mode", endpoint_mode)
        full_cmd.add_simple_arg("--entrypoint", entrypoint)

        full_cmd.add_args_list("--env", format_dict_for_cli(envs))
        full_cmd.add_args_list("--env-file", env_files)

        full_cmd.add_args_list("--generic-resource", generic_resources)
        full_cmd.add_args_list("--group", groups)

        full_cmd.add_flag("--no-healthcheck", not healthcheck)
        full_cmd.add_simple_arg("--health-cmd", health_cmd)
        full_cmd.add_simple_arg("--health-interval",
                                to_seconds(health_interval))
        full_cmd.add_simple_arg("--health-retries", health_retries)
        full_cmd.add_simple_arg("--health-start-period",
                                to_seconds(health_start_period))
        full_cmd.add_simple_arg("--health-timeout", to_seconds(health_timeout))
        for key, value in hosts:
            full_cmd += ["--host", f"{key}:{value}"]

        full_cmd.add_simple_arg("--hostname", hostname)

        full_cmd.add_flag("--init", init)
        full_cmd.add_simple_arg("--isolation", isolation)
        full_cmd.add_args_list("--label", format_dict_for_cli(labels))
        full_cmd.add_simple_arg("--limit-cpu", limit_cpu)
        full_cmd.add_simple_arg("--limit-memory", limit_memory)
        full_cmd.add_simple_arg("--limit-pids", limit_pids)
        full_cmd.add_simple_arg("--log-driver", log_driver)

        full_cmd.append(image)
        if command is not None:
            for string in to_list(command):
                full_cmd.append(string)

        service_id = run(full_cmd)
        return Service(self.client_config, service_id, is_immutable_id=True)