Compare commits

...

1 Commits

Author SHA1 Message Date
444f185fc5 Add support for versioned building from tasks 2025-03-19 22:43:19 +03:00

View File

@ -3,6 +3,7 @@
import argparse import argparse
import functools import functools
import json import json
import logging
import re import re
import subprocess import subprocess
import textwrap import textwrap
@ -16,6 +17,8 @@ import tomli
import yaml import yaml
from jinja2 import Template from jinja2 import Template
logger = logging.getLogger(__name__)
ORG_DIR = Path("org") ORG_DIR = Path("org")
PKG_VERSIONS: dict | None = None PKG_VERSIONS: dict | None = None
@ -114,6 +117,25 @@ def api_get_source_package_version(branch: str, package_name: str) -> str:
return result["versions"][0]["version"] return result["versions"][0]["version"]
def api_get_source_package_version_from_task(task_id: str, package_name: str):
api_url = f"https://rdb.altlinux.org/api/task/packages/{task_id}"
response = requests.get(api_url)
if response.status_code != 200:
print(response)
raise RuntimeError(
f"failed to retrieve source package version from task: source package {package_name!r}, branch {branch!r}, task_id {task_id}"
)
result = response.json()
for subtask in result["subtasks"]:
if subtask["source"]["name"] == package_name:
return subtask["source"]["version"]
raise RuntimeError(
f"failed to retrieve source package version from task: source package {package_name!r}, branch {branch!r}, task_id {task_id}"
)
class Tags: class Tags:
def __init__(self, tags_file: str | None, latest: str): def __init__(self, tags_file: str | None, latest: str):
if tags_file is None: if tags_file is None:
@ -122,7 +144,7 @@ class Tags:
self._tags = tomli.loads(Path(tags_file).read_text()) self._tags = tomli.loads(Path(tags_file).read_text())
self._latest = latest self._latest = latest
def tags(self, branch: str, image: Image): def tags(self, branch: str, image: Image, tasks: Tasks | None = None):
if self._tags is None: if self._tags is None:
if image.is_versioned is None: if image.is_versioned is None:
tags = [branch] tags = [branch]
@ -155,7 +177,28 @@ class Tags:
package_name = Template(package_name).render( package_name = Template(package_name).render(
version=PKG_VERSIONS[image.canonical_name] version=PKG_VERSIONS[image.canonical_name]
) )
version = api_get_source_package_version(branch, package_name)
if tasks is not None:
task_ids = tasks.get(branch, image)
else:
task_ids = []
if task_ids:
logger.info(
"getting %s package version from task %s",
package_name,
task_ids[0],
)
version = api_get_source_package_version_from_task(
task_ids[0], package_name
)
else:
logger.info(
"getting %s package version from repo %s",
package_name,
branch,
)
version = api_get_source_package_version(branch, package_name)
if image.version_template is not None: if image.version_template is not None:
version = ( version = (
@ -652,7 +695,7 @@ class DockerBuilder:
self.images_info.skip_arches(image.canonical_name) self.images_info.skip_arches(image.canonical_name)
) )
platforms = ",".join([f"linux/{a}" for a in build_arches]) platforms = ",".join([f"linux/{a}" for a in build_arches])
tags = self.tags.tags(self.branch, image) tags = self.tags.tags(self.branch, image, self.tasks)
manifest = self.render_full_tag(image, tags[0]) manifest = self.render_full_tag(image, tags[0])
msg = "Building image {} for {} arches".format( msg = "Building image {} for {} arches".format(
@ -712,7 +755,7 @@ class DockerBuilder:
if self.images_info.skip_branch(image.canonical_name, self.branch): if self.images_info.skip_branch(image.canonical_name, self.branch):
return return
tags = self.tags.tags(self.branch, image) tags = self.tags.tags(self.branch, image, self.tasks)
manifests = [self.render_full_tag(image, t) for t in tags] manifests = [self.render_full_tag(image, t) for t in tags]
for manifest in manifests: for manifest in manifests:
@ -765,6 +808,8 @@ def parse_args():
images = [f"{o.name}/{i.name}" for o in organizations for i in o.iterdir()] images = [f"{o.name}/{i.name}" for o in organizations for i in o.iterdir()]
organizations = [o.name for o in organizations] organizations = [o.name for o in organizations]
log_levels = ["debug", "info", "warning", "error", "critical"]
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
) )
@ -875,6 +920,12 @@ def parse_args():
type=json.loads, type=json.loads,
help="json string where key is image name, value is the package version", help="json string where key is image name, value is the package version",
) )
parser.add_argument(
"--log-level",
default="warning",
choices=log_levels,
help="log messages above specified level",
)
args = parser.parse_args() args = parser.parse_args()
args.stages = set(args.stages) - set(args.skip_stages) args.stages = set(args.stages) - set(args.skip_stages)
@ -890,6 +941,14 @@ def main():
args = parse_args() args = parse_args()
PKG_VERSIONS = args.package_versions PKG_VERSIONS = args.package_versions
numeric_level = getattr(logging, args.log_level.upper(), logging.WARNING)
logging.basicConfig(
level=numeric_level, format="%(asctime)s - %(levelname)s\t- %(message)s"
)
logger.info("PKG_VERSIONS=%s", PKG_VERSIONS)
arches = args.arches arches = args.arches
images_info = ImagesInfo() images_info = ImagesInfo()
tags = Tags(args.tags, args.latest) tags = Tags(args.tags, args.latest)