def up(self, services: List[str] = [], build: bool = False, detach: bool = False): """Start the containers. Reading the logs of the containers is not yet implemented. # Arguments services: The services to start. If empty (default), all services are started. build: If `True`, build the docker images before starting the containers even if a docker image with this name already exists. If `False` (the default), build only the docker images that do not already exist. detach: If `True`, run the containers in the background. If `False` this function returns only when all containers have stopped. # Returns `None` at the moment. The plan is to be able to capture and stream the logs later. It's not yet implemented. """ full_cmd = self.docker_compose_cmd + ["up"] full_cmd.add_flag("--detach", detach) full_cmd.add_flag("--build", build) full_cmd += services run(full_cmd, capture_stdout=False)
def upgrade( self, plugin: ValidPlugin, remote: Optional[str] = None, disable_content_trust: bool = True, skip_remote_check: bool = False, ) -> None: """Upgrade a plugin Warning: `--grant-all-permissions` is enabled, which means the program won't stop to ask you to grant the permissions. # Arguments plugin: The plugin to upgrade remote: The remote to fetch the upgrade from disable_content_trust: Skip image verification (default `True`) skip_remote_check: Do not check if specified remote plugin matches existing plugin image """ full_cmd = self.docker_cmd + [ "plugin", "upgrade", "--grant-all-permissions" ] if not disable_content_trust: full_cmd.append("--disable-content-trust=false") full_cmd.add_flag("--skip-remote-check", skip_remote_check) full_cmd.append(plugin) if remote is not None: full_cmd.append(remote) run(full_cmd)
def remove( self, x: Union[ValidImage, List[ValidImage]], force: bool = False, prune: bool = True, ): """Remove one or more docker images. # Arguments x: Single image or list of Docker images to remove. You can use tags or `python_on_whales.Image` objects. force: Force removal of the image prune: Delete untagged parents # Raises `python_on_whales.exceptions.NoSuchImage` if one of the images does not exists. """ full_cmd = self.docker_cmd + ["image", "remove"] full_cmd.add_flag("--force", force) full_cmd.add_flag("--no-prune", not prune) for image in to_list(x): full_cmd.append(image) run(full_cmd)
def update( self, service: ValidService, detach: bool = False, force: bool = False, image: Optional[str] = None, with_registry_authentication: bool = False, ): """Update a service More options coming soon # Arguments service: The service to update detach: Exit immediately instead of waiting for the service to converge force: Force update even if no changes require it image: Service image tag with_registry_authentication: Send registry authentication details to swarm agents """ full_cmd = self.docker_cmd + ["service", "update"] full_cmd.add_flag("--force", force) full_cmd.add_simple_arg("--image", image) full_cmd.add_flag("--with-registry-auth", with_registry_authentication) full_cmd.add_flag("--detach", detach) full_cmd.append(service) run(full_cmd, capture_stdout=False)
def update( self, node: ValidNode, availability: Optional[str] = None, labels_add: Dict[str, str] = {}, rm_labels: List[str] = [], role: Optional[str] = None, ) -> None: """Updates a Swarm node. # Arguments node: The node to update, you can use a string or a `python_on_whales.Node` object. availability: Availability of the node ("active"|"pause"|"drain") labels_add: Remove a node label if exists rm_labels: Labels to remove from the node. role: Role of the node ("worker"|"manager") """ full_cmd = self.docker_cmd + ["node", "update"] full_cmd.add_simple_arg("--availability", availability) for label_name, label_value in labels_add.items(): full_cmd += ["--label-add", f"{label_name}={label_value}"] for label in rm_labels: full_cmd += ["--rm-label", label] full_cmd.add_simple_arg("--role", role) full_cmd.append(node) run(full_cmd)
def join( self, manager_address: str, advertise_address: str = None, availability: str = "active", data_path_address: str = None, listen_address: str = None, token: str = None, ): """Joins a swarm # Arguments manager_address: The address of the swarm manager in the format `"{ip}:{port}"` advertise_address: Advertised address (format: <ip|interface>[:port]) availability: Availability of the node (`"active"`|`"pause"`|`"drain"`) data_path_address: Address or interface to use for data path traffic (format: <ip|interface>) listen-address: Listen address (format: <ip|interface>[:port]) (default 0.0.0.0:2377) token: Token for entry into the swarm, will determine if the node enters the swarm as a manager or a worker. """ full_cmd = self.docker_cmd + ["swarm", "join"] full_cmd.add_simple_arg("--advertise-addr", advertise_address) full_cmd.add_simple_arg("--availability", availability) full_cmd.add_simple_arg("--data-path-addr", data_path_address) full_cmd.add_simple_arg("--listen-addr", listen_address) full_cmd.add_simple_arg("--token", token) full_cmd.append(manager_address) run(full_cmd)
def create( self, services: Union[str, List[str]] = [], build: bool = False, force_recreate: bool = False, no_build: bool = False, no_recreate=False, ): """Creates containers for a service. # Arguments build: Build images before starting containers. force_recreate: Recreate containers even if their configuration and image haven't changed. no_build: Don't build an image, even if it's missing. no_recreate: If containers already exist, don't recreate them. Incompatible with `force_recreate=True`. """ full_cmd = self.docker_compose_cmd + ["create"] full_cmd.add_flag("--build", build) full_cmd.add_flag("--force-recreate", force_recreate) full_cmd.add_flag("--no-build", no_build) full_cmd.add_flag("--no-recreate", no_recreate) full_cmd += to_list(services) run(full_cmd, capture_stdout=False)
def down( self, remove_orphans: bool = False, remove_images: Optional[str] = None, timeout: Optional[int] = None, volumes: bool = False, ): """Stops and removes the containers # Arguments remove_orphans: Remove containers for services not defined in the Compose file. remove_images: Remove images used by services. `"local"` remove only images that don't have a custom tag. Possible values are `"local"` and `"all"`. timeout: Specify a shutdown timeout in seconds (default 10). volumes: Remove named volumes declared in the volumes section of the Compose file and anonymous volumes attached to containers. """ full_cmd = self.docker_compose_cmd + ["down"] full_cmd.add_flag("--remove-orphans", remove_orphans) full_cmd.add_simple_arg("--rmi", remove_images) full_cmd.add_simple_arg("--timeout", timeout) full_cmd.add_flag("--volumes", volumes) run(full_cmd)
def install( self, plugin_name: str, configuration: Dict[str, str] = {}, alias: Optional[str] = None, disable: bool = False, disable_content_trust: bool = True, ) -> Plugin: """Installs a Docker plugin Warning: `--grant-all-permissions` is enabled, which means the program won't stop to ask you to grant the permissions. # Arguments plugin_name: The name of the plugin you want to install configuration: A `dict` adding configuration options to the plugin alias: Local name for plugin disable: Do not enable the plugin on install disable_content_trust: Skip image verification (default `True`) # Returns A `python_on_whales.Plugin`. """ full_cmd = self.docker_cmd + ["plugin", "install", "--grant-all-permissions"] full_cmd.add_simple_arg("--alias", alias) full_cmd.add_flag("--disable", disable) if not disable_content_trust: full_cmd.append("--disable-content-trust=false") full_cmd.append(plugin_name) for key, value in configuration.items(): full_cmd.append(f"{key}={value}") run(full_cmd) if alias is not None: return Plugin(self.client_config, alias) return Plugin(self.client_config, plugin_name)
def use(self, context: ValidContext): """Set the default context # Arguments context: The context to set as default """ full_cmd = self.docker_cmd + ["context", "use", context] run(full_cmd)
def remove(self, x: Union[ValidSecret, List[ValidSecret]]) -> None: """Removes one or more secrets # Arguments x: One or more secrets. Name, ids or `python_on_whales.Secret` objects are valid inputs. """ full_cmd = self.docker_cmd + ["secret", "remove"] + to_list(x) run(full_cmd)
def remove(self, x: Union[ValidStack, List[ValidStack]]) -> None: """Removes one or more stacks. # Arguments x: One or more stacks """ full_cmd = self.docker_cmd + ["stack", "remove"] + to_list(x) run(full_cmd)
def _pull_single_tag(self, image_name: str, quiet: bool): full_cmd = self.docker_cmd + ["image", "pull"] if quiet: full_cmd.append("--quiet") full_cmd.append(image_name) run(full_cmd, capture_stdout=quiet, capture_stderr=quiet) return Image(self.client_config, image_name)
def start(self, services: Union[str, List[str]] = []): """Start the specified services. # Arguments services: The names of one or more services to start """ full_cmd = self.docker_compose_cmd + ["start"] full_cmd += to_list(services) run(full_cmd)
def leave(self, force: bool = False) -> None: """Leave the swarm # Arguments force: Force this node to leave the swarm, ignoring warnings """ full_cmd = self.docker_cmd + ["swarm", "leave"] full_cmd.add_flag("--force", force) run(full_cmd)
def save( self, images: Union[ValidImage, List[ValidImage]], output: Optional[ValidPath] = None, ) -> Optional[Iterator[bytes]]: """Save one or more images to a tar archive. Returns a stream if output is `None` Alias: `docker.save(...)` # Arguments images: Single docker image or list of docker images to save output: Path of the tar archive to produce. If `output` is None, a generator of bytes is produced. It can be used to stream those bytes elsewhere, to another Docker daemon for example. # Returns `Optional[Iterator[bytes]]`. If output is a path, nothing is returned. # Raises `python_on_whales.exceptions.NoSuchImage` if one of the images does not exists. # Example An example of transfer of an image from a local Docker daemon to a remote Docker daemon. We assume that the remote machine has an ssh access: ```python from python_on_whales import DockerClient local_docker = DockerClient() remote_docker = DockerClient(host="ssh://[email protected]") image_name = "busybox:1" local_docker.pull(image_name) bytes_iterator = local_docker.image.save(image_name) remote_docker.image.load(bytes_iterator) ``` Of course the best solution is to use a registry to transfer image but it's a cool example nonetheless. """ full_cmd = self.docker_cmd + ["image", "save"] images = to_list(images) # trigger an exception early self.inspect(images) if output is not None: full_cmd += ["--output", str(output)] full_cmd += images if output is None: # we stream the bytes return self._save_generator(full_cmd) else: run(full_cmd)
def promote(self, x: Union[ValidNode, List[ValidNode]]): """Promote one or more nodes to manager in the swarm # Arguments x: One or a list of nodes. """ full_cmd = self.docker_cmd + ["node", "promote"] full_cmd += to_list(x) run(full_cmd)
def remove(self, builder: Union[Builder, str]) -> None: """Remove a builder # Arguments builder: The builder to remove """ full_cmd = self.docker_cmd + ["buildx", "rm"] full_cmd.append(builder) run(full_cmd)
def build(self, services: List[str] = []): """Build services declared in a yaml compose file. # Arguments services: The services to build (as strings). If empty (default), all services are built. """ full_cmd = self.docker_compose_cmd + ["build"] full_cmd += services run(full_cmd, capture_stdout=False)
def unlock(self, key: str) -> None: """Unlock a swarm after the `--autolock` parameter was used and the daemon restarted. # Arguments: key: The key to unlock the swarm. The key can be obtained on any manager with `docker.swarm.unlock_key()`. """ full_cmd = self.docker_cmd + ["swarm", "unlock"] run(full_cmd, input=key.encode("utf-8"))
def disconnect( self, network: ValidNetwork, container: python_on_whales.components.container.ValidContainer, force: bool = False, ): full_cmd = self.docker_cmd + ["network", "disconnet"] full_cmd.add_flag("--force", force) full_cmd += [network, container] run(full_cmd)
def remove(self, x: Union[ValidConfig, List[ValidConfig]]): """Remove one or more configs. # Arguments x: One or a list of configs. Valid values are the id of the config or a `python_on_whales.Config` object. """ full_cmd = self.docker_cmd + ["config", "rm"] full_cmd += to_list(x) run(full_cmd)
def remove(self, networks: Union[ValidNetwork, List[ValidNetwork]]): """Removes a Docker network # Arguments networks: One or more networks. """ full_cmd = self.docker_cmd + ["network", "remove"] for network in to_list(networks): full_cmd.append(network) run(full_cmd)
def push(self, services: List[str] = []): """Push service images # Arguments services: The list of services to select. Only the images of those services will be pushed. If no services are specified (the default behavior) all images of all services are pushed. """ full_cmd = self.docker_compose_cmd + ["push"] full_cmd += services run(full_cmd)
def stop(self, builder: Optional[ValidBuilder]) -> None: """Stop the builder instance # Arguments: builder: The builder to stop. If `None` (the default value), the current builder is stopped. """ full_cmd = self.docker_cmd + ["buildx", "stop"] if builder is not None: full_cmd.append(builder) run(full_cmd)
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)
def enable(self, plugin: ValidPlugin, timeout: int = None) -> None: """Enable a plugin # Arguments plugin: The plugin to enable timeout: HTTP client timeout (in seconds) (default 30) """ full_cmd = self.docker_cmd + ["plugin", "enable"] full_cmd.add_simple_arg("--timeout", timeout) full_cmd.append(plugin) run(full_cmd)
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)
def prune(self, all: bool = False, volumes: bool = False) -> None: """Remove unused docker data # Arguments all: Remove all unused images not just dangling ones volumes: Prune volumes """ full_cmd = self.docker_cmd + ["system", "prune"] full_cmd.add_flag("--all", all) full_cmd.add_flag("--volumes", volumes) run(full_cmd)
def disable(self, plugin: ValidPlugin, force: bool = False) -> None: """Disable a plugin # Arguments plugin: The plugin to disable force: Force the disable of an active plugin """ full_cmd = self.docker_cmd + ["plugin", "disable"] full_cmd.add_flag("--force", force) full_cmd.append(plugin) run(full_cmd)