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)
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)
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)
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()
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
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
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()
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
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})", )
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
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})", )
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