Discussion:
Bug#1086801: apt: autoremove fails to remove garbage packages with unrelated Suggests links
Add Reply
Aaron Rainbolt
2024-11-06 08:10:01 UTC
Reply
Permalink
Package: apt
Version: 2.9.10
Severity: normal
X-Debbugs-Cc: ***@kicksecure.com, ***@gmail.com

Suppose a user wants to install package `foo`. `foo` recommends `bar`.
The user already has an unrelated package `frazzle` installed, which
suggests `bar`. When the user installs `foo`, `bar` will be
automatically pulled in due to the Recommends link. If the user later
uninstalls `foo`, `bar` should become autoremovable, because nothing
has a hard or even strong dependency on `bar` any longer and `bar`
wasn't installed because of `frazzle`. However, because `frazzle`
suggests `bar`, this will not happen
- `bar` will remain on the system until manually uninstalled.

Steps to reproduce:

1. Ensure `git` is installed by running `sudo apt install git`.
2. Create a testing metapackage called `test-meta`, which recommends
`gitk`. My source package tree looks like this:

test-meta (dir)
|
-> debian (dir)
|
-> changelog (file)
-> control (file)
-> rules (file)
-> source (dir)
|
-> format (file)

test-meta/debian/changelog:

test-meta (1.0) unstable; urgency=medium

* Test build

-- Aaron Rainbolt <***@ubuntu.com> Wed, 06 Nov 2024
00:36:00 +0500

test-meta/debian/control:

Source: test-meta
Section: metapackages
Priority: optional
Maintainer: Aaron Rainbolt <***@ubuntu.com>
Build-Depends: debhelper (>= 13), debhelper-compat (= 13)
Standards-Version: 4.6.2
Rules-Requires-Root: no

Package: test-meta
Architecture: all
Depends: ${misc:Depends}
Recommends: gitk
Description: Test metapackage
This is a test metapackage.
.
Yep, that's what this is.

test-meta/debian/rules

#!/usr/bin/make -f

#export DH_VERBOSE=1

%:
dh $@

test-meta/debian/source/format:

3.0 (native)

3. Build the package. (I used sbuild for this, dpkg-buildpackage will
almost certainly work fine though.)
4. Install the package with `sudo apt install ./test-meta_1.0_all.deb`.
5. Purge the package with `sudo apt purge test-meta`.
6. Run `sudo apt autopurge`.

Expected result: `gitk` should be removed during the autopurge step.

Actual result: Only the test-meta package is removed.

Additional info: `gitk` is suggested by `git`. I believe this is what's
causing the problem - apt sees the Suggests link and refuses to remove
`gitk`, even though `gitk` isn't installed because of `git`.

Terminal output from me running the following commands, in order:

* sudo apt install git
* sudo apt install ./test-meta_1.0_all.deb
* aptitude why gitk
* apt list --installed | grep gitk
* sudo apt purge test-meta
* aptitude why gitk
* apt list --installed | grep gitk

***@apttest:~/Public/kicksecure/git$ sudo apt install git
git is already the newest version (1:2.45.2-1.1).
Summary:
Upgrading: 0, Installing: 0, Removing: 0, Not Upgrading: 0
***@apttest:~/Public/kicksecure/git$ sudo apt install
./test-meta_1.0_all.deb Note, selecting 'test-meta' instead of
'./test-meta_1.0_all.deb' Installing:
test-meta

Installing dependencies:
gitk libtcl8.6 libtk8.6 tcl tcl8.6 tk tk8.6

Suggested packages:
git-doc tcl-tclreadline

Summary:
Upgrading: 0, Installing: 8, Removing: 0, Not Upgrading: 0
Download size: 3,208 kB / 3,210 kB
Space needed: 9,144 kB / 26.0 GB available

Continue? [Y/n] y
Get:1 /home/user/Public/kicksecure/git/test-meta_1.0_all.deb
test-meta all 1.0 [1,072 B]
Get:2 http://deb.debian.org/debian sid/main amd64 libtcl8.6 amd64 8.6.15+dfsg-2 [1,042 kB] Get:3 http://deb.debian.org/debian sid/main amd64 libtk8.6 amd64 8.6.15-1 [791 kB]
Get:4 http://deb.debian.org/debian sid/main amd64 tk8.6 amd64 8.6.15-1 [69.6 kB]
Get:5 http://deb.debian.org/debian sid/main amd64 tcl8.6 amd64 8.6.15+dfsg-2 [120 kB]
Get:6 http://deb.debian.org/debian sid/main amd64 tcl amd64 8.6.14 [4,032 B]
Get:7 http://deb.debian.org/debian sid/main amd64 tk amd64 8.6.14 [4,076 B]
Get:8 http://deb.debian.org/debian sid/main amd64 gitk all 1:2.45.2-1.1 [1,177 kB]
Fetched 3,208 kB in 1s (2,608 kB/s)
Selecting previously unselected package libtcl8.6:amd64.
(Reading database ... 108537 files and directories currently
installed.) Preparing to unpack
.../0-libtcl8.6_8.6.15+dfsg-2_amd64.deb ... Unpacking
libtcl8.6:amd64 (8.6.15+dfsg-2) ... Selecting previously unselected
package libtk8.6:amd64. Preparing to unpack
.../1-libtk8.6_8.6.15-1_amd64.deb ... Unpacking libtk8.6:amd64
(8.6.15-1) ... Selecting previously unselected package tk8.6.
Preparing to unpack .../2-tk8.6_8.6.15-1_amd64.deb ...
Unpacking tk8.6 (8.6.15-1) ...
Selecting previously unselected package tcl8.6.
Preparing to unpack .../3-tcl8.6_8.6.15+dfsg-2_amd64.deb ...
Unpacking tcl8.6 (8.6.15+dfsg-2) ...
Selecting previously unselected package tcl.
Preparing to unpack .../4-tcl_8.6.14_amd64.deb ...
Unpacking tcl (8.6.14) ...
Selecting previously unselected package tk.
Preparing to unpack .../5-tk_8.6.14_amd64.deb ...
Unpacking tk (8.6.14) ...
Selecting previously unselected package gitk.
Preparing to unpack .../6-gitk_1%3a2.45.2-1.1_all.deb ...
Unpacking gitk (1:2.45.2-1.1) ...
Selecting previously unselected package test-meta.
Preparing to unpack .../7-test-meta_1.0_all.deb ...
Unpacking test-meta (1.0) ...
Setting up test-meta (1.0) ...
Setting up libtcl8.6:amd64 (8.6.15+dfsg-2) ...
Setting up tcl8.6 (8.6.15+dfsg-2) ...
Setting up libtk8.6:amd64 (8.6.15-1) ...
Setting up tcl (8.6.14) ...
Setting up tk8.6 (8.6.15-1) ...
Setting up tk (8.6.14) ...
Setting up gitk (1:2.45.2-1.1) ...
Processing triggers for man-db (2.13.0-1) ...
Processing triggers for libc-bin (2.40-3) ...
Notice: Download is performed unsandboxed as root as file
'/home/user/Public/kicksecure/git/test-meta_1.0_all.deb' couldn't
be accessed by user '_apt'. - pkgAcquire::Run (13: Permission
denied) ***@apttest:~/Public/kicksecure/git$ aptitude why gitk i
test-meta Recommends gitk ***@apttest:~/Public/kicksecure/git$ apt
list --installed | grep gitk

WARNING: apt does not have a stable CLI interface. Use with caution
in scripts.

gitk/unstable,now 1:2.45.2-1.1 all [installed,automatic]
***@apttest:~/Public/kicksecure/git$ sudo apt purge test-meta
REMOVING:
test-meta*

Summary:
Upgrading: 0, Installing: 0, Removing: 1, Not Upgrading: 0
Freed space: 7,168 B

Continue? [Y/n] y
(Reading database ... 108937 files and directories currently
installed.) Removing test-meta (1.0) ...
***@apttest:~/Public/kicksecure/git$ aptitude why gitk
i git Suggests gitk
***@apttest:~/Public/kicksecure/git$ apt list --installed | grep
gitk

WARNING: apt does not have a stable CLI interface. Use with caution
in scripts.

gitk/unstable,now 1:2.45.2-1.1 all [installed,automatic]

I'm not entirely sure if this is something that can be or even should be
solved. Assuming I'm right about the cause of the issue here, what's
happening is that apt sees that the package is referenced by another
package in a dependency relationship, and so refuses to autoremove it
since it *could* have been installed by doing something along the lines
of `sudo apt install --install-suggests git`. However, given the
purpose of the Suggests field, this does not seem like correct behavior
to me. If a package is not installed because of a particular Suggests
link, it should not be retained because of that particular Suggests
link.

Assuming this is something that should be solved, it seems to me like
there would need to be some way of identifying *which* package (or
packages) were installed that ended up pulling in a particular other
package as a Suggests because of APT::Install-Suggests. That way apt
could decide whether the Suggests link should be ignored, or if it
should be taken into account when determining which packages are
autoremovable. The question then is if this would require changes to
tools beyond apt to implement.


-- Package-specific info:

-- apt-config dump --

APT "";
APT::Architecture "amd64";
APT::Build-Essential "";
APT::Build-Essential:: "build-essential";
APT::Install-Recommends "1";
APT::Install-Suggests "0";
APT::Key "";
APT::Key::Assert-Pubkey-Algo
">=rsa2048,ed25519,ed448,nistp256,nistp384,nistp512,brainpoolP256r1,brainpoolP320r1,brainpoolP384r1,brainpoolP512r1,secp256k1";
APT::Key::Assert-Pubkey-Algo::Next
">=rsa2048,ed25519,ed448,nistp256,nistp384,nistp512";
APT::Key::Assert-Pubkey-Algo::Future ">=rsa3072,ed25519,ed448";
APT::Sandbox ""; APT::Sandbox::User "_apt"; APT::Authentication "";
APT::Authentication::TrustCDROM "true";
APT::NeverAutoRemove "";
APT::NeverAutoRemove:: "^firmware-linux.*";
APT::NeverAutoRemove:: "^linux-firmware$";
APT::NeverAutoRemove:: "^linux-image-[a-z0-9]*$";
APT::NeverAutoRemove:: "^linux-image-[a-z0-9]*-[a-z0-9]*$";
APT::VersionedKernelPackages "";
APT::VersionedKernelPackages:: "linux-.*";
APT::VersionedKernelPackages:: "kfreebsd-.*";
APT::VersionedKernelPackages:: "gnumach-.*";
APT::VersionedKernelPackages:: ".*-modules";
APT::VersionedKernelPackages:: ".*-kernel";
APT::Never-MarkAuto-Sections "";
APT::Never-MarkAuto-Sections:: "metapackages";
APT::Never-MarkAuto-Sections:: "tasks";
APT::Move-Autobit-Sections "";
APT::Move-Autobit-Sections:: "oldlibs";
APT::Architectures "";
APT::Architectures:: "amd64";
APT::Compressor "";
APT::Compressor::. "";
APT::Compressor::.::Name ".";
APT::Compressor::.::Extension "";
APT::Compressor::.::Binary "";
APT::Compressor::.::Cost "0";
APT::Compressor::zstd "";
APT::Compressor::zstd::Name "zstd";
APT::Compressor::zstd::Extension ".zst";
APT::Compressor::zstd::Binary "zstd";
APT::Compressor::zstd::Cost "60";
APT::Compressor::zstd::CompressArg "";
APT::Compressor::zstd::CompressArg:: "-19";
APT::Compressor::zstd::UncompressArg "";
APT::Compressor::zstd::UncompressArg:: "-d";
APT::Compressor::lz4 "";
APT::Compressor::lz4::Name "lz4";
APT::Compressor::lz4::Extension ".lz4";
APT::Compressor::lz4::Binary "false";
APT::Compressor::lz4::Cost "50";
APT::Compressor::gzip "";
APT::Compressor::gzip::Name "gzip";
APT::Compressor::gzip::Extension ".gz";
APT::Compressor::gzip::Binary "gzip";
APT::Compressor::gzip::Cost "100";
APT::Compressor::gzip::CompressArg "";
APT::Compressor::gzip::CompressArg:: "-6n";
APT::Compressor::gzip::UncompressArg "";
APT::Compressor::gzip::UncompressArg:: "-d";
APT::Compressor::xz "";
APT::Compressor::xz::Name "xz";
APT::Compressor::xz::Extension ".xz";
APT::Compressor::xz::Binary "xz";
APT::Compressor::xz::Cost "200";
APT::Compressor::xz::CompressArg "";
APT::Compressor::xz::CompressArg:: "-6";
APT::Compressor::xz::UncompressArg "";
APT::Compressor::xz::UncompressArg:: "-d";
APT::Compressor::bzip2 "";
APT::Compressor::bzip2::Name "bzip2";
APT::Compressor::bzip2::Extension ".bz2";
APT::Compressor::bzip2::Binary "bzip2";
APT::Compressor::bzip2::Cost "300";
APT::Compressor::bzip2::CompressArg "";
APT::Compressor::bzip2::CompressArg:: "-6";
APT::Compressor::bzip2::UncompressArg "";
APT::Compressor::bzip2::UncompressArg:: "-d";
APT::Compressor::lzma "";
APT::Compressor::lzma::Name "lzma";
APT::Compressor::lzma::Extension ".lzma";
APT::Compressor::lzma::Binary "xz";
APT::Compressor::lzma::Cost "400";
APT::Compressor::lzma::CompressArg "";
APT::Compressor::lzma::CompressArg:: "--format=lzma";
APT::Compressor::lzma::CompressArg:: "-6";
APT::Compressor::lzma::UncompressArg "";
APT::Compressor::lzma::UncompressArg:: "--format=lzma";
APT::Compressor::lzma::UncompressArg:: "-d";
Dir "/";
Dir::State "var/lib/apt";
Dir::State::lists "lists/";
Dir::State::cdroms "cdroms.list";
Dir::State::extended_states "extended_states";
Dir::State::status "/var/lib/dpkg/status";
Dir::Cache "var/cache/apt";
Dir::Cache::archives "archives/";
Dir::Cache::srcpkgcache "srcpkgcache.bin";
Dir::Cache::pkgcache "pkgcache.bin";
Dir::Etc "etc/apt";
Dir::Etc::sourcelist "sources.list";
Dir::Etc::sourceparts "sources.list.d";
Dir::Etc::main "apt.conf";
Dir::Etc::netrc "auth.conf";
Dir::Etc::netrcparts "auth.conf.d";
Dir::Etc::parts "apt.conf.d";
Dir::Etc::preferences "preferences";
Dir::Etc::preferencesparts "preferences.d";
Dir::Etc::trusted "trusted.gpg";
Dir::Etc::trustedparts "trusted.gpg.d";
Dir::Boot "boot";
Dir::Usr "usr";
Dir::Bin "";
Dir::Bin::methods "/usr/lib/apt/methods";
Dir::Bin::solvers "";
Dir::Bin::solvers:: "/usr/lib/apt/solvers";
Dir::Bin::planners "";
Dir::Bin::planners:: "/usr/lib/apt/planners";
Dir::Bin::dpkg "/usr/bin/dpkg";
Dir::Bin::gzip "/bin/gzip";
Dir::Bin::bzip2 "/bin/bzip2";
Dir::Bin::xz "/usr/bin/xz";
Dir::Bin::lz4 "/usr/bin/lz4";
Dir::Bin::zstd "/usr/bin/zstd";
Dir::Bin::lzma "/usr/bin/xz";
Dir::Media "";
Dir::Media::MountPath "/media/cdrom";
Dir::Log "var/log/apt";
Dir::Log::Terminal "term.log";
Dir::Log::History "history.log";
Dir::Log::Planner "eipp.log.xz";
Dir::Ignore-Files-Silently "";
Dir::Ignore-Files-Silently:: "~$";
Dir::Ignore-Files-Silently:: "\.disabled$";
Dir::Ignore-Files-Silently:: "\.bak$";
Dir::Ignore-Files-Silently:: "\.dpkg-[a-z]+$";
Dir::Ignore-Files-Silently:: "\.ucf-[a-z]+$";
Dir::Ignore-Files-Silently:: "\.save$";
Dir::Ignore-Files-Silently:: "\.orig$";
Dir::Ignore-Files-Silently:: "\.distUpgrade$";
Acquire "";
Acquire::AllowInsecureRepositories "0";
Acquire::AllowWeakRepositories "0";
Acquire::AllowDowngradeToInsecureRepositories "0";
Acquire::cdrom "";
Acquire::cdrom::mount "/media/cdrom";
Acquire::IndexTargets "";
Acquire::IndexTargets::deb "";
Acquire::IndexTargets::deb::Packages "";
Acquire::IndexTargets::deb::Packages::MetaKey
"$(COMPONENT)/binary-$(ARCHITECTURE)/Packages";
Acquire::IndexTargets::deb::Packages::flatMetaKey "Packages";
Acquire::IndexTargets::deb::Packages::ShortDescription "Packages";
Acquire::IndexTargets::deb::Packages::Description
"$(RELEASE)/$(COMPONENT) $(ARCHITECTURE) Packages";
Acquire::IndexTargets::deb::Packages::flatDescription "$(RELEASE)
Packages"; Acquire::IndexTargets::deb::Packages::Optional "0";
Acquire::IndexTargets::deb::Translations "";
Acquire::IndexTargets::deb::Translations::MetaKey
"$(COMPONENT)/i18n/Translation-$(LANGUAGE)";
Acquire::IndexTargets::deb::Translations::flatMetaKey "$(LANGUAGE)";
Acquire::IndexTargets::deb::Translations::ShortDescription
"Translation-$(LANGUAGE)";
Acquire::IndexTargets::deb::Translations::Description
"$(RELEASE)/$(COMPONENT) Translation-$(LANGUAGE)";
Acquire::IndexTargets::deb::Translations::flatDescription "$(RELEASE)
Translation-$(LANGUAGE)"; Acquire::IndexTargets::deb-src "";
Acquire::IndexTargets::deb-src::Sources "";
Acquire::IndexTargets::deb-src::Sources::MetaKey
"$(COMPONENT)/source/Sources";
Acquire::IndexTargets::deb-src::Sources::flatMetaKey "Sources";
Acquire::IndexTargets::deb-src::Sources::ShortDescription "Sources";
Acquire::IndexTargets::deb-src::Sources::Description
"$(RELEASE)/$(COMPONENT) Sources";
Acquire::IndexTargets::deb-src::Sources::flatDescription "$(RELEASE)
Sources"; Acquire::IndexTargets::deb-src::Sources::Optional "0";
Acquire::Changelogs ""; Acquire::Changelogs::URI "";
Acquire::Changelogs::URI::Origin "";
Acquire::Changelogs::URI::Origin::Debian
"https://metadata.ftp-master.debian.org/changelogs/@***@_changelog";
Acquire::Changelogs::URI::Origin::Ubuntu
"https://changelogs.ubuntu.com/changelogs/pool/@CHANGEPATH@/changelog";
Acquire::Changelogs::AlwaysOnline "";
Acquire::Changelogs::AlwaysOnline::Origin "";
Acquire::Changelogs::AlwaysOnline::Origin::Ubuntu "1";
Acquire::Snapshots ""; Acquire::Snapshots::URI "";
Acquire::Snapshots::URI::Origin "";
Acquire::Snapshots::URI::Origin::Debian
"https://snapshot.debian.org/archive/debian/@SNAPSHOTID@/";
Acquire::Snapshots::URI::Origin::Ubuntu
"https://snapshot.ubuntu.com/ubuntu/@SNAPSHOTID@/";
Acquire::Snapshots::URI::Override "";
Acquire::Snapshots::URI::Override::Label "";
Acquire::Snapshots::URI::Override::Label::Debian-Security
"https://snapshot.debian.org/archive/debian-security/@SNAPSHOTID@/";
Acquire::Snapshots::URI::Host "";
Acquire::Snapshots::URI::Host::archive.ubuntu.com
"https://snapshot.ubuntu.com/@PATH@/@SNAPSHOTID@/";
Acquire::Snapshots::URI::Host::deb.debian.org
"https://snapshot.debian.org/archive/@PATH@/@SNAPSHOTID@/";
Acquire::Snapshots::URI::Host::.archive.ubuntu.com
"https://snapshot.ubuntu.com/@PATH@/@SNAPSHOTID@/";
Acquire::Snapshots::URI::Host::security.ubuntu.com
"https://snapshot.ubuntu.com/@PATH@/@SNAPSHOTID@/";
Acquire::Snapshots::URI::Host::ppa.launchpadcontent.net
"https://snapshot.ppa.launchpadcontent.net/@PATH@/@SNAPSHOTID@/";
Acquire::Snapshots::URI::Host::ppa.launchpad.net
"https://snapshot.ppa.launchpadcontent.net/@PATH@/@SNAPSHOTID@/";
Acquire::Languages ""; Acquire::Languages:: "en"; Acquire::Languages::
"none"; Acquire::CompressionTypes ""; Acquire::CompressionTypes::xz
"xz"; Acquire::CompressionTypes::bz2 "bzip2";
Acquire::CompressionTypes::lzma "lzma"; Acquire::CompressionTypes::gz
"gzip"; Acquire::CompressionTypes::lz4 "lz4";
Acquire::CompressionTypes::zst "zstd"; DPkg ""; DPkg::Path
"/usr/sbin:/usr/bin:/sbin:/bin"; DPkg::Pre-Install-Pkgs "";
DPkg::Pre-Install-Pkgs:: "/usr/sbin/dpkg-preconfigure --apt || true";
Aptitude ""; Aptitude::Get-Root-Command "sudo:/usr/bin/sudo"; Binary
"apt-config"; Binary::apt-cdrom ""; Binary::apt-cdrom::APT "";
Binary::apt-cdrom::APT::Internal "";
Binary::apt-cdrom::APT::Internal::OpProgress "";
Binary::apt-cdrom::APT::Internal::OpProgress::EraseLines "0";
Binary::apt ""; Binary::apt::APT ""; Binary::apt::APT::Color "1";
Binary::apt::APT::Output-Version "30"; Binary::apt::APT::Cache "";
Binary::apt::APT::Cache::Show "";
Binary::apt::APT::Cache::Show::Version "2";
Binary::apt::APT::Cache::AllVersions "0";
Binary::apt::APT::Cache::ShowVirtuals "1";
Binary::apt::APT::Cache::Search "";
Binary::apt::APT::Cache::Search::Version "2";
Binary::apt::APT::Cache::ShowDependencyType "1";
Binary::apt::APT::Cache::ShowVersion "1"; Binary::apt::APT::Get "";
Binary::apt::APT::Get::Upgrade-Allow-New "1";
Binary::apt::APT::Get::Update "";
Binary::apt::APT::Get::Update::InteractiveReleaseInfoChanges "1";
Binary::apt::APT::Cmd ""; Binary::apt::APT::Cmd::Show-Update-Stats "1";
Binary::apt::APT::Cmd::Pattern-Only "1";
Binary::apt::APT::Keep-Downloaded-Packages "0"; Binary::apt::DPkg "";
Binary::apt::DPkg::Progress-Fancy "1"; Binary::apt::DPkg::Lock "";
Binary::apt::DPkg::Lock::Timeout "-1";
CommandLine "";
CommandLine::AsString "apt-config dump";

-- (no /etc/apt/preferences present) --


-- (no /etc/apt/preferences.d/* present) --


-- /etc/apt/sources.list --

deb http://deb.debian.org/debian/ sid main non-free-firmware
deb-src http://deb.debian.org/debian/ sid main non-free-firmware

-- (no /etc/apt/sources.list.d/* present) --


-- System Information:
Debian Release: trixie/sid
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.11.6-amd64 (SMP w/2 CPU threads; PREEMPT)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8),
LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages apt depends on:
ii adduser 3.137
ii base-passwd 3.6.5
ii debian-archive-keyring 2023.4
ii gpgv 2.2.45-2
ii libapt-pkg6.0t64 2.9.10
ii libc6 2.40-3
ii libgcc-s1 14.2.0-8
ii libgnutls30t64 3.8.6-2+b1
ii libseccomp2 2.5.5-1+b2
ii libstdc++6 14.2.0-8
ii libsystemd0 256.7-3

Versions of packages apt recommends:
ii ca-certificates 20240203

Versions of packages apt suggests:
pn apt-doc <none>
ii aptitude 0.8.13-6.1
pn dpkg-dev <none>
ii gnupg 2.2.45-2
pn powermgmt-base <none>
ii synaptic 0.91.3+b1

-- no debconf information
David Kalnischkies
2024-11-06 09:20:01 UTC
Reply
Permalink
Post by Aaron Rainbolt
4. Install the package with `sudo apt install ./test-meta_1.0_all.deb`.
5. Purge the package with `sudo apt purge test-meta`.
6. Run `sudo apt autopurge`.
Expected result: `gitk` should be removed during the autopurge step.
Actual result: Only the test-meta package is removed.
That might be expected if there are mere seconds between step 4 and 5 as
the user has realistically only interacted with test-meta in that time
frame. The longer the time is between these two steps through it becomes
possible that the user discovered gitk and fell in love with it.

autoremoving it would be very wrong then (and gitk is a really bad
example here as you interact with it directly; many recommends "just"
enable features within the package that recommended them).


Thankfully, we don't need to debate how many minutes have to be between
the two to behave one way or the other.

1. If you dislike the behavior for Suggests entirely, disable it:
APT::AutoRemove::SuggestsImportant "false";

2. Your step 5. would be better expressed as a sort-of 'undo'. There
exists requests for it, some pre requirements (like history.log),
"all" that is missing is the actual code of course.

3. Instead of trying to track which packages caused which other packages
to install¹ you might be better off with given the user a chance to
say: "git was suggesting gitk, but I resisted." to ignore that
relation (instead of the global switch from 1.). Does not exist in
apt and I think it shouldn't as it is too needy and kinda needs
a dedicated front end for the constant user interaction.

4. Its important to remember that autoremove is not meant to help you
maintain a lean and clean system. It is trying to remove "obvious"
obsolete stuff, but if it can't decide, it will always opt for keep
because user attention, knowledge and time is limited, but disk space
usually isn't ~ in the general case at least.


¹ Lets say: pkga recommends foo, pkgb suggests foo. You install pkga
(which also brings in foo). After a while you install pkgb and use it
– especially that feature only enabled by foo, but how do you know that.
Six months later you remove pkga. Are we autoremoving foo now?
It was never installed due to pkgb, it was already there.
How about if pkga is replaced in an upgrade with pkgc that doesn't
recommend foo? What if we don't deal with 3 but 300 packages?


So, in short: I think your suggestion is over-fitted for your example
and I believe your example would be better served by 2. for which
bug reports already exist, so adding another doesn't help & I am
therefore closing this one (as sorta duplicate).


Best regards

David Kalnischkies
Aaron Rainbolt
2024-11-06 15:10:01 UTC
Reply
Permalink
On Wed, 6 Nov 2024 10:07:54 +0100
Post by David Kalnischkies
Post by Aaron Rainbolt
4. Install the package with `sudo apt install
./test-meta_1.0_all.deb`. 5. Purge the package with `sudo apt purge
test-meta`. 6. Run `sudo apt autopurge`.
Expected result: `gitk` should be removed during the autopurge step.
Actual result: Only the test-meta package is removed.
That might be expected if there are mere seconds between step 4 and 5
as the user has realistically only interacted with test-meta in that
time frame. The longer the time is between these two steps through it
becomes possible that the user discovered gitk and fell in love with
it.
autoremoving it would be very wrong then (and gitk is a really bad
example here as you interact with it directly; many recommends "just"
enable features within the package that recommended them).
Thankfully, we don't need to debate how many minutes have to be
between the two to behave one way or the other.
APT::AutoRemove::SuggestsImportant "false";
Hmm, didn't know that existed. I wonder how that interacts with
`--install-suggests`, though I suppose it doesn't matter since someone
who toggled that feature on should probably expect things to be
autoremoved if they don't take explicit measures to keep them.
Post by David Kalnischkies
2. Your step 5. would be better expressed as a sort-of 'undo'. There
exists requests for it, some pre requirements (like history.log),
"all" that is missing is the actual code of course.
Respectfully, this isn't at all helpful here. The actual use case I had
in mind for fixing this issue would be to prevent situations where a
downstream derivative's metapackage changes the applications it
recommends (for instance to install the Chromium web browser instead of
Firefox, or to change one text editor for another, or something like
that). The preferred behavior in these instances is that the new
package should replace the old one (which will get autoremoved by the
user whenever they care to run an autoremove operation, unless they
mark it as manually installed in order to keep it). Being able to undo
an apt operation doesn't help at all. I see why you thought this would
help since my minimal reproducible example made it look like that, but
my example was meant to demonstrate the issue, *not* the use case
scenario.
Post by David Kalnischkies
3. Instead of trying to track which packages caused which other
packages to install¹ you might be better off with given the user a
chance to say: "git was suggesting gitk, but I resisted." to ignore
that relation (instead of the global switch from 1.). Does not exist
in apt and I think it shouldn't as it is too needy and kinda needs
a dedicated front end for the constant user interaction.
Not a bad idea, definitely feasible.
Post by David Kalnischkies
4. Its important to remember that autoremove is not meant to help you
maintain a lean and clean system. It is trying to remove "obvious"
obsolete stuff, but if it can't decide, it will always opt for keep
because user attention, knowledge and time is limited, but disk
space usually isn't ~ in the general case at least.
Sure, but keep in mind that I'm willing to contribute code to fix the
"bug" I'm looking at. Perhaps the existing developers haven't found
something like this worth implementing, but I think it's worth it and
am willing to do it, depending on how big of a job it becomes.
Post by David Kalnischkies
¹ Lets say: pkga recommends foo, pkgb suggests foo. You install pkga
(which also brings in foo). After a while you install pkgb and use it
– especially that feature only enabled by foo, but how do you know
that. Six months later you remove pkga. Are we autoremoving foo now?
It was never installed due to pkgb, it was already there.
How about if pkga is replaced in an upgrade with pkgc that doesn't
recommend foo? What if we don't deal with 3 but 300 packages?
This is a good point. Arguably though, autoremove already does lots of
surprising things if you don't look at the packages it's going to
remove. (Install, full-upgrade, remove, and purge do too in some
instances.) Autoremove's job is to clear out unneeded junk, and the
only way it knows how to do that is from package dependencies and
stored data about how packages were installed. Figuring out the user's
use case is not its job, that's the user's job and it's why apt shows
info about what packages will be installed, removed, etc. (I realize
typing this that this isn't a great argument though, everyone knows
that users can and will blindly hit `y` whenever prompted by apt, and
it's already liable to eat people's face off when they do that. Making
that worse is potentially not a great idea, though I'm not sure that
autoremoving foo in the scenario you mention makes things that much
worse from that standpoint.)
Post by David Kalnischkies
So, in short: I think your suggestion is over-fitted for your example
and I believe your example would be better served by 2. for which
bug reports already exist, so adding another doesn't help & I am
therefore closing this one (as sorta duplicate).
As explained above, your suggestion in 2 is not really usable or
relevant here. It only really fits the particular example I made here,
not the actual use case. It seems you didn't actually close the bug, so
there's nothing further for me to do to reopen it, but please do not
close it yet.
Post by David Kalnischkies
Best regards
David Kalnischkies
Loading...