diff options
-rw-r--r-- | apt-pkg/aptconfiguration.cc | 61 | ||||
-rw-r--r-- | apt-pkg/aptconfiguration.h | 7 | ||||
-rw-r--r-- | apt-pkg/cacheiterators.h | 14 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 7 | ||||
-rw-r--r-- | apt-pkg/pkgcache.h | 12 | ||||
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 4 | ||||
-rw-r--r-- | apt-pkg/policy.cc | 48 | ||||
-rw-r--r-- | apt-pkg/policy.h | 3 | ||||
-rw-r--r-- | apt-pkg/tagfile-keys.list | 1 | ||||
-rw-r--r-- | apt-private/private-show.cc | 8 | ||||
-rw-r--r-- | debian/NEWS | 7 | ||||
-rw-r--r-- | doc/apt_preferences.5.xml | 19 | ||||
-rw-r--r-- | doc/examples/configure-index | 10 | ||||
-rw-r--r-- | test/integration/framework | 3 | ||||
-rwxr-xr-x | test/integration/test-phased-updates | 272 |
15 files changed, 469 insertions, 7 deletions
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 61e53ec3a..b3b423fdc 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -480,4 +480,65 @@ std::string const Configuration::getBuildProfilesString() { return list; } /*}}}*/ + +// getMachineID - supported data.tar extensions /*{{{*/ +// --------------------------------------------------------------------- +/* */ +std::string const Configuration::getMachineID() +{ + std::string id = _config->Find("APT::Machine-ID"); + + if (id.empty()) + { + std::string file = _config->FindFile("Dir::Etc::machine-id"); + + if (file.empty()) + { + file = flCombine(_config->FindDir("Dir::Etc"), "../machine-id"); + } + FileFd fd; + _error->PushToStack(); + + if (not OpenConfigurationFileFd(file, fd) || not fd.ReadLine(id)) + { + if (_config->FindB("Debug::Phasing", false)) + { + _error->DumpErrors(std::clog); + } + } + + _error->RevertToStack(); + } + + return id; +} + /*}}}*/ +// isChroot - whether we are inside a chroot /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Configuration::isChroot() +{ + static struct once + { + bool res = false; + once() + { + pid_t child = ExecFork(); + if (child == 0) + { + auto binary = _config->FindFile("Dir::Bin::ischroot", "/usr/bin/ischroot"); + const char *const Args[] = { + binary.c_str(), + nullptr}; + execvp(Args[0], const_cast<char **>(Args)); + _exit(127); + } + + res = ExecWait(child, "ischroot", true); + } + } once; + + return once.res; +} + /*}}}*/ } diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index 2cb2d823a..bbeb156b9 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -122,7 +122,12 @@ namespace Configuration { /*{{{*/ APT_PUBLIC std::vector<std::string> const getBuildProfiles(); /** \return Return a comma-separated list of enabled build profile specifications */ APT_PUBLIC std::string const getBuildProfilesString(); - /*}}}*/ + + std::string const getMachineID(); + + /** \return Whether we are running in a chroot */ + bool isChroot(); + /*}}}*/ } /*}}}*/ } diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 1b049b6e5..6261b5089 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -242,6 +242,20 @@ class APT_PUBLIC pkgCache::VerIterator : public Iterator<Version, VerIterator> { bool Automatic() const; VerFileIterator NewestFile() const; +#ifdef APT_COMPILING_APT + inline unsigned int PhasedUpdatePercentage() const + { + return (static_cast<Version::Extra *>(Owner->Map.Data()) + S->d)->PhasedUpdatePercentage; + } + inline bool PhasedUpdatePercentage(unsigned int percentage) + { + if (percentage > 100) + return false; + (static_cast<Version::Extra *>(Owner->Map.Data()) + S->d)->PhasedUpdatePercentage = static_cast<uint8_t>(percentage); + return true; + } +#endif + inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) { if (S == 0) S = OwnerPointer(); diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 95f6f6fc8..b5c9c066e 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -338,6 +338,13 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg, else if (std::find(forceImportant.begin(), forceImportant.end(), Pkg.Name()) != forceImportant.end()) Pkg->Flags |= pkgCache::Flag::Important; + auto phased = Section.FindULL(pkgTagSection::Key::Phased_Update_Percentage, 100); + if (phased != 100) + { + if (not Ver.PhasedUpdatePercentage(phased)) + _error->Warning("Ignoring invalid Phased-Update-Percentage value"); + } + if (ParseStatus(Pkg,Ver) == false) return false; return true; diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 6c6a4664e..55baa3cef 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -623,6 +623,8 @@ struct pkgCache::DescFile or handled as separate versions based on the Hash value. */ struct pkgCache::Version { + struct Extra; + /** \brief complete version string */ map_stringitem_t VerStr; /** \brief section this version is filled in */ @@ -688,8 +690,16 @@ struct pkgCache::Version map_pointer<Version> NextInSource; /** \brief Private pointer */ - map_pointer<void> d; + map_pointer<Extra> d; }; + +#ifdef APT_COMPILING_APT +/// \brief Extra information for packages. APT-internal use only. +struct pkgCache::Version::Extra +{ + uint8_t PhasedUpdatePercentage; +}; +#endif /*}}}*/ // Description structure /*{{{*/ /** \brief datamember of a linked list of available description for a version */ diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index d02c49f03..bd81ca0f5 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -873,6 +873,10 @@ map_pointer<pkgCache::Version> pkgCacheGenerator::NewVersion(pkgCache::VerIterat // Fill it in Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version); + Ver->d = AllocateInMap<pkgCache::Version::Extra>(); + if (not Ver.PhasedUpdatePercentage(100)) + abort(); + //Dynamic<pkgCache::VerIterator> DynV(Ver); // caller MergeListVersion already takes care of it Ver->NextVer = Next; Ver->ParentPkg = ParentPkg; diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 761a6ede1..39879f754 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -14,6 +14,7 @@ // Include Files /*{{{*/ #include <config.h> +#include <apt-pkg/aptconfiguration.h> #include <apt-pkg/cachefilter.h> #include <apt-pkg/configuration.h> #include <apt-pkg/error.h> @@ -26,6 +27,7 @@ #include <apt-pkg/versionmatch.h> #include <iostream> +#include <random> #include <sstream> #include <string> #include <vector> @@ -40,12 +42,17 @@ using namespace std; constexpr short NEVER_PIN = std::numeric_limits<short>::min(); +struct pkgPolicy::Private +{ + std::string machineID; +}; + // Policy::Init - Startup and bind to a cache /*{{{*/ // --------------------------------------------------------------------- /* Set the defaults for operation. The default mode with no loaded policy file matches the V0 policy engine. */ pkgPolicy::pkgPolicy(pkgCache *Owner) : VerPins(nullptr), - PFPriority(nullptr), Cache(Owner), d(NULL) + PFPriority(nullptr), Cache(Owner), d(new Private) { if (Owner == 0) return; @@ -77,6 +84,8 @@ pkgPolicy::pkgPolicy(pkgCache *Owner) : VerPins(nullptr), CreatePin(pkgVersionMatch::Release,"",DefRel,990); } InitDefaults(); + + d->machineID = APT::Configuration::getMachineID(); } /*}}}*/ // Policy::InitDefaults - Compute the default selections /*{{{*/ @@ -274,8 +283,38 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name, // Policy::GetPriority - Get the priority of the package pin /*{{{*/ // --------------------------------------------------------------------- /* */ +// Returns true if this update is excluded by phasing. +static inline bool ExcludePhased(std::string machineID, pkgCache::VerIterator const &Ver) +{ + // The order and fallbacks for the always/never checks come from update-manager and exist + // to preserve compatibility. + if (_config->FindB("APT::Get::Always-Include-Phased-Updates", + _config->FindB("Update-Manager::Always-Include-Phased-Updates", false))) + return false; + + if (_config->FindB("APT::Get::Never-Include-Phased-Updates", + _config->FindB("Update-Manager::Never-Include-Phased-Updates", false))) + return true; + + if (machineID.empty() // no machine-id + || getenv("SOURCE_DATE_EPOCH") != nullptr // reproducible build - always include + || APT::Configuration::isChroot()) + return false; + + std::string seedStr = std::string(Ver.SourcePkgName()) + "-" + Ver.SourceVerStr() + "-" + machineID; + std::seed_seq seed(seedStr.begin(), seedStr.end()); + std::minstd_rand rand(seed); + std::uniform_int_distribution<unsigned int> dist(0, 100); + + return dist(rand) > Ver.PhasedUpdatePercentage(); +} APT_PURE signed short pkgPolicy::GetPriority(pkgCache::VerIterator const &Ver, bool ConsiderFiles) { + if (Ver.ParentPkg()->CurrentVer && Ver.PhasedUpdatePercentage() != 100) + { + if (ExcludePhased(d->machineID, Ver)) + return 1; + } if (VerPins[Ver->ID].Type != pkgVersionMatch::None) { // If all sources are never pins, the never pin wins. @@ -454,4 +493,9 @@ bool ReadPinFile(pkgPolicy &Plcy,string File) } /*}}}*/ -pkgPolicy::~pkgPolicy() {delete [] PFPriority; delete [] VerPins; } +pkgPolicy::~pkgPolicy() +{ + delete[] PFPriority; + delete[] VerPins; + delete d; +} diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h index 7f30d40ed..589cebcde 100644 --- a/apt-pkg/policy.h +++ b/apt-pkg/policy.h @@ -83,7 +83,8 @@ class APT_PUBLIC pkgPolicy : public pkgDepCache::Policy explicit pkgPolicy(pkgCache *Owner); virtual ~pkgPolicy(); private: - void * const d; + struct Private; + Private *const d; }; APT_PUBLIC bool ReadPinFile(pkgPolicy &Plcy, std::string File = ""); diff --git a/apt-pkg/tagfile-keys.list b/apt-pkg/tagfile-keys.list index a16bc686a..b5cc2f1a4 100644 --- a/apt-pkg/tagfile-keys.list +++ b/apt-pkg/tagfile-keys.list @@ -46,6 +46,7 @@ Package-List Package_Revision Package-Revision Package-Type +Phased-Update-Percentage Pre-Depends Priority Protected diff --git a/apt-private/private-show.cc b/apt-private/private-show.cc index 103fa57e4..30b99b013 100644 --- a/apt-private/private-show.cc +++ b/apt-private/private-show.cc @@ -563,7 +563,13 @@ bool Policy(CommandLine &CmdL) else std::cout << " " << V.VerStr(); - std::cout << " " << Plcy->GetPriority(V) << std::endl; + std::cout << " " << Plcy->GetPriority(V); + + if (V.PhasedUpdatePercentage() != 100) + std::cout << " " + << "(" << _("phased") << " " << V.PhasedUpdatePercentage() << "%)"; + + std::cout << std::endl; for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; ++VF) { // Locate the associated index files so we can derive a description diff --git a/debian/NEWS b/debian/NEWS index 9d9c963c2..eb8e2c116 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -3,6 +3,13 @@ apt (2.1.16) UNRELEASED; urgency=medium Automatically remove unused kernels on dist-upgrade. To revert to previous behavior, set APT::Get::AutomaticRemove::Kernels to false. + Packages files can now set the Phased-Update-Percentage field to restrict + update rollout to a specified percentage of machines. Previously, this has + only been available to users of Ubuntu's update-manager tool. See + apt_preferences(5) for details and how to configure multiple systems to get + the same updates. Phased updates are disabled in chroots for now to not + break buildd-style setups. + -- Julian Andres Klode <jak@debian.org> Mon, 04 Jan 2021 10:47:14 +0100 apt (1.9.11) experimental; urgency=medium diff --git a/doc/apt_preferences.5.xml b/doc/apt_preferences.5.xml index 4ef5282e7..23f2d2d6b 100644 --- a/doc/apt_preferences.5.xml +++ b/doc/apt_preferences.5.xml @@ -102,7 +102,8 @@ algorithm to set the priorities of the versions of a package. Assign: <term>priority 1</term> <listitem><simpara>to the versions coming from archives which in their <filename>Release</filename> files are marked as "NotAutomatic: yes" but <emphasis>not</emphasis> as "ButAutomaticUpgrades: yes" -like the Debian <literal>experimental</literal> archive.</simpara></listitem> +like the Debian <literal>experimental</literal> archive.</simpara></listitem>, +as well as versions that are not phased on this systems. </varlistentry> <varlistentry> @@ -175,6 +176,22 @@ because at least <emphasis>one</emphasis> of the available versions has a higher priority than the installed version.</para> </refsect2> +<refsect2><title>Phased Updates</title> +<para>APT understands a field called <literal>Phased-Update-Percentage</literal> +which can be used to control the rollout of a new version. It is an integer between +0 and 100.</para> + +<para>A system's eligibility to a phased update is determined by seeding +random number generator with the package source name, the version number, +and /etc/machine-id, and then calculating an integer in the range [0, 100]. +If this integer is larger than the <literal>Phased-Update-Percentage</literal>, +the version is pinned to 1, and thus held back. Otherwise, normal policy rules apply. +</para> + +<para>In case you have multiple systems that you want to receive the same set of updates, you can set +<code>APT::Machine-ID</code> to a UUID such that they all phase the same, or set <code>APT::Get::Never-Include-Phased-Updates</code> +or <code>APT::Get::Always-Include-Phased-Updates</code> to true such that APT will never/always consider phased updates.</para> +</refsect2> <refsect2><title>The Effect of APT Preferences</title> <para>The APT preferences file allows the system administrator to control the diff --git a/doc/examples/configure-index b/doc/examples/configure-index index 15b020198..5ddf4132c 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -101,6 +101,8 @@ APT Upgrade "<BOOL>"; Only-Upgrade "<BOOL>"; Upgrade-Allow-New "<BOOL>"; + Always-Include-Phased-Updates "<BOOL>"; + Never-Include-Phased-Updates "<BOOL>"; Purge "<BOOL>"; ReInstall "<BOOL>"; Compile "<BOOL>"; @@ -219,6 +221,8 @@ APT // control parameters for cron jobs by /etc/cron.daily/apt documented there Periodic {}; + + Machine-ID "<STRING>"; // Value of /etc/machine-id }; // Options for the downloading routines @@ -417,6 +421,7 @@ Dir "<DIR>" SourceParts "<DIR>"; Trusted "<FILE>"; TrustedParts "<DIR>"; + Machine-ID "<FILE>"; // by default points to ../machine-id effectively }; // Locations of binaries @@ -434,6 +439,7 @@ Dir "<DIR>" bzip2 "<PROGRAM_PATH>"; lzma "<PROGRAM_PATH>"; uncompressed "<PROGRAM_PATH>"; + ischroot "<PROGRAM_PATH>"; solvers "<LIST>"; // of directories planners "<LIST>"; // of directories @@ -561,6 +567,7 @@ Debug APT::Progress::PackageManagerFd "<BOOL>"; SetupAPTPartialDirectory::AssumeGood "<BOOL>"; Locking "<BOOL>"; + Phasing "<BOOL>"; }; pkgCacheGen @@ -843,3 +850,6 @@ Rred::Compress "<STRING>"; APT::Internal::OpProgress::Absolute "<BOOL>"; APT::Color "<BOOL>"; + +update-manager::always-include-phased-updates "<BOOL>"; +update-manager::never-include-phased-updates "<BOOL>"; diff --git a/test/integration/framework b/test/integration/framework index 3973ad863..696fcd8cd 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -484,6 +484,8 @@ EOF # Allow release files to be 10 hours in the future, rather than 10 seconds echo 'Acquire::Max-FutureTime "'$((10 * 60 * 60))'";' > rootdir/etc/apt/apt.conf.d/future-time + echo 'APT::Machine-ID "912e43bd1c1d4ba481f9f8ccab25f9ee";' > rootdir/etc/apt/apt.conf.d/machine-id + configcompression '.' 'gz' #'bz2' 'lzma' 'xz' confighashes 'SHA256' # these are tests, not security best-practices @@ -505,6 +507,7 @@ EOF # Make dpkg inherit testing path echo 'DPkg::Path "";' >> aptconfig.conf + echo 'Dir::Bin::ischroot "/bin/false";' >> aptconfig.conf # Make gcov shut up export GCOV_ERROR_FILE=/dev/null diff --git a/test/integration/test-phased-updates b/test/integration/test-phased-updates new file mode 100755 index 000000000..50f151f79 --- /dev/null +++ b/test/integration/test-phased-updates @@ -0,0 +1,272 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" + +setupenvironment +echo 'Debug::Phasing "1";' > rootdir/etc/apt/apt.conf.d/debug-phasing +configarchitecture 'i386' 'armel' + + +insertinstalledpackage 'phased1' 'all' '1' +insertinstalledpackage 'phased2' 'all' '1' + +insertpackage 'unstable' 'phased1' 'all' '10' 'Phased-Update-Percentage: 10' +insertpackage 'unstable' 'phased2' 'all' '10' 'Phased-Update-Percentage: 10' +insertpackage 'unstable' 'phased3' 'all' '10' 'Phased-Update-Percentage: 10' + +insertpackage 'unstable' 'phased1' 'all' '100' 'Phased-Update-Percentage: 100' +insertpackage 'unstable' 'phased2' 'all' '100' 'Phased-Update-Percentage: 100' +insertpackage 'unstable' 'phased3' 'all' '100' 'Phased-Update-Percentage: 100' + +insertpackage 'unstable' 'phased1' 'all' '50' 'Phased-Update-Percentage: 50' +insertpackage 'unstable' 'phased2' 'all' '50' 'Phased-Update-Percentage: 50' +insertpackage 'unstable' 'phased3' 'all' '50' 'Phased-Update-Percentage: 50' + +setupaptarchive + +msgmsg "Basic test" +testsuccessequal "phased1: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 1 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased2: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 1 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 1 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased3: + Installed: (none) + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages" aptcache policy phased1 phased2 phased3 + +msgmsg "Test for always-include-phased-updates" +for always in Update-Manager::Always-Include-Phased-Updates APT::Get::Always-Include-Phased-Updates; do +testsuccessequal "phased1: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased2: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased3: + Installed: (none) + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages" aptcache policy phased1 phased2 phased3 -o $always=true +done + +msgmsg "Test for never-include-phased-updates" +for never in Update-Manager::Never-Include-Phased-Updates APT::Get::Never-Include-Phased-Updates; do +testsuccessequal "phased1: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 1 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 1 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased2: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 1 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 1 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased3: + Installed: (none) + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages" aptcache policy phased1 phased2 phased3 -o $never=true +done + +msgmsg "Test that being in a chroot equals always-include-phased-updates" +testsuccessequal "phased1: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased2: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy phased1 phased2 -o Dir::Bin::ischroot=/bin/true + +msgmsg "Test that empty machine-id equals always-include-phased-updates" +testsuccessequal "phased1: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased2: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy phased1 phased2 -o Dir::Etc::machine-id=/dev/null -o APT::Machine-Id="" + +msgmsg "Test that never-include-phased-updates trumps empty machine-id" +testsuccessequal "phased1: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 1 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 1 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased2: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 1 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 1 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy phased1 phased2 -o Dir::Etc::machine-id=/dev/null -o APT::Machine-Id="" -o APT::Get::Never-Include-Phased-Updates=1 + + +msgmsg "Test that SOURCE_DATE_EPOCH set equals always-include-phased-updates" +export SOURCE_DATE_EPOCH=0 +testsuccessequal "phased1: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased2: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 500 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy phased1 phased2 +unset SOURCE_DATE_EPOCH + +msgmsg "Test that different machine-id produces different outcome" +testsuccessequal "phased1: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 1 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status +phased2: + Installed: 1 + Candidate: 100 + Version table: + 100 500 + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 50 500 (phased 50%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + 10 1 (phased 10%) + 500 file:${TMPWORKINGDIRECTORY}/aptarchive unstable/main all Packages + *** 1 100 + 100 ${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status" aptcache policy phased1 phased2 -o apt::machine-id="00000000000000000000000000000000" |