diff options
author | David Kalnischkies <david@kalnischkies.de> | 2016-05-14 10:43:03 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2016-05-16 16:17:54 +0200 |
commit | eb1f04dda07c2b69549ad9fd793cca0e91841b3e (patch) | |
tree | 473136bd9eb4161f1201b746c1ed0a21c357aa27 | |
parent | fd78974020e23679e9e810cf01dc5c8f3012bb8a (diff) | |
download | apt-eb1f04dda07c2b69549ad9fd793cca0e91841b3e.tar.gz |
show final solution in --no-download --fix-missing mode
This commit moves the creation of the fetcher and with it the
calculation of the filenames before the code generation the various
lists detailing the solution. This means that simulation comes even so
slightly closer to a real run as it will require and parse the package
indexes for filenames and queuing of URIs, so that a simulation "using"
an unavailable download method actually fails now.
The real benefit of this change is through that the rather special but
nontheless handy --no-download --fix-missing mode now actually shows
what the solution is it will apply to the system rather than the
solution it would if it could download all not-downloaded packages.
-rw-r--r-- | apt-private/private-install.cc | 211 | ||||
-rwxr-xr-x | test/integration/test-bug-602412-dequote-redirect | 17 | ||||
-rwxr-xr-x | test/integration/test-compressed-indexes | 2 |
3 files changed, 120 insertions, 110 deletions
diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc index 44980ceed..213b3b90c 100644 --- a/apt-private/private-install.cc +++ b/apt-private/private-install.cc @@ -77,38 +77,86 @@ bool CheckNothingBroken(CacheFile &Cache) /*{{{*/ // --------------------------------------------------------------------- /* This displays the informative messages describing what is going to happen and then calls the download routines */ -bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) +static void RemoveDownloadNeedingItemsFromFetcher(pkgAcquire &Fetcher, bool &Transient) { - if (_config->FindB("APT::Get::Purge",false) == true) + for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();) { - pkgCache::PkgIterator I = Cache->PkgBegin(); - for (; I.end() == false; ++I) + if ((*I)->Local == true) { - if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete) - Cache->MarkDelete(I,true); + ++I; + continue; } + + // Close the item and check if it was found in cache + (*I)->Finished(); + if ((*I)->Complete == false) + Transient = true; + + // Clear it out of the fetch list + delete *I; + I = Fetcher.ItemsBegin(); } - - bool Hold = false; - bool Downgrade = false; - bool Essential = false; - +} +bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) +{ + if (_config->FindB("APT::Get::Purge", false) == true) + for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; ++I) + if (Cache[I].Delete() == true && Cache[I].Purge() == false) + Cache->MarkDelete(I,true); + + // Create the download object + aptAcquireWithTextStatus Fetcher; + if (_config->FindB("APT::Get::Print-URIs", false) == true) + { + // force a hashsum for compatibility reasons + _config->CndSet("Acquire::ForceHash", "md5sum"); + } + else if (Fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false) + return false; + + // Read the source list + if (Cache.BuildSourceList() == false) + return false; + pkgSourceList * const List = Cache.GetSourceList(); + + // Create the text record parser + pkgRecords Recs(Cache); + if (_error->PendingError() == true) + return false; + + // Create the package manager and prepare to download + std::unique_ptr<pkgPackageManager> PM(_system->CreatePM(Cache)); + if (PM->GetArchives(&Fetcher,List,&Recs) == false || + _error->PendingError() == true) + return false; + + if (_config->FindB("APT::Get::Fix-Missing",false) == true && + _config->FindB("APT::Get::Download",true) == false) + { + bool Missing = false; + RemoveDownloadNeedingItemsFromFetcher(Fetcher, Missing); + if (Missing) + PM->FixMissing(); + Fetcher.Shutdown(); + if (PM->GetArchives(&Fetcher,List,&Recs) == false || + _error->PendingError() == true) + return false; + } + // Show all the various warning indicators ShowDel(c1out,Cache); ShowNew(c1out,Cache); if (ShwKept == true) ShowKept(c1out,Cache); - Hold = !ShowHold(c1out,Cache); + bool const Hold = !ShowHold(c1out,Cache); if (_config->FindB("APT::Get::Show-Upgraded",true) == true) ShowUpgraded(c1out,Cache); - Downgrade = !ShowDowngraded(c1out,Cache); + bool const Downgrade = !ShowDowngraded(c1out,Cache); + bool Essential = false; if (_config->FindB("APT::Get::Download-Only",false) == false) Essential = !ShowEssential(c1out,Cache); - // All kinds of failures - bool Fail = (Essential || Downgrade || Hold); - Stats(c1out,Cache); // Sanity check @@ -127,6 +175,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) return _error->Error(_("Packages need to be removed but remove is disabled.")); // Fail safe check + bool const Fail = (Essential || Downgrade || Hold); if (_config->FindI("quiet",0) >= 2 || _config->FindB("APT::Get::Assume-Yes",false) == true) { @@ -159,37 +208,11 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) return _error->Error(_("Internal error, Ordering didn't finish")); return true; } - - // Create the text record parser - pkgRecords Recs(Cache); - if (_error->PendingError() == true) - return false; - - // Create the download object - aptAcquireWithTextStatus Fetcher; - if (_config->FindB("APT::Get::Print-URIs", false) == true) - { - // force a hashsum for compatibility reasons - _config->CndSet("Acquire::ForceHash", "md5sum"); - } - else if (Fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false) - return false; - - // Read the source list - if (Cache.BuildSourceList() == false) - return false; - pkgSourceList *List = Cache.GetSourceList(); - - // Create the package manager and prepare to download - std::unique_ptr<pkgPackageManager> PM(_system->CreatePM(Cache)); - if (PM->GetArchives(&Fetcher,List,&Recs) == false || - _error->PendingError() == true) - return false; // Display statistics - unsigned long long FetchBytes = Fetcher.FetchNeeded(); - unsigned long long FetchPBytes = Fetcher.PartialPresent(); - unsigned long long DebBytes = Fetcher.TotalNeeded(); + auto const FetchBytes = Fetcher.FetchNeeded(); + auto const FetchPBytes = Fetcher.PartialPresent(); + auto const DebBytes = Fetcher.TotalNeeded(); if (DebBytes != Cache->DebSize()) { c0out << DebBytes << ',' << Cache->DebSize() << std::endl; @@ -220,12 +243,22 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"), SizeToStr(-1*Cache->UsrSize()).c_str()); - if (_error->PendingError() == true) + if (CheckFreeSpaceBeforeDownload(_config->FindDir("Dir::Cache::Archives"), (FetchBytes - FetchPBytes)) == false) return false; - if (CheckFreeSpaceBeforeDownload(_config->FindDir("Dir::Cache::Archives"), (FetchBytes - FetchPBytes)) == false) + if (_error->PendingError() == true) return false; + // Just print out the uris an exit if the --print-uris flag was used + if (_config->FindB("APT::Get::Print-URIs") == true) + { + pkgAcquire::UriIterator I = Fetcher.UriBegin(); + for (; I != Fetcher.UriEnd(); ++I) + std::cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << + I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl; + return true; + } + if (Essential == true && Safety == true && _config->FindB("APT::Get::allow-remove-essential", false) == false) { if (_config->FindB("APT::Get::Trivial-Only",false) == true) @@ -243,36 +276,26 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) { c2out << _("Abort.") << std::endl; exit(1); - } + } } else - { + { // Prompt to continue if (Ask == true || Fail == true) - { + { if (_config->FindB("APT::Get::Trivial-Only",false) == true) return _error->Error(_("Trivial Only specified but this is not a trivial operation.")); - + if (_config->FindI("quiet",0) < 2 && _config->FindB("APT::Get::Assume-Yes",false) == false) { - if (YnPrompt(_("Do you want to continue?")) == false) + if (YnPrompt(_("Do you want to continue?")) == false) { c2out << _("Abort.") << std::endl; exit(1); - } - } - } - } - - // Just print out the uris an exit if the --print-uris flag was used - if (_config->FindB("APT::Get::Print-URIs") == true) - { - pkgAcquire::UriIterator I = Fetcher.UriBegin(); - for (; I != Fetcher.UriEnd(); ++I) - std::cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << - I->Owner->FileSize << ' ' << I->Owner->HashSum() << std::endl; - return true; + } + } + } } if (!CheckAuth(Fetcher, true)) @@ -282,46 +305,15 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) after. */ if (_config->FindB("APT::Get::Download-Only",false) == true) _system->UnLock(); - + // Run it + bool Failed = false; while (1) { bool Transient = false; - if (_config->FindB("APT::Get::Download",true) == false) - { - for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();) - { - if ((*I)->Local == true) - { - ++I; - continue; - } - - // Close the item and check if it was found in cache - (*I)->Finished(); - if ((*I)->Complete == false) - Transient = true; - - // Clear it out of the fetch list - delete *I; - I = Fetcher.ItemsBegin(); - } - } - - bool Failed = false; if (AcquireRun(Fetcher, 0, &Failed, &Transient) == false) return false; - /* If we are in no download mode and missing files and there were - 'failures' then the user must specify -m. Furthermore, there - is no such thing as a transient error in no-download mode! */ - if (Transient == true && - _config->FindB("APT::Get::Download",true) == false) - { - Transient = false; - Failed = true; - } - if (_config->FindB("APT::Get::Download-Only",false) == true) { if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false) @@ -329,15 +321,13 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) c1out << _("Download complete and in download only mode") << std::endl; return true; } - + if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false) - { return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?")); - } - + if (Transient == true && Failed == true) return _error->Error(_("--fix-missing and media swapping is not currently supported")); - + // Try to deal with missing package files if (Failed == true && PM->FixMissing() == false) { @@ -345,23 +335,26 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) return _error->Error(_("Aborting install.")); } + auto const progress = APT::Progress::PackageManagerProgressFactory(); _system->UnLock(); - - APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory(); - pkgPackageManager::OrderResult Res = PM->DoInstall(progress); + pkgPackageManager::OrderResult const Res = PM->DoInstall(progress); delete progress; if (Res == pkgPackageManager::Failed || _error->PendingError() == true) return false; if (Res == pkgPackageManager::Completed) break; - + + _system->Lock(); + // Reload the fetcher object and loop again for media swapping Fetcher.Shutdown(); if (PM->GetArchives(&Fetcher,List,&Recs) == false) return false; - - _system->Lock(); + + Failed = false; + if (_config->FindB("APT::Get::Download",true) == false) + RemoveDownloadNeedingItemsFromFetcher(Fetcher, Failed); } std::set<std::string> const disappearedPkgs = PM->GetDisappearedPackages(); diff --git a/test/integration/test-bug-602412-dequote-redirect b/test/integration/test-bug-602412-dequote-redirect index 3d88baaef..b4da876cb 100755 --- a/test/integration/test-bug-602412-dequote-redirect +++ b/test/integration/test-bug-602412-dequote-redirect @@ -7,6 +7,8 @@ setupenvironment configarchitecture 'amd64' buildsimplenativepackage 'unrelated' 'all' '0.5~squeeze1' 'unstable' +buildsimplenativepackage 'unrelated2' 'all' '0.5~squeeze1' 'unstable' +insertinstalledpackage 'unrelated2' 'all' '0.1' setupaptarchive --no-update changetowebserver -o aptwebserver::redirect::replace::/pool/=/newpool/ \ @@ -42,3 +44,18 @@ for CODE in 301 302 307; do testrun "$CODE" "https://localhost:${APTHTTPSPORT}" rm -rf rootdir/var/lib/apt/lists rootdir/var/cache/apt/archives done + +testsuccess apt update +testsuccess aptget install unrelated --download-only +testsuccessequal 'Reading package lists... +Building dependency tree... +Calculating upgrade... +The following NEW packages will be installed: + unrelated +The following packages have been kept back: + unrelated2 +0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded. +Inst unrelated (0.5~squeeze1 unstable [all]) +Conf unrelated (0.5~squeeze1 unstable [all])' aptget dist-upgrade unrelated --no-download --fix-missing -s +testsuccess aptget dist-upgrade unrelated --no-download --fix-missing -y +testdpkginstalled unrelated diff --git a/test/integration/test-compressed-indexes b/test/integration/test-compressed-indexes index 7ddf2e2e2..d544ac89f 100755 --- a/test/integration/test-compressed-indexes +++ b/test/integration/test-compressed-indexes @@ -70,7 +70,7 @@ The following NEW packages will be installed: testpkg 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Inst testpkg (1.0 unstable [i386]) -Conf testpkg (1.0 unstable [i386])' aptget install testpkg -s +Conf testpkg (1.0 unstable [i386])' aptget install testpkg -s -o Debug::pkgAcquire::Auth=0 -o Debug::pkgAcquire::Worker=0 rm -f rootdir/var/cache/apt/pkgcache.bin rootdir/var/cache/apt/srcpkgcache.bin testsuccessequal "$GOODSHOW" aptcache show testpkg testsuccessequal "$GOODSHOW" aptcache show testpkg |