From e8bdc91d3cbc1bdfcf8e53dce1d62fc988a910f5 Mon Sep 17 00:00:00 2001 From: Johannes Starosta Date: Sat, 7 Feb 2026 22:47:30 +0100 Subject: [PATCH] New variable `publish_children` in mirror configuration allows multi-component publishing. See https://www.aptly.info/doc/feature/multi-component/ and README.md for more information. Please note that this works by having one mirror per component, who will get published to the same target location. Using multiple components in one mirror is NOT expected to work. Signed-off-by: Johannes Starosta --- CHANGELOG.md | 5 +++++ README.md | 31 +++++++++++++++++++++++++++++++ files/aptly-mirror-update.py | 35 +++++++++++++++++++++++++++++++++-- templates/mirror.conf.yaml.j2 | 11 +++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6413f9..9559508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# For the next release + + * ** Johannes Starosta** + * New parameter publish_children in mirrors config allows multi-component publishing + # Patch Release v1.1.2 (2026-01-28) * **Johannes Starosta** * Use keyring file instead of apt-key due to deprecation/removal of apt-key in recent Debian and Ubuntu releases diff --git a/README.md b/README.md index d9fd329..a6f6ee8 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,37 @@ aptly__mirrors: - main keys: - url: "" + # Example for multi-component publishing. + # Note: Set only one component per repository see https://www.aptly.info/doc/feature/multi-component/ + # Specifying multiple components is not expected to work + - name: openvox-noble + publish_prefix: openvox + no_block_mirror_task: true + origin: Vox Pupuli + label: openvox-ubuntu24.04 + distribution: ubuntu24.04 + publish_children: true + childrens: + - name: openvox7 + distribution: ubuntu24.04 + archive_url: https://apt.voxpupuli.org/ + state: present + components: + - openvox7 + architectures: + - amd64 + keys: + - url: https://apt.voxpupuli.org/openvox-keyring.gpg + - name: openvox8 + distribution: ubuntu24.04 + archive_url: https://apt.voxpupuli.org/ + state: present + components: + - openvox8 + architectures: + - amd64 + keys: + - url: https://apt.voxpupuli.org/openvox-keyring.gpg aptly__repositories: - name: jammy diff --git a/files/aptly-mirror-update.py b/files/aptly-mirror-update.py index 549f61f..d50e08e 100644 --- a/files/aptly-mirror-update.py +++ b/files/aptly-mirror-update.py @@ -274,6 +274,27 @@ def get_arguments(): return parser.parse_args() +def publish_multi(client, sources, mirror_config, async_run: bool): + publish = Publish(client) + distribution = mirror_config.get("mirror_distribution") + prefix = mirror_config.get("mirror_prefix") + if publish.check_if_exists(name=distribution, prefix=prefix): + publish.switch_snapshot( + snapshots=sources, + prefix=prefix, + distribution=distribution, + async_run=async_run, + ) + else: + publish.create_from_snapshot( + sources=sources, + distribution=distribution, + origin=mirror_config.get("mirror_origin"), + label=mirror_config.get("mirror_label"), + prefix=prefix, + async_run=async_run, + ) + def publish_mirror(client, mirror_name, mirror_config, current_day, async_run: bool): publish = Publish(client) distribution = mirror_config.get("mirror_distribution") @@ -297,6 +318,7 @@ def publish_mirror(client, mirror_name, mirror_config, current_day, async_run: b distribution=distribution, async_run=async_run, ) + else: publish.create_from_snapshot( sources=[{"Name": f"{mirror_name}-{current_day}"}], @@ -307,7 +329,6 @@ def publish_mirror(client, mirror_name, mirror_config, current_day, async_run: b async_run=async_run, ) - def mirror_update_and_snapshot(client, mirror_name, current_day, async_run: bool): mirror = Mirror(client=client, mirror=mirror_name) mirror.update(async_run=async_run) @@ -353,6 +374,7 @@ def main(): mirror_config = yaml.safe_load(stream) if mirror_config.get("mirror_childrens"): + sources = [] for children_mirror_name in mirror_config.get("mirror_childrens"): with open(f"/etc/aptly/mirror/{children_mirror_name}.conf.yaml") as stream: children_mirror_config = yaml.safe_load(stream) @@ -360,6 +382,12 @@ def main(): raise ValueError( f"Children mirror {children_mirror_name} is not the parent of {mirror_name}" ) + components = '' + source = '' + if children_mirror_config.get("mirror_components"): + components = ','.join(children_mirror_config.get('mirror_components')) + source = { "Name": f"{children_mirror_name}-{current_day}", "Component": components } + sources.append(source) mirror_update_and_snapshot( client, children_mirror_name, current_day, mirror_async @@ -383,7 +411,10 @@ def main(): parent_snapshot.merge(snapshots=snapshots, package_refs=packages) print("Switch publish to new snapshot") - publish_mirror(client, mirror_name, mirror_config, current_day, mirror_async) + if mirror_config.get("publish_children"): + publish_multi(client, sources, mirror_config, mirror_async) + else: + publish_mirror(client, mirror_name, mirror_config, current_day, mirror_async) print("Delete all old snapshots") old_snapshot = Snapshot(client, f"{parent_snapshot_name}-old") diff --git a/templates/mirror.conf.yaml.j2 b/templates/mirror.conf.yaml.j2 index 9c23598..817372a 100644 --- a/templates/mirror.conf.yaml.j2 +++ b/templates/mirror.conf.yaml.j2 @@ -4,6 +4,9 @@ {% if mirror_children is defined and mirror_children %} mirror_parent: '{{ aptly__mirror_base.name }}' {% endif %} +{% if aptly__mirror_base.publish_children is defined and publish_children is not defined %} +publish_children: true +{% endif %} {% if aptly__mirror_base.childrens is defined and mirror_children is not defined %} mirror_childrens: {% for children in aptly__mirror.childrens %} @@ -12,6 +15,14 @@ mirror_childrens: {% endif %} {% endfor %} {% endif %} + +{% if aptly__mirror.components is defined and mirror_components is not defined %} +mirror_components: +{% for component in aptly__mirror.components %} + - '{{ component }}' +{% endfor %} +{% endif %} + mirror_distribution: '{{ aptly__mirror.distribution }}' {% if aptly__mirror_base.label is defined and aptly__mirror_base.label | length > 0 %} mirror_label: '{{ aptly__mirror_base.label }}'