diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2024-02-19 12:07:55 +0100 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2024-02-20 18:50:14 +0100 |
commit | b6274188312e6338e94edc45dbf9cc410d650477 (patch) | |
tree | 382dd0a4014e161824b0b5c25c7e9c8dc2ce9fa1 | |
parent | e1eb204542c456732160a154225e743bc552b6b2 (diff) |
Automatically enable snapshots where supported
Convert sources.list Snapshot option from opt-in to automatic. If
we can find a snapshot server, Snapshot: yes is assumed if a snapshot
is specified.
On the implementation side, we record automatic snapshot enablement
by adding a '?' suffix to the snapshot timestamp, if any is specified,
this avoids introducing bugs into the code where we could end up with
an empty snapshot.
This has an annoying internal implementation caveat: Since we call
GetDebReleaseIndexBy() with the SHADOWED option emplaced, if we do
not find a server, we need to remove the SHADOWED option again, but
we already have inserted a shadowed release index into the list.
This will simply insert the release index a second time without the
SHADOWED option which in preliminary testing works fine, but it would
arguably be more correct to also remove the release index again if
we have created it.
FIXME: This only has one test case: A source with supported snapshot
server is auto-discovered. We should also add a test case where we
cannot detect a server and then don't fail in automatic mode.
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 17 | ||||
-rwxr-xr-x | test/integration/test-snapshot | 7 |
2 files changed, 22 insertions, 2 deletions
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 0f05cb21a..3bc7f78de 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -17,6 +17,7 @@ #include <apt-pkg/tagfile.h> #include <algorithm> +#include <cassert> #include <map> #include <optional> #include <sstream> @@ -1299,7 +1300,8 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ std::string const &Dist, std::string const &Section, bool const &IsSrc, std::map<std::string, std::string> Options) const { - auto Snapshot = GetSnapshotOption(Options, "snapshot"); + std::string SnapshotAptConf = _config->Find("APT::Snapshot"); + std::string Snapshot = GetSnapshotOption(Options, "snapshot", SnapshotAptConf.empty() ? "" : SnapshotAptConf + "?"); if (not Snapshot.empty()) { std::map<std::string, std::string> SnapshotOptions = Options; @@ -1339,15 +1341,28 @@ class APT_HIDDEN debSLTypeDebian : public pkgSourceList::Type /*{{{*/ } if (Server.empty() || Server == "no") { + if (APT::String::Endswith(Snapshot, "?")) + { + Options.erase("SHADOWED"); + goto nosnapshot; + } if (Server != "no" && filename.empty()) return _error->Error("Cannot identify snapshot server for %s %s - run update without snapshot id first", URI.c_str(), Dist.c_str()); return _error->Error("Snapshots not supported for %s %s", URI.c_str(), Dist.c_str()); } + // We have found a server by now, so we enable snapshots for this source. + if (APT::String::Endswith(Snapshot, "?")) + { + Snapshot.pop_back(); + } + + assert(not Snapshot.empty()); auto SnapshotURI = SubstVar(SubstVar(Server, "@SNAPSHOTID@", Snapshot), "@PATH@", ArchiveURI.Path); if (not CreateItemInternalOne(List, SnapshotURI, Dist, Section, IsSrc, SnapshotOptions)) return false; } + nosnapshot: if (not CreateItemInternalOne(List, URI, Dist, Section, IsSrc, Options)) return false; diff --git a/test/integration/test-snapshot b/test/integration/test-snapshot index 2bf7d70d4..f7d7e6a05 100755 --- a/test/integration/test-snapshot +++ b/test/integration/test-snapshot @@ -24,7 +24,12 @@ testsuccessequal "'http://localhost:${APTHTTPPORT}/dists/stable/InRelease' local 'http://localhost:${APTHTTPPORT}/dists/stable/main/binary-all/Packages.xz' localhost:${APTHTTPPORT}_dists_stable_main_binary-all_Packages 0 'http://localhost:${APTHTTPPORT}/dists/stable/main/i18n/Translation-en.xz' localhost:${APTHTTPPORT}_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris -testsuccessequal "'http://localhost:${APTHTTPPORT}/dists/stable/InRelease' localhost:${APTHTTPPORT}_dists_stable_InRelease 0 +testsuccessequal "'https://snapshot.debian.org/archive/debian/OPTIONNOTSET/dists/stable/InRelease' snapshot.debian.org_archive_debian_OPTIONNOTSET_dists_stable_InRelease 0 +'https://snapshot.debian.org/archive/debian/OPTIONNOTSET/dists/stable/main/source/Sources.xz' snapshot.debian.org_archive_debian_OPTIONNOTSET_dists_stable_main_source_Sources 0 +'https://snapshot.debian.org/archive/debian/OPTIONNOTSET/dists/stable/main/binary-amd64/Packages.xz' snapshot.debian.org_archive_debian_OPTIONNOTSET_dists_stable_main_binary-amd64_Packages 0 +'https://snapshot.debian.org/archive/debian/OPTIONNOTSET/dists/stable/main/binary-all/Packages.xz' snapshot.debian.org_archive_debian_OPTIONNOTSET_dists_stable_main_binary-all_Packages 0 +'https://snapshot.debian.org/archive/debian/OPTIONNOTSET/dists/stable/main/i18n/Translation-en.xz' snapshot.debian.org_archive_debian_OPTIONNOTSET_dists_stable_main_i18n_Translation-en 0 +'http://localhost:${APTHTTPPORT}/dists/stable/InRelease' localhost:${APTHTTPPORT}_dists_stable_InRelease 0 'http://localhost:${APTHTTPPORT}/dists/stable/main/source/Sources.xz' localhost:${APTHTTPPORT}_dists_stable_main_source_Sources 0 'http://localhost:${APTHTTPPORT}/dists/stable/main/binary-amd64/Packages.xz' localhost:${APTHTTPPORT}_dists_stable_main_binary-amd64_Packages 0 'http://localhost:${APTHTTPPORT}/dists/stable/main/binary-all/Packages.xz' localhost:${APTHTTPPORT}_dists_stable_main_binary-all_Packages 0 |