Beispiel #1
0
    def update_submodules(self, depth: int = 0, jobs: int = 0) -> None:
        """
        Update all submodules

        Returns:
            None
        """
        os_command = [
            "git",
            "submodule",
            "update",
            "--init",
            "--recursive",
        ]

        if depth:
            os_command += ["--depth", f"{depth}"]

        if jobs:
            os_command += ["--jobs", f"{jobs}"]

        logger.info(icon=f"{self.ICON} 🌱", title="Updating submodules: ", end="")

        result = run_os_command(os_command)
        if result.return_code:
            logger.std(result, raise_exception=True)
        logger.success()
    def delete(
        self,
        resource: str,
        name: Optional[str] = None,
        labels: Optional[Dict[str, str]] = None,
        namespace: str = settings.K8S_NAMESPACE,
    ) -> None:
        os_command = [
            "kubectl",
            "delete",
            resource,
            "--ignore-not-found",
            "--wait=true",
            f"--namespace={namespace}",
        ]

        logger.info(icon=f"{self.ICON}  🗑️ ",
                    title=f"Removing {resource}",
                    end="")
        if labels:
            labels_str = self.labels_to_string(labels)
            os_command += ["-l", labels_str]
            logger.info(title=f" with labels {labels_str}", end="")
        if name:
            os_command += [name]
            logger.info(title=f" with name '{name}'", end="")
        logger.info(": ", end="")
        result = run_os_command(os_command, shell=True)
        if not result.return_code:
            logger.success()
        else:
            logger.std(result, raise_exception=True)
Beispiel #3
0
 def update_repos(self) -> None:
     logger.info(icon=f"{self.ICON}  🔄", title="Updating Helm repos: ", end="")
     result = run_os_command(["helm", "repo", "update"])
     if not result.return_code:
         logger.success()
     else:
         logger.std(result, raise_exception=True)
Beispiel #4
0
 def remove_repo(self, repo_name: str) -> None:
     logger.info(
         icon=f"{self.ICON}  âž–",
         title=f"Removing Helm repo {repo_name}: ",
         end="",
     )
     result = run_os_command(["helm", "repo", "remove", repo_name])
     if not result.return_code:
         logger.success()
     else:
         logger.std(result, raise_exception=True)
Beispiel #5
0
    def delete_image(self, image: DockerImage) -> None:
        logger.warning(icon=f"{self.ICON}", message="Removing Docker image")
        for tag in image.tags:
            logger.info(message=f"\t {image.repository}:{tag}: ", end="")
            delete_command = ["docker", "rmi", f"{image.repository}:{tag}"]
            result = run_os_command(delete_command, shell=False)

            if result.return_code:
                logger.std(result, raise_exception=False)
            else:
                logger.success()
Beispiel #6
0
    def pull_image(self, image: str) -> bool:
        logger.info(icon=f"{self.ICON} ⏬", title=f"Pulling {image}:", end=" ")
        pull_command = ["docker", "pull", image]
        result = run_os_command(pull_command, shell=False)

        if result.return_code:
            logger.std(result, raise_exception=False)
        else:
            logger.success()
            return True
        return False
Beispiel #7
0
    def build_stage(
        self,
        stage: str = "",
        final_image: bool = False,
        push_images: bool = True,
        disable_cache: bool = settings.BUILDKIT_CACHE_DISABLE,
    ) -> DockerImage:
        logger.info(icon=f"{self.ICON} 🔨", title=f"Building stage '{stage}': ")

        build_command = [
            "docker",
            "buildx",
            "build",
            f"--file={self.dockerfile.absolute()}",
            f"--target={stage}",
            "--progress=plain",
        ]

        build_command.extend(self.get_build_arguments())

        if push_images:
            build_command.append("--push")

        if not disable_cache:
            cache_to = self.create_cache_tag(postfix=stage)
            logger.info(title=f"\t ℹ️ Cache to: {cache_to}")
            build_command.append(
                f"--cache-to=type=registry,ref={cache_to},mode=max")

            for cache_tag in self.get_cache_tags():
                logger.info(title=f"\t ℹ️ Cache from: {cache_tag}")
                build_command.append(
                    f"--cache-from=type=registry,ref={cache_tag}")

        tags = self.get_image_tags(stage, final_image=final_image)

        for tag in tags:
            build_command.append(f"--tag={self.image_repo}:{tag}")

        build_command.append(f"{self.docker_context.absolute()}")

        image = DockerImage(repository=self.image_repo, tags=tags)

        with settings.plugin_manager.lifecycle.container_build_stage(
                image=image, stage=stage):
            result = run_os_command(build_command, shell=False)
            if result.return_code:
                logger.std(result, raise_exception=True)
            else:
                for tag in tags:
                    logger.info(title=f"\t 🏷 Tagged: {self.image_repo}:{tag}")

        return image
Beispiel #8
0
    def add_repo(self, repo_name: str, repo_url: str, update: bool = True) -> None:
        logger.info(
            icon=f"{self.ICON}  âž•",
            title=f"Adding Helm repo {repo_url} with name {repo_name}: ",
            end="",
        )
        result = run_os_command(["helm", "repo", "add", repo_name, repo_url])
        if not result.return_code:
            logger.success()
        else:
            logger.std(result, raise_exception=True)

        if update:
            self.update_repos()
Beispiel #9
0
    def build_stage(self,
                    stage: str = "",
                    final_image: bool = False,
                    push_images: bool = True) -> DockerImage:
        logger.info(icon=f"{self.ICON} 🔨", title=f"Building stage '{stage}': ")

        cache_tags = self.get_cache_tags()
        postfix = stage if not final_image else ""

        build_command = [
            "docker",
            "buildx",
            "build",
            f"--file={self.dockerfile.absolute()}",
            f"--target={stage}",
            "--progress=plain",
        ]

        if push_images:
            build_command.append("--push")

        cache_to = self.create_cache_tag(postfix=postfix)
        logger.info(title=f"\t ℹ️ Cache to: {cache_to}")
        build_command.append(
            f"--cache-to=type=registry,ref={cache_to},mode=max")

        for cache_tag in cache_tags:
            logger.info(title=f"\t ℹ️ Cache from: {cache_tag}")
            build_command.append(f"--cache-from=type=registry,ref={cache_tag}")

        tags = self.get_image_tags(stage, final_image=final_image)

        for tag in tags:
            build_command.append(f"--tag={self.image_repo}:{tag}")

        build_command.append(f"{self.docker_context.absolute()}")

        result = run_os_command(build_command, shell=False)

        if result.return_code:
            logger.std(result, raise_exception=True)
        else:
            for tag in tags:
                logger.info(title=f"\t 🏷 Tagged: {self.image_repo}:{tag}")

        image = DockerImage(repository=self.image_repo, tags=tags)
        return image
Beispiel #10
0
    def setup_buildkit(self, name: str = "kolgabk") -> None:
        setup_command = [
            "docker",
            "buildx",
            "create",
            "--name",
            name,
            "--use",
        ]

        result = run_os_command(setup_command)
        if result.return_code:
            logger.std(result, raise_exception=True)
        else:
            logger.success(
                icon=f"{self.ICON} 🔑",
                message=
                f"New buildx builder instance is set up (Instance name: {name})",
            )
Beispiel #11
0
    def get(
        self,
        resource: str,
        name: Optional[str] = None,
        labels: Optional[Dict[str, str]] = None,
        namespace: str = settings.K8S_NAMESPACE,
        raise_exception: bool = True,
    ) -> SubprocessResult:
        os_command = ["kubectl", "get"]

        logger.info(icon=f"{self.ICON}  ℹ️ ", title=f"Getting {resource}", end="")
        os_command += self._resource_command(
            resource=resource, name=name, labels=labels, namespace=namespace
        )
        logger.info(": ", end="")
        result = run_os_command(os_command, shell=True)  # nosec
        if not result.return_code:
            logger.success()
        else:
            logger.std(result, raise_exception=raise_exception)
        return result
    def logs(
        self,
        labels: Optional[Dict[str, str]] = None,
        since_time: Optional[str] = None,
        namespace: str = settings.K8S_NAMESPACE,
        print_result: bool = True,
        raise_exception: bool = True,
    ) -> SubprocessResult:
        os_command = [
            "kubectl",
            "logs",
            f"--namespace={namespace}",
            "--prefix=true",
            "--timestamps=true",
            "--tail=100",
        ]

        logger.info(icon=f"{self.ICON}  📋️️ ",
                    title="Getting logs for resource: ",
                    end="")

        if labels:
            labels_str = self.labels_to_string(labels)
            os_command += ["-l", labels_str]
            logger.info(title=f" with labels {labels_str}", end="")

        if since_time:
            os_command += [f"--since-time={since_time}"]
            logger.info(title=f" since {since_time}", end="")

        result = run_os_command(os_command, shell=True)
        if not result.return_code:
            logger.success()
            if print_result:
                logger.std(result)
        else:
            logger.std(result, raise_exception=raise_exception)

        return result
Beispiel #13
0
    def login(
        self,
        username: str = settings.CONTAINER_REGISTRY_USER,
        password: str = settings.CONTAINER_REGISTRY_PASSWORD,
        registry: str = settings.CONTAINER_REGISTRY,
    ) -> None:
        login_command = [
            "docker",
            "login",
            "-u",
            username,
            "-p",
            password,
            registry,
        ]

        result = run_os_command(login_command)
        if result.return_code:
            logger.std(result, raise_exception=True)
        else:
            logger.success(
                icon=f"{self.ICON} 🔑",
                message=f"Logged in to registry (User: {username})",
            )
Beispiel #14
0
    def upgrade_chart(
        self,
        name: str,
        values: HelmValues,
        namespace: str,
        chart: str = "",
        chart_path: Optional[Path] = None,
        values_files: Optional[List[Path]] = None,
        install: bool = True,
        version: Optional[str] = None,
        raise_exception: bool = True,
    ) -> SubprocessResult:
        if chart_path:
            if not chart_path.is_absolute():
                chart_path = settings.devops_root_path / chart_path
            if not chart_path.exists():
                logger.error(
                    message=f"Path '{str(chart_path)}' does not exist",
                    error=OSError(),
                    raise_exception=True,
                )
            chart = str(chart_path)

        logger.info(
            icon=f"{self.ICON}  📄",
            title=f"Upgrading chart from '{chart}': ",
            end="",
        )

        replica_timeout_multiplier = 2 if settings.K8S_REPLICACOUNT > 1 else 1
        timeout = (
            (settings.K8S_PROBE_INITIAL_DELAY * replica_timeout_multiplier)
            + (settings.K8S_PROBE_FAILURE_THRESHOLD * settings.K8S_PROBE_PERIOD)
            + 120  # Buffer time
        )

        # Construct initial helm upgrade command
        install_arg = "--install" if install else ""
        helm_command = [
            "helm",
            "upgrade",
            "--atomic",
            "--timeout",
            f"{timeout}s",
            "--history-max",
            "30",
            install_arg,
            "--namespace",
            f"{namespace}",
        ]

        if version:
            helm_command += ["--version", version]

        # Add values files
        if values_files:
            helm_command += self.get_chart_params(flag="--values", values=values_files)

        safe_name = kubernetes_safe_name(name=name)
        values_yaml = yaml.dump(values)

        with NamedTemporaryFile(buffering=0) as fobj:
            fobj.write(values_yaml.encode())
            result = run_os_command(
                [*helm_command, "--values", fobj.name, f"{safe_name}", f"{chart}"],
            )

        if result.return_code:
            logger.std(result, raise_exception=raise_exception)
            return result

        logger.success()
        logger.info(f"\tName: {safe_name} (orig: {name})")
        logger.info(f"\tNamespace: {namespace}")

        return result