diff --git a/agent/server.py b/agent/server.py index 75c80f50..a00f4c8c 100644 --- a/agent/server.py +++ b/agent/server.py @@ -4,6 +4,7 @@ import json import os import platform +import shlex import shutil import subprocess import tempfile @@ -58,14 +59,14 @@ def press_url(self): return self.config.get("press_url", "https://frappecloud.com") def docker_login(self, registry): - url = registry["url"] - username = registry["username"] - password = registry["password"] + url = shlex.quote(registry["url"]) + username = shlex.quote(registry["username"]) + password = shlex.quote(registry["password"]) return self.execute(f"docker login -u {username} -p {password} {url}") def docker_inspect_manifest(self, image_tag: str): try: - return self.execute(f"docker manifest inspect {image_tag}") + return self.execute(f"docker manifest inspect {shlex.quote(image_tag)}") except AgentException as e: if "no such manifest" in e.data.get("output", ""): raise Exception(f"Image {image_tag} not found in registry") from e @@ -149,7 +150,7 @@ def container_exists(self, name: str, max_retries: int = 3): """ for attempt in range(max_retries): try: - self.execute(f"docker inspect {name}") + self.execute(f"docker inspect {shlex.quote(name)}") except AgentException: break # container does not exist else: @@ -162,7 +163,7 @@ def get_image_size(self, image_tag: str): return ( to_bytes( self.execute( - f'docker image ls --format "{{{{.Tag}}}} {{{{.Size}}}}" | grep -E "^{image_tag} "' + f'docker image ls --format "{{{{.Tag}}}} {{{{.Size}}}}" | grep -E {shlex.quote("^" + image_tag + " ")}' )["output"].split()[-1] ) / 1024**3 @@ -233,7 +234,7 @@ def push_images_to_registry(self, images: list[str], registry_settings: dict[str def _push_images_to_registry(self, images: list[str], registry_settings: dict[str, str]) -> None: self.docker_login(registry_settings) for image in images: - self.execute(f"docker push {image}") + self.execute(f"docker push {shlex.quote(image)}") @job("Remove Redis Localhost Bind") def remove_redis_localhost_bind(self): @@ -270,7 +271,7 @@ def _check_site_on_bench(self, bench_name: str): def disable_production_on_bench(self, name: str): """In case of corrupted bench / site config don't stall archive""" self._check_site_on_bench(name) - self.execute(f"docker rm {name} --force") + self.execute(f"docker rm {shlex.quote(name)} --force") @job("Run Benches on Shared FS") def change_bench_directory( @@ -418,7 +419,7 @@ def remove_docker_image(self, image_tag: str): manifest = self.docker_inspect_manifest(image_tag) if not manifest: return - self.execute(f"docker rmi {image_tag} --force") + self.execute(f"docker rmi {shlex.quote(image_tag)} --force") @job("Cleanup Unused Files", priority="low") def cleanup_unused_files(self, force: bool = False): @@ -431,7 +432,7 @@ def cleanup_unused_files(self, force: bool = False): def remove_benches_without_container(self, benches: list[str]): for bench in benches: try: - self.execute(f"docker ps -a | grep {bench}") + self.execute(f"docker ps -a | grep {shlex.quote(bench)}") except AgentException as e: if e.data.returncode: self.move_to_archived_directory(Bench(bench, self)) @@ -720,7 +721,7 @@ def _pull_docker_images(self, image_tags: list[str], registry: dict[str, str]) - self.docker_login(registry) for image_tag in image_tags: - command = f"docker pull {image_tag}" + command = f"docker pull {shlex.quote(image_tag)}" self.execute(command, directory=self.directory) @job("Reload NGINX")