Package: python3-apt
Version: 3.1.0
Severity: important
Tags: patch
Control: affects -1 software-properties
Control: block 1038747 by -1

Dear Maintainer,

This is the underlying fix for Debian bug #1038747[1]. That bug is currently
filed against software-properties, but the actual defect lives in python3-apt:
aptsources.distro.Distribution.change_server() rewrites *every* child source's
URI onto the newly selected main mirror. On Debian that is wrong for the
security archive, which is a SEPARATE archive (deb.debian.org/debian-security)
rather than a pocket of the main archive (as it is on Ubuntu).

Root cause
----------
In aptsources/distro.py, change_server() does (for child sources):

    if (source.template.base_uri is None
            or source.template.base_uri != source.uri):
        change_server_of_source(source, uri, seen_binary)

This replaces the whole child URI with the main mirror URI. For a Debian
security source the template's base_uri is security.debian.org while the
source URI is deb.debian.org/debian-security; the old guard only skips the
source when base_uri already equals the current URI, so the security source
is moved to <mirror>/debian/<suite>-security, which does not exist.

Result: after changing the download mirror in the "Software & Updates" GUI,
`apt update` fails with

    E: The repository 'https://deb.debian.org/debian bookworm-security
       Release' does not have a Release file.

and the entire security-update channel is disabled. The deb-src counterpart
is affected the same way via the source_code_sources loop.

Fix
---
Introduce an `_archive_root()` helper (host + first path segment) and a
`separate_archive()` predicate that compares the child source's template
base_uri against the main archive's base_uri. Child sources (and their
deb-src siblings) that live on a separate archive are left untouched when the
main download server is changed, while same-archive children such as
*-updates keep following the mirror. Ubuntu behaviour is unchanged because
its -security shares the main archive.

Verification
------------
I reproduced the bug and confirmed the fix on a current Debian sid container
(python3-apt 3.1.0). The attached hermetic test(AI generated) drives
change_server()
directly with an in-memory Debian sid source set (no /etc/apt access, no
network):

  BEFORE (unpatched 3.1.0):
    main         -> http://ftp.hu.debian.org/debian/        (follows mirror, ok)
    security     -> http://ftp.hu.debian.org/debian/        (WRONG:
moved off debian-security)
    security-src -> http://ftp.hu.debian.org/debian/        (WRONG)
    RESULT: FAIL

  AFTER (patched):
    main         -> http://ftp.hu.debian.org/debian/        (follows mirror, ok)
    security     -> http://deb.debian.org/debian-security   (kept)
    security-src -> http://deb.debian.org/debian-security   (kept)
    RESULT: PASS

The patch below applies cleanly to sid's 3.1.0.

Kind regards,
Emfox Zhou

[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1038747

Attachment: fix-1038747-sid-3.1.0.patch
Description: Binary data

Attachment: test-1038747.py
Description: Binary data

Reply via email to