Compare commits
	
		
			14 Commits
		
	
	
		
			workflow
			...
			refactor-i
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9e9f57957e | |||
| d9e501ccda | |||
| 0e335ff425 | |||
| fd353cabb1 | |||
| d9dc8a94b7 | |||
| 424c8b3927 | |||
| 6ee75efc93 | |||
| 05707d938c | |||
| 13f9a20369 | |||
| 92ebc2f9d2 | |||
| 955edbf714 | |||
| db15411d60 | |||
| 1113beba96 | |||
| 3bffb21c84 | 
							
								
								
									
										17
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,5 +1,22 @@ | ||||
| # image-forge | ||||
|  | ||||
| ## Wrapper | ||||
|  | ||||
| ### Examples | ||||
|  | ||||
| From the repository | ||||
|  | ||||
| ```shell | ||||
| image-build -b sisyphus -r registry.altlinux.org --prefix=k8s-sisyphus kube-apiserver kubernetes1.28 | ||||
| ``` | ||||
|  | ||||
| From a task | ||||
|  | ||||
| ```shell | ||||
| image-build -b sisyphus -r test.registry.altlinux.org -t 335250 --prefix=k8s-sisyphus kube-apiserver kubernetes1.28 | ||||
| ``` | ||||
|  | ||||
|  | ||||
| ## alt images | ||||
| To build `alt` images, run: | ||||
| ```bash | ||||
|   | ||||
							
								
								
									
										9
									
								
								build.py
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								build.py
									
									
									
									
									
								
							| @@ -15,6 +15,7 @@ from jinja2 import Template | ||||
|  | ||||
| ORG_DIR = Path("org") | ||||
|  | ||||
| PKG_VERSION: str = "" | ||||
|  | ||||
| class Image: | ||||
|     def __init__(self, canonical_name): | ||||
| @@ -578,6 +579,7 @@ class DockerBuilder: | ||||
|             "--force-rm", | ||||
|             f"--manifest={manifest}", | ||||
|             f"--platform={platforms}", | ||||
|             f'--build-arg=PKG_VERSION={PKG_VERSION}', | ||||
|             ".", | ||||
|         ] | ||||
|         self.run(build_cmd, cwd=image.path) | ||||
| @@ -749,6 +751,10 @@ def parse_args(): | ||||
|         choices=stages, | ||||
|         help="list of stages to skip", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--package-version", | ||||
|         help="from which package to build", | ||||
|     ) | ||||
|     args = parser.parse_args() | ||||
|  | ||||
|     args.stages = set(args.stages) - set(args.skip_stages) | ||||
| @@ -760,7 +766,10 @@ def parse_args(): | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     global PKG_VERSION | ||||
|  | ||||
|     args = parse_args() | ||||
|     PKG_VERSION = args.package_version | ||||
|     arches = args.arches | ||||
|     images_info = ImagesInfo() | ||||
|     tags = Tags(args.tags, args.latest) | ||||
|   | ||||
							
								
								
									
										7
									
								
								image-build.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								image-build.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| ## Examples | ||||
|  | ||||
| Build `kube-apisever` image from package `kubernetes1.31`: | ||||
|  | ||||
| ```bash | ||||
| ./image-build.py -b sisyphus -r registry.altlinux.org kube-apiserver kubernetes1.31 | ||||
| ``` | ||||
							
								
								
									
										234
									
								
								image-build.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										234
									
								
								image-build.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,234 @@ | ||||
| #!/usr/bin/env python3 | ||||
|  | ||||
| import argparse | ||||
| import logging | ||||
| import re | ||||
| import subprocess | ||||
| from pathlib import Path | ||||
|  | ||||
| import requests | ||||
|  | ||||
| LOGGING_FORMAT = "%(asctime)s %(name)s %(levelname)s %(message)s" | ||||
| logging.basicConfig(format=LOGGING_FORMAT) | ||||
| logger = logging.getLogger(__name__) | ||||
|  | ||||
|  | ||||
| def parse_args() -> argparse.Namespace: | ||||
|     parser = argparse.ArgumentParser( | ||||
|         description="build an OCI image from a package", | ||||
|         epilog="""The image is only pushed to the destination registry | ||||
|         if the option --push is present.""", | ||||
|         formatter_class=argparse.ArgumentDefaultsHelpFormatter, | ||||
|     ) | ||||
|  | ||||
|     parser.add_argument("image_name") | ||||
|     parser.add_argument("package_name") | ||||
|     parser.add_argument( | ||||
|         "-b", | ||||
|         "--branch", | ||||
|         default="sisyphus", | ||||
|         help="package repository branch", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "-r", | ||||
|         "--registry", | ||||
|         default="registry.altlinux.org", | ||||
|         help="OCI destination registry", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "-t", | ||||
|         "--task-id", | ||||
|         help="install the package from the task with this id", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--prefix", | ||||
|         help="image name prefix", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--dry-run", | ||||
|         action="store_true", | ||||
|         help="only print what would be done", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--latest", | ||||
|         action="store_true", | ||||
|         help="also tag this image as latest", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--push", | ||||
|         action="store_true", | ||||
|         help="push the image to the registry after build", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--skip-build", | ||||
|         action="store_true", | ||||
|         help="if push is true, then skip the build stage", | ||||
|     ) | ||||
|     parser.add_argument( | ||||
|         "--log-level", | ||||
|         choices=["debug", "info", "warning"], | ||||
|         default="warning", | ||||
|         help="logging level", | ||||
|     ) | ||||
|  | ||||
|     return parser.parse_args() | ||||
|  | ||||
|  | ||||
| def api_get_source_package_version(branch: str, package_name: str) -> str: | ||||
|     api_url = "https://rdb.altlinux.org/api/site/package_versions_from_tasks" | ||||
|     params = {"branch": branch, "name": package_name} | ||||
|     response = requests.get(api_url, params) | ||||
|     if response.status_code != 200: | ||||
|         raise RuntimeError( | ||||
|             f"failed to retrieve package version: package {package_name!r}, branch {branch!r} " | ||||
|         ) | ||||
|  | ||||
|     result = response.json() | ||||
|  | ||||
|     logger.debug("api/site/package_versions_from_tasks response=%s", result) | ||||
|  | ||||
|     return result["versions"][0]["version"] | ||||
|  | ||||
|  | ||||
| def api_get_source_package_version_from_task(task_id: int, package_name: str) -> str: | ||||
|     api_url = f"https://rdb.altlinux.org/api/task/packages/{task_id}" | ||||
|     response = requests.get(api_url) | ||||
|     if response.status_code != 200: | ||||
|         raise RuntimeError(f"failed to retrieve information about task {task_id}") | ||||
|  | ||||
|     result = response.json() | ||||
|  | ||||
|     logger.debug("api/task/packages/%s response=%s", task_id, result) | ||||
|  | ||||
|     for subtask in result["subtasks"]: | ||||
|         if subtask["source"]["name"] == package_name: | ||||
|             return subtask["source"]["version"] | ||||
|  | ||||
|     raise RuntimeError( | ||||
|         f"vailed to retrieve version of package {package_name!r} from task {task_id}" | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def main() -> None: | ||||
|     args = parse_args() | ||||
|     logger.setLevel(args.log_level.upper()) | ||||
|  | ||||
|     image = f"k8s/{args.image_name}" | ||||
|     version_arg = None | ||||
|     tasks_file = None | ||||
|  | ||||
|     if args.task_id is None: | ||||
|         version = api_get_source_package_version(args.branch, args.package_name) | ||||
|     else: | ||||
|         version = api_get_source_package_version_from_task( | ||||
|             args.task_id, args.package_name | ||||
|         ) | ||||
|         tasks_file = "/tmp/k8s-tasks.toml" | ||||
|         tasks_file_contents = f"['{args.branch}']\n" | ||||
|         tasks_file_contents += f"{args.task_id} = ['{image}']\n" | ||||
|         Path(tasks_file).write_text(tasks_file_contents) | ||||
|  | ||||
|     tags_file = "/tmp/k8s-tags.toml" | ||||
|     tags_file_contents = f"['{image}']\n" | ||||
|  | ||||
|     match args.image_name: | ||||
|         case ( | ||||
|             "etcd" | ||||
|             | "flannel" | ||||
|             | "flannel-cni-plugin" | ||||
|             | "pause" | ||||
|             | "cert-manager-acmesolver" | ||||
|             | "cert-manager-cainjector" | ||||
|             | "cert-manager-controller" | ||||
|             | "cert-manager-startupapicheck" | ||||
|             | "cert-manager-webhook" | ||||
|         ): | ||||
|             match args.image_name: | ||||
|                 case "flannel-cni-plugin": | ||||
|                     num_dots = version.count(".") | ||||
|                     if num_dots == 2: | ||||
|                         tags_file_contents += ( | ||||
|                             f"{args.branch} = ['v{version}-flannel1']\n" | ||||
|                         ) | ||||
|                     elif num_dots == 3: | ||||
|                         flannel_version, flannel_release = version.rsplit(".", 1) | ||||
|                         tags_file_contents += f"{args.branch} = ['v{flannel_version}-flannel{flannel_release}']\n" | ||||
|                     else: | ||||
|                         raise RuntimeError( | ||||
|                             f"wrong version for package {args.package_name!r}, version {version!r}" | ||||
|                         ) | ||||
|                 case "etcd": | ||||
|                     tags_file_contents += f"{args.branch} = ['{version}-0']\n" | ||||
|                 case "pause": | ||||
|                     tags_file_contents += f"{args.branch} = ['{version}']\n" | ||||
|                 case _: | ||||
|                     tags_file_contents += f"{args.branch} = ['v{version}']\n" | ||||
|  | ||||
|         case ( | ||||
|             "kube-apiserver" | ||||
|             | "kube-controller-manager" | ||||
|             | "kube-scheduler" | ||||
|             | "kube-proxy" | ||||
|             | "coredns" | ||||
|         ): | ||||
|             match args.image_name: | ||||
|                 case "coredns": | ||||
|                     regex_string = "coredns(.+)" | ||||
|                 case ( | ||||
|                     "kube-apiserver" | ||||
|                     | "kube-controller-manager" | ||||
|                     | "kube-scheduler" | ||||
|                     | "kube-proxy" | ||||
|                 ): | ||||
|                     regex_string = "kubernetes(.+)" | ||||
|  | ||||
|             version_match = re.search(regex_string, args.package_name) | ||||
|             if version_match is None: | ||||
|                 raise RuntimeError( | ||||
|                     f"failed to retrieve version argument from package name: package {args.package_name!r}" | ||||
|                 ) | ||||
|  | ||||
|             version_arg = version_match.group(1) | ||||
|  | ||||
|             tags_file = "/tmp/k8s-tags.toml" | ||||
|             tags_file_contents = f"['{image}']\n" | ||||
|             tags_file_contents += f"{args.branch} = ['v{version}']\n" | ||||
|         case _: | ||||
|             raise RuntimeError(f"unknown image {args.image_name!r}") | ||||
|  | ||||
|     Path(tags_file).write_text(tags_file_contents) | ||||
|  | ||||
|     command = [ | ||||
|         "./build.py", | ||||
|         f"--branch={args.branch}", | ||||
|         f"--registry={args.registry}", | ||||
|         f"--image={image}", | ||||
|         f"--tags={tags_file}", | ||||
|     ] | ||||
|  | ||||
|     if tasks_file is not None: | ||||
|         command.append(f"--tasks={tasks_file}") | ||||
|  | ||||
|     if version_arg is not None: | ||||
|         command.append(f"--package-version={version_arg}") | ||||
|  | ||||
|     if args.prefix is not None: | ||||
|         command.append(f"--overwrite-organization={args.prefix}") | ||||
|  | ||||
|     if args.latest: | ||||
|         command.append(f"--latest={args.branch}") | ||||
|  | ||||
|     if not args.push: | ||||
|         command.append("--skip-stages=push") | ||||
|     elif args.skip_build: | ||||
|         command.append("--stages=push") | ||||
|  | ||||
|     if args.dry_run: | ||||
|         command.append("--dry-run") | ||||
|  | ||||
|     logger.debug("Running command: %s", command) | ||||
|     subprocess.run(command, check=True) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
| @@ -8,6 +8,8 @@ LABEL org.opencontainers.image.source="https://github.com/coredns/coredns" | ||||
| LABEL org.opencontainers.image.licenses="Apache-2.0" | ||||
| LABEL org.opencontainers.image.vendor="ALT Linux Team" | ||||
|  | ||||
| {{ install_packages("coredns") }} | ||||
| ARG PKG_VERSION | ||||
|  | ||||
| {{ install_packages("coredns${PKG_VERSION}") }} | ||||
|  | ||||
| ENTRYPOINT ["/usr/bin/coredns"] | ||||
|   | ||||
| @@ -8,6 +8,8 @@ LABEL org.opencontainers.image.source="https://github.com/kubernetes/kubernetes" | ||||
| LABEL org.opencontainers.image.licenses="Apache-2.0" | ||||
| LABEL org.opencontainers.image.vendor="ALT Linux Team" | ||||
|  | ||||
| {{ install_packages("kubernetes-master") }} | ||||
| ARG PKG_VERSION | ||||
|  | ||||
| {{ install_packages("kubernetes${PKG_VERSION}-master") }} | ||||
|  | ||||
| ENTRYPOINT ["/usr/bin/kube-apiserver"] | ||||
|   | ||||
| @@ -8,6 +8,8 @@ LABEL org.opencontainers.image.source="https://github.com/kubernetes/kubernetes" | ||||
| LABEL org.opencontainers.image.licenses="Apache-2.0" | ||||
| LABEL org.opencontainers.image.vendor="ALT Linux Team" | ||||
|  | ||||
| {{ install_packages("kubernetes-master") }} | ||||
| ARG PKG_VERSION | ||||
|  | ||||
| {{ install_packages("kubernetes${PKG_VERSION}-master") }} | ||||
|  | ||||
| ENTRYPOINT ["/usr/bin/kube-controller-manager"] | ||||
|   | ||||
| @@ -8,7 +8,9 @@ LABEL org.opencontainers.image.source="https://github.com/kubernetes/kubernetes" | ||||
| LABEL org.opencontainers.image.licenses="Apache-2.0" | ||||
| LABEL org.opencontainers.image.vendor="ALT Linux Team" | ||||
|  | ||||
| {{ install_packages("kubernetes-node") }} | ||||
| ARG PKG_VERSION | ||||
|  | ||||
| {{ install_packages("kubernetes${PKG_VERSION}-node") }} | ||||
|  | ||||
| RUN ln -s /usr/bin/kube-proxy /usr/local/bin/kube-proxy | ||||
|  | ||||
|   | ||||
| @@ -8,6 +8,8 @@ LABEL org.opencontainers.image.source="https://github.com/kubernetes/kubernetes" | ||||
| LABEL org.opencontainers.image.licenses="Apache-2.0" | ||||
| LABEL org.opencontainers.image.vendor="ALT Linux Team" | ||||
|  | ||||
| {{ install_packages("kubernetes-master") }} | ||||
| ARG PKG_VERSION | ||||
|  | ||||
| {{ install_packages("kubernetes${PKG_VERSION}-master") }} | ||||
|  | ||||
| ENTRYPOINT ["/usr/bin/kube-scheduler"] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user