summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-private/private-update.cc166
-rw-r--r--doc/examples/configure-index6
-rwxr-xr-xtest/integration/test-apt-get-update-sourceslist-warning71
3 files changed, 193 insertions, 50 deletions
diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc
index affae655d..f1734fea2 100644
--- a/apt-private/private-update.cc
+++ b/apt-private/private-update.cc
@@ -21,13 +21,32 @@
#include <ostream>
#include <string>
+#include <tuple>
#include <apti18n.h>
/*}}}*/
// DoUpdate - Update the package lists /*{{{*/
-// ---------------------------------------------------------------------
-/* */
+static bool isDebianBookwormRelease(pkgCache::RlsFileIterator const &RlsFile)
+{
+ std::tuple<std::string_view, std::string_view, std::string_view> const affected[] = {
+ {"Debian", "Debian", "bookworm"},
+ {"Debian", "Debian", "sid"},
+ };
+ if (RlsFile.end() || RlsFile->Origin == nullptr || RlsFile->Label == nullptr || RlsFile->Codename == nullptr)
+ return false;
+ std::tuple<std::string_view, std::string_view, std::string_view> const release{RlsFile.Origin(), RlsFile.Label(), RlsFile.Codename()};
+ return std::find(std::begin(affected), std::end(affected), release) != std::end(affected);
+}
+static void suggestDebianNonFreeFirmware(char const *const repo, char const *const val,
+ char const *const from, char const *const to)
+{
+ // Both messages are reused from the ReleaseInfoChange feature in acquire-item.cc
+ _error->Notice(_("Repository '%s' changed its '%s' value from '%s' to '%s'"), repo, val, from, to);
+ std::string notes;
+ strprintf(notes, "https://www.debian.org/releases/bookworm/%s/release-notes/ch-information.html#non-free-split", _config->Find("APT::Architecture").c_str());
+ _error->Notice(_("More information about this can be found online in the Release notes at: %s"), notes.c_str());
+}
bool DoUpdate(CommandLine &CmdL)
{
if (CmdL.FileSize() != 1)
@@ -81,44 +100,135 @@ bool DoUpdate(CommandLine &CmdL)
if (Cache.BuildCaches(false) == false)
return false;
- if (_config->FindB("APT::Get::Update::SourceListWarnings", true))
- {
+ bool const SLWarnings = _config->FindB("APT::Get::Update::SourceListWarnings", true);
+ if (SLWarnings)
List = Cache.GetSourceList();
- for (pkgSourceList::const_iterator S = List->begin(); S != List->end(); ++S)
- {
- if (APT::String::Startswith((*S)->GetURI(), "ftp://") == false)
- continue;
- pkgCache::RlsFileIterator const RlsFile = (*S)->FindInCache(Cache, false);
- if (RlsFile.end() || RlsFile->Origin == 0 || RlsFile->Label == 0)
- continue;
- char const *const affected[][2] = {
- {"Debian", "Debian"},
- {"Debian", "Debian-Security"},
- {"Debian Backports", "Debian Backports"},
- };
- auto const matchRelease = [&](decltype(affected[0]) a) {
- return strcmp(RlsFile.Origin(), a[0]) == 0 && strcmp(RlsFile.Label(), a[1]) == 0;
- };
- if (std::find_if(std::begin(affected), std::end(affected), matchRelease) != std::end(affected))
- _error->Warning("Debian shuts down public FTP services currently still used in your sources.list(5) as '%s'.\n"
- "See press release %s for details.",
- (*S)->GetURI().c_str(), "https://debian.org/News/2017/20170425");
- }
- for (pkgSourceList::const_iterator S = List->begin(); S != List->end(); ++S)
+
+ if (_config->FindB("APT::Get::Update::SourceListWarnings::APTAuth", SLWarnings))
+ {
+ constexpr std::string_view const affected_method[] = {"http", "https", "tor+http", "tor+https", "ftp"};
+ for (auto *S : *List)
{
- URI uri((*S)->GetURI());
+ URI uri(S->GetURI());
if (uri.User.empty() && uri.Password.empty())
continue;
// we can't really predict if a +http method supports everything http does,
// so we play it safe and use an allowlist here.
- char const *const affected[] = {"http", "https", "tor+http", "tor+https", "ftp"};
- if (std::find(std::begin(affected), std::end(affected), uri.Access) != std::end(affected))
+ if (std::find(std::begin(affected_method), std::end(affected_method), uri.Access) != std::end(affected_method))
// TRANSLATOR: the first two are manpage references, the last the URI from a sources.list
_error->Notice(_("Usage of %s should be preferred over embedding login information directly in the %s entry for '%s'"),
"apt_auth.conf(5)", "sources.list(5)", URI::ArchiveOnly(uri).c_str());
}
}
+ if (_config->FindB("APT::Get::Update::SourceListWarnings::NonFreeFirmware", SLWarnings))
+ {
+ // If a Debian source has a non-free component, suggest adding non-free-firmware
+ bool found_affected_release = false;
+ bool found_non_free = false;
+ bool found_non_free_firmware = false;
+ for (auto *S : *List)
+ {
+ if (not isDebianBookwormRelease(S->FindInCache(Cache, false)))
+ continue;
+
+ for (auto PkgFile = Cache.GetPkgCache()->FileBegin(); not PkgFile.end(); ++PkgFile)
+ {
+ if (PkgFile.Flagged(pkgCache::Flag::NoPackages))
+ continue;
+ found_affected_release = true;
+ const auto * const comp = PkgFile.Component();
+ if (comp == nullptr)
+ continue;
+ if (strcmp(comp, "non-free") == 0)
+ found_non_free = true;
+ else if (strcmp(comp, "non-free-firmware") == 0)
+ {
+ found_non_free_firmware = true;
+ break;
+ }
+ }
+ if (found_non_free_firmware)
+ break;
+ }
+ if (not found_non_free_firmware && found_non_free && found_affected_release)
+ {
+ /* See if a well-known firmware package is installable from this codename
+ if so, we likely operate with new apt on an old snapshot not supporting non-free-firmware */
+ bool suggest_non_free_firmware = true;
+ if (auto const Grp = Cache.GetPkgCache()->FindGrp("firmware-linux-nonfree"); not Grp.end())
+ {
+ for (auto Pkg = Grp.PackageList(); not Pkg.end() && suggest_non_free_firmware; Pkg = Grp.NextPkg(Pkg))
+ {
+ for (auto Ver = Pkg.VersionList(); not Ver.end(); ++Ver)
+ {
+ if (not Ver.Downloadable())
+ continue;
+ for (auto VerFile = Ver.FileList(); not VerFile.end(); ++VerFile)
+ {
+ auto const PkgFile = VerFile.File();
+ if (PkgFile.end())
+ continue;
+ if (not isDebianBookwormRelease(PkgFile.ReleaseFile()))
+ continue;
+ suggest_non_free_firmware = false;
+ break;
+ }
+ if (not suggest_non_free_firmware)
+ break;
+ }
+ }
+ }
+ if (suggest_non_free_firmware)
+ suggestDebianNonFreeFirmware("Debian bookworm", "non-free component", "non-free", "non-free non-free-firmware");
+ }
+
+ if (not found_non_free_firmware && not found_non_free && found_affected_release)
+ {
+ /* Try to notify users who have installed firmware packages at some point, but
+ have not enabled non-free currently – they might want to opt into updates now */
+ APT::StringView const affected_pkgs[] = {
+ "amd64-microcode", "atmel-firmware", "bluez-firmware", "dahdi-firmware-nonfree",
+ "firmware-amd-graphics", "firmware-ast", "firmware-atheros", "firmware-bnx2",
+ "firmware-bnx2x", "firmware-brcm80211", "firmware-cavium", "firmware-intel-sound",
+ "firmware-intelwimax", "firmware-ipw2x00", "firmware-ivtv", "firmware-iwlwifi",
+ "firmware-libertas", "firmware-linux", "firmware-linux-nonfree", "firmware-misc-nonfree",
+ "firmware-myricom", "firmware-netronome", "firmware-netxen", "firmware-qcom-media",
+ "firmware-qcom-soc", "firmware-qlogic", "firmware-realtek", "firmware-realtek-rtl8723cs-bt",
+ "firmware-samsung", "firmware-siano", "firmware-sof-signed", "firmware-ti-connectivity",
+ "firmware-zd1211", "intel-microcode", "midisport-firmware", "raspi-firmware",
+ };
+ bool suggest_non_free_firmware = false;
+ for (auto pkgname : affected_pkgs)
+ {
+ auto const Grp = Cache.GetPkgCache()->FindGrp(pkgname);
+ if (Grp.end())
+ continue;
+ for (auto Pkg = Grp.PackageList(); not Pkg.end(); Pkg = Grp.NextPkg(Pkg))
+ {
+ auto const Ver = Pkg.CurrentVer();
+ if (Ver.end() || Ver.Downloadable())
+ continue;
+ bool another = false;
+ for (auto V = Pkg.VersionList(); not V.end(); ++V)
+ if (V.Downloadable())
+ {
+ another = true;
+ break;
+ }
+ if (another)
+ continue;
+ suggest_non_free_firmware = true;
+ break;
+ }
+ if (suggest_non_free_firmware)
+ break;
+ }
+ if (suggest_non_free_firmware)
+ suggestDebianNonFreeFirmware("Debian bookworm", "firmware component", "non-free", "non-free-firmware");
+ }
+ }
+
// show basic stats (if the user whishes)
if (_config->FindB("APT::Cmd::Show-Update-Stats", false) == true)
{
diff --git a/doc/examples/configure-index b/doc/examples/configure-index
index b3deccaaf..beafbbcd4 100644
--- a/doc/examples/configure-index
+++ b/doc/examples/configure-index
@@ -123,7 +123,11 @@ APT
Update
{
InteractiveReleaseInfoChanges "<BOOL>";
- SourceListWarnings "<BOOL>";
+ SourceListWarnings "<BOOL>"
+ {
+ APTAuth "<BOOL>";
+ NonFreeFirmware "<BOOL>";
+ };
};
};
diff --git a/test/integration/test-apt-get-update-sourceslist-warning b/test/integration/test-apt-get-update-sourceslist-warning
index a99356b8b..60c8d7308 100755
--- a/test/integration/test-apt-get-update-sourceslist-warning
+++ b/test/integration/test-apt-get-update-sourceslist-warning
@@ -11,35 +11,64 @@ setupaptarchive --no-update
testsuccess apt update
testsuccess apt update --no-download
-echo 'deb ftp://ftp.tlh.debian.org/debian zurg main' > rootdir/etc/apt/sources.list.d/ftpshutdown.list
-cat > rootdir/var/lib/apt/lists/ftp.tlh.debian.org_debian_dists_zurg_Release <<EOF
+cat > rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_Release <<EOF
Origin: Debian
Label: Debian
Suite: unreleased
-Codename: zurg
-Date: Fri, 14 Jul 2017 11:34:35 +0000
+Codename: bookworm
+Date: Sun, 29 Jan 2023 20:14:10 +0000
Architectures: amd64
-Components: main
-Description: Debian x.y Zurg - Not Released
+Components: main contrib non-free non-free-firmware
+Description: Debian x.y Bookworm - Not Released
EOF
-chmod 644 rootdir/var/lib/apt/lists/ftp.tlh.debian.org_debian_dists_zurg_Release
+chmod 644 rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_Release
+touch rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_main_binary-amd64_Packages
+touch rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_contrib_binary-amd64_Packages
+touch rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_non-free_binary-amd64_Packages
+touch rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_non-free-firmware_binary-amd64_Packages
-testwarningequal "Reading package lists...
+NOTESURL='https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.html#non-free-split'
+BOILERPLATE='Reading package lists...
Building dependency tree...
-All packages are up to date.
-W: Debian shuts down public FTP services currently still used in your sources.list(5) as 'ftp://ftp.tlh.debian.org/debian/'.
- See press release https://debian.org/News/2017/20170425 for details." apt update --no-download
+All packages are up to date.'
+msgmsg 'Do not suggest new non-free-firmware component if no non-free'
+echo 'deb http://example.org/debian bookworm main' > rootdir/etc/apt/sources.list.d/example.list
+testsuccessequal "$BOILERPLATE" apt update --no-download
+echo 'deb-src http://example.org/debian bookworm main non-free' > rootdir/etc/apt/sources.list.d/example.list
+testsuccessequal "$BOILERPLATE" apt update --no-download
-echo 'deb http://apt:debian@ftp.tlh.debian.org/debian zurg main' > rootdir/etc/apt/sources.list.d/ftpshutdown.list
-testsuccessequal "Reading package lists...
-Building dependency tree...
-All packages are up to date.
-N: Usage of apt_auth.conf(5) should be preferred over embedding login information directly in the sources.list(5) entry for 'http://ftp.tlh.debian.org/debian'" apt update --no-download
+msgmsg 'Is non-free-firmware missing?'
+echo 'deb http://example.org/debian bookworm main non-free' > rootdir/etc/apt/sources.list.d/example.list
+cat >> rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_non-free_binary-amd64_Packages <<EOF
+Package: firmware-linux-nonfree
+Architecture: all
+Version: 1
+EOF
+testsuccessequal "$BOILERPLATE" apt update --no-download
+echo -n > rootdir/var/lib/apt/lists/example.org_debian_dists_bookworm_non-free_binary-amd64_Packages
+testsuccessequal "$BOILERPLATE
+N: Repository 'Debian bookworm' changed its 'non-free component' value from 'non-free' to 'non-free non-free-firmware'
+N: More information about this can be found online in the Release notes at: $NOTESURL" apt update --no-download
+msgmsg 'Component already present'
+echo 'deb http://example.org/debian bookworm non-free non-free-firmware' > rootdir/etc/apt/sources.list.d/example.list
+testsuccessequal "$BOILERPLATE" apt update --no-download
+echo 'deb http://example.org/debian bookworm non-free
+deb http://example.org/debian bookworm non-free-firmware' > rootdir/etc/apt/sources.list.d/example.list
+testsuccessequal "$BOILERPLATE" apt update --no-download
-echo 'deb tor+https://apt:debian@ftp.tlh.debian.org/debian zurg main' > rootdir/etc/apt/sources.list.d/ftpshutdown.list
-testsuccessequal "Reading package lists...
-Building dependency tree...
-All packages are up to date.
-N: Usage of apt_auth.conf(5) should be preferred over embedding login information directly in the sources.list(5) entry for 'tor+https://ftp.tlh.debian.org/debian'" apt update --no-download
+msgmsg 'Detect login info embedded in sources.list'
+echo 'deb http://apt:debian@example.org/debian bookworm main' > rootdir/etc/apt/sources.list.d/example.list
+testsuccessequal "$BOILERPLATE
+N: Usage of apt_auth.conf(5) should be preferred over embedding login information directly in the sources.list(5) entry for 'http://example.org/debian'" apt update --no-download
+echo 'deb tor+https://apt:debian@example.org/debian bookworm main' > rootdir/etc/apt/sources.list.d/example.list
+testsuccessequal "$BOILERPLATE
+N: Usage of apt_auth.conf(5) should be preferred over embedding login information directly in the sources.list(5) entry for 'tor+https://example.org/debian'" apt update --no-download
+
+msgmsg 'Firmware packages without upgrades'
+echo 'deb http://example.org/debian bookworm main' > rootdir/etc/apt/sources.list.d/example.list
+insertinstalledpackage 'firmware-linux-nonfree' 'all' '1'
+testsuccessequal "$BOILERPLATE
+N: Repository 'Debian bookworm' changed its 'firmware component' value from 'non-free' to 'non-free-firmware'
+N: More information about this can be found online in the Release notes at: $NOTESURL" apt update --no-download