<feed xmlns='http://www.w3.org/2005/Atom'>
<title>apt/test, branch 3.1.4</title>
<subtitle>Debians commandline package manager</subtitle>
<id>https://git.kalnischkies.de/apt/atom?h=3.1.4</id>
<link rel='self' href='https://git.kalnischkies.de/apt/atom?h=3.1.4'/>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/'/>
<updated>2025-06-24T16:47:18Z</updated>
<entry>
<title>Fix stuck acquire queues on partial server errors</title>
<updated>2025-06-24T16:47:18Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-24T14:52:06Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=5378c38db0a5dedef34fdf35e357f76c104d717a'/>
<id>urn:sha1:5378c38db0a5dedef34fdf35e357f76c104d717a</id>
<content type='text'>
When a server responds with two InRelease files, but one
is good, and the other indicates a temporary error, we
queued the other indices from the good repository for
downloading and then queued the retry.

The resulting queue ended up with items having fetchAfter=0
before the item with fetchAfter=&lt;something&gt;, causing the
Run() loop to not detect a stuck queue.

Change the order of the queue such that the highest retry-after
items comes first; this ensures that we always see stuck queues.

This of course changes the behavior of retries in that if one
file fails temporarily we block the entire server. This does
seem more beneficial in the common case - if one file fails,
probably all of them fail, and there's no point bombarding
the server with requests for indices from good repositories
until all have failed.

The actual root cause is more that the remaining items are
Enqueued like this:

1. Enqueue jammy/InRelease (delayed)
2. Enqueue jammy-updates/main all Packages

The resulting queue ended up being:

    jammy-updates/main all Packages
    jammy/InRelease (delayed)

But Enqueue() only calls Cycle() when there are no items in
the queue already - after all, any item that is already running
will call Cycle() eventually. Or so was the case until we added
the retry-after handling.

It's unclear why we don't Cycle() all the time when enqueuing
a new item, given that our pipeline might not be filled yet,
and we could send the request to the server while waiting for
data on a running item.

Trying to always Cycle() however led to regressions that still
need investigating. Given that, this solution certainly is the
more easy to reason about one.

LP: #2003851
</content>
</entry>
<entry>
<title>solver3: Filter installed Recommends</title>
<updated>2025-06-10T14:27:36Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T14:09:19Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=b99ec5f1d80962e39e9debb05f1a7c7840e7d97c'/>
<id>urn:sha1:b99ec5f1d80962e39e9debb05f1a7c7840e7d97c</id>
<content type='text'>
When inspecting Recommends of installed packages, filter
them to the installed packages only, as we want to avoid
switching between alternatives of recommended packages.
</content>
</entry>
<entry>
<title>solver3: Ignore Architecture: all for obsoleted-by</title>
<updated>2025-06-10T14:27:36Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T09:47:41Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=15f48dcd65fb17a4cb4cd1f93b872b3bb810c3b2'/>
<id>urn:sha1:15f48dcd65fb17a4cb4cd1f93b872b3bb810c3b2</id>
<content type='text'>
In case a new version of the source package is published, we
check that if there's a newer binary for the same architecture
and then consider the binary obsoleted.

This logic did not properly account for Architecture: all packages
which are considered as native architecture package with an "All"
multi-arch flag set, and hence a native architecture package may
inadvertently be considered obsoleted by a package that only built
on Architecture: all.
</content>
</entry>
<entry>
<title>solver3: Only merge dependencies on the same package</title>
<updated>2025-05-28T11:58:04Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-28T11:57:17Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=3f8162ea008b8a3330a1113a94bc654f05000660'/>
<id>urn:sha1:3f8162ea008b8a3330a1113a94bc654f05000660</id>
<content type='text'>
Avoid or groups and dependencies on different (virtual) packages,
to avoid some common pitfalls like the added xorg test case.
</content>
</entry>
<entry>
<title>solver3: Merge Depends into Recommends</title>
<updated>2025-05-27T14:06:06Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-27T12:24:09Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=86c44166b470ecee5a192ffb434fb7931b7c0afd'/>
<id>urn:sha1:86c44166b470ecee5a192ffb434fb7931b7c0afd</id>
<content type='text'>
Merge any hard clauses into optional clauses, such that
optional clauses don't end up with more choices.

For example if you have

    Depends: a | b
    Recommends: a | c

This becomes:

    Depends: a | b
    Recommends: a

We have simulated this with the chaos-actor in the test case
and a

    Depends: git (not satisfied by chaos provider)
    Recommends: git (satisfied by chaos provider)

and the latter constraint is limited to the former.
</content>
</entry>
<entry>
<title>solver3: Merge intersecting dependencies</title>
<updated>2025-05-27T13:56:55Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-27T12:24:09Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=eafc52e942d4daec30fb80e70c035ed935f31afb'/>
<id>urn:sha1:eafc52e942d4daec30fb80e70c035ed935f31afb</id>
<content type='text'>
If a package declares multiple dependencies that can be solved by
the same packages we should use the common set of packages to
solve them.

A common example is requiring the same Debian source version, or the
same upstream version as in our test case:

    git-ng Depends: git (&gt;&gt; 1:2.26.2), git (&lt;&lt; 1:2.26.2-.)

The solver expands this to the concrete objects:

    git-ng Depends: "real git" (= 1:2.26.2-1) | chaos-actor, "real git" (= 1:2.26.2-1) | "real git" (= 1:2.25.1-1)

When given an upgrade request, the solver would now choose

    chaos-actor               to satisfy git (&gt;&gt; 1:2.26.2)
    "real git" (= 1:2.25.1-1) to satisfy git (&lt;&lt; 1:2.26.2-.)

To satisfy the two constraints, which is not the intended outcome.

Address this problem by introducing a concept of merged clauses:
If two dependencies of a package have overlapping solutions, replace
the dependency by the intersection, and record the merged clause
instead, this leads to a single clause:

    Depends: git (&gt;&gt; 1:2.26.2) and git (&lt;&lt; 1:2.26.2-.)

which expands to just the real git binary.

The implementation is a bit finicky in that it removes the variables
from the original clause which may not be helpful for debugging, but
it records the clauses merged with, as seen in the test case, so the
reasoning is clear.

LP: #2111792
</content>
</entry>
<entry>
<title>solver3: Assume manual packages</title>
<updated>2025-05-26T10:45:12Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-26T09:19:11Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=717ca7922be8a025b8034dc840b2ad9befc3b171'/>
<id>urn:sha1:717ca7922be8a025b8034dc840b2ad9befc3b171</id>
<content type='text'>
If we have allowed the removal of manual packages, assume them
all before starting the solver. This should ensure that as long
as there is a solution that does not remove a manually installed
package, it is found.

This requires a sweeping set of changes in the test suite, but
ensures that we get "safe" behavior from the solver. We have
in particular seen that without asserting the installed packages,
several people ended up with ubuntu-minimal and perl removed in
a situation where that was not warranted, that is, they install
winehq, and then pull in some new perl packages in a newer version
than the installed one, and the solver chose to create a mismatched
version set, which then caused the main perl package to not be
installable.

Oops: 1b55173a-3526-11f0-b7ac-fa163e171f02
Oops: dbd5149e-36b9-11f0-bb74-fa163ec44ecd
</content>
</entry>
<entry>
<title>💬 Recommend use of `apt update` over `apt-get update`</title>
<updated>2025-05-19T16:29:45Z</updated>
<author>
<name>Max Coplan</name>
<email>mchcopl@gmail.com</email>
</author>
<published>2019-11-20T16:03:39Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=d493545484fbb100e559e39618b30a3b3a3526d1'/>
<id>urn:sha1:d493545484fbb100e559e39618b30a3b3a3526d1</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Introduce apt why, apt why-not</title>
<updated>2025-05-19T15:20:09Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-19T12:17:23Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=7724d170751b3dc1717ba7a08881437cf7151996'/>
<id>urn:sha1:7724d170751b3dc1717ba7a08881437cf7151996</id>
<content type='text'>
These are implemented somewhat differently from aptitudes
why and why-not commands: They produce the actual solver
trace for why a particular decision has been taken.

For the why-not case, we need to explicitly discover our
specified package, as if nothing else depends on it in
our graph, it would otherwise always be undiscovered and
conflicts not detected (see e.g. level-3 in the test).
</content>
</entry>
<entry>
<title>Add 'Include'/'Exclude' options to limit packages used from a repository</title>
<updated>2025-05-19T15:19:23Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>julian.klode@canonical.com</email>
</author>
<published>2025-01-29T18:01:06Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=93416f3227685c390c7ab579981efde526134181'/>
<id>urn:sha1:93416f3227685c390c7ab579981efde526134181</id>
<content type='text'>
'Include' allows limiting a repository to a allowlist of packages,
'Exclude' allows removing packages from a repository.

Implementation wise this is not the nicest as it goes via the
IndexTarget options, so we first parse our option value into a
vector, then we turn the vector into a string, and then vectorize
it again. That said, we support both "," and " " as separators due
to the construction (we split by "," then we join using " ").

Gbp-Dch: full
</content>
</entry>
</feed>
