Skip to content

apt2aptly: use dist-scoped, directory-safe upload directory - #72

Open
andrewshadura with Copilot wants to merge 1 commit into
mainfrom
copilot/fix-concurrent-uploads-issue
Open

apt2aptly: use dist-scoped, directory-safe upload directory#72
andrewshadura with Copilot wants to merge 1 commit into
mainfrom
copilot/fix-concurrent-uploads-issue

Conversation

Copilot AI commented Aug 26, 2026

Copy link
Copy Markdown

Concurrent apt2aptly runs all uploaded to /api/files/apt2aptly, causing files from different distributions to collide and land in the wrong repos.

Changes

  • apt2aptly/src/main.rs: Replace the hardcoded "apt2aptly" upload directory with a per-distribution name derived from base_dist(), sanitized to be directory-safe (non-alphanumeric chars except -/_ replaced with -).
// Before
actions.apply("apt2aptly", &upload_opts).await?;

// After — e.g. "apt2aptly-bookworm" or "apt2aptly-v2022-snapshots-20260129T071258Z"
actions.apply(
    &format!(
        "apt2aptly-{}",
        apt_repo.dist.base_dist()
            .replace(|c: char| !c.is_alphanumeric() && c != '-' && c != '_', "-")
    ),
    &upload_opts,
).await?;

base_dist() is used (rather than the full path which includes /snapshots/…) so snapshot runs for the same dist still share a namespace, while different dists are fully isolated.

Copilot AI lite review requested due to automatic review settings August 26, 2026 11:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI linked an issue Aug 26, 2026 that may be closed by this pull request
Copilot AI review requested due to automatic review settings August 26, 2026 11:34
Copilot AI changed the title [WIP] Fix concurrent uploads in apt2aptly to prevent repository conflicts apt2aptly: use dist-scoped, directory-safe upload directory Aug 26, 2026
Copilot AI requested a review from andrewshadura August 26, 2026 11:35
@andrewshadura
andrewshadura requested a review from refi64 August 26, 2026 11:36
@andrewshadura
andrewshadura marked this pull request as ready for review August 26, 2026 11:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread apt2aptly/src/main.rs
Uploading to a shared /api/files/apt2aptly directory caused concurrent
apt2aptly instances (running for different distributions) to interfere
with each other. Fix by using /api/files/apt2aptly-{dist} instead, where
{dist} is the base distribution name with any non-alphanumeric characters
(e.g. /) replaced by - to ensure a valid directory name.

For example, v2022/snapshots/20260129T071258Z becomes
apt2aptly-v2022-snapshots-20260129T071258Z.

Closes: #71

Co-Authored-By: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
@andrewshadura

andrewshadura commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

I was curious whether or not guarding by component might be useful, so I asked DeepWiki:


No: a per-component guard isn't needed, based on how sync_dist actually drives things.

Within a single apt2aptly process, everything is sequential, not concurrent:

  • main calls sync_dist once per snapshot in --apt-snapshots (looped, each awaited in turn), then once more for the base dist, all .await?-ed sequentially — never spawned as parallel tasks.

  • Inside sync_dist, the for component in scanner.components() loop processes each component one at a time, .await-ing actions.apply("apt2aptly-{dist}", ...) fully (including the upload) before moving to the next component.

So for one dist value, the upload directory apt2aptly-{base_dist} is used by one component's apply() call at a time — there's no overlap between components of the same dist within a single process, because there's no concurrency at that level; the max_parallel option only controls parallelism of file uploads within a single apply() call, not across components or dists.

The concurrency problem the patch fixes is specifically separate OS processes running for different distributions (e.g., two cron/CI invocations for v2022 and v2023 at the same time) colliding on the same shared /api/files/apt2aptly directory. Making the directory name include base_dist() addresses exactly that case.

The only scenario where a per-component split could matter is if two separate apt2aptly process invocations were run concurrently for the same dist value (e.g., someone manually races two runs of the same distribution) — that would still collide on apt2aptly-{dist}, since the directory name doesn't include the component. But that's an unusual/probably unsupported invocation pattern (nothing in main.rs suggests concurrent multi-process runs for the same dist are expected), and it's a different problem class (same-dist double-invocation) than what this patch targets (different-dist concurrent invocations). If that's a real concern in your deployment, you'd want to prevent concurrent same-dist runs entirely (e.g., via a lock) rather than adding a component suffix, since even a component-scoped path wouldn't fully protect other shared state like aptly_published_cache or repo/snapshot creation.

@andrewshadura

Copy link
Copy Markdown
Collaborator

I’m now testing this on a test conversion of Apertis. Seems to work so far for one concurrent instance (so no regressions).
Going to start another instance doing a different release to see if that works now.

@emanueleaina

Copy link
Copy Markdown
Collaborator

Why not coming up with a name that is unlikely to collide instead of picking the dist? UUIDv7 so you can easily spot old stale folders?

Maybe having two instances publishing to same dist works, maybe doesn't, but this surely does not work in that case.

@andrewshadura

Copy link
Copy Markdown
Collaborator

Do we need to run multiple instances uploading the same dist?
I mean, yeah, we could do UUID, but are we sure that’s needed?

@emanueleaina

Copy link
Copy Markdown
Collaborator

Do we need to run multiple instances uploading the same dist? I mean, yeah, we could do UUID, but are we sure that’s needed?

It is just that while we are fixing the issue it seems to be appropriate to fix it generally given it is not much more affort than fixing it partially. Let's fix the our side so at some point we may try to see how the rest of aptly copes with multiple concurrent uploads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Concurrent uploads with apt2aptly don’t work

4 participants