From b58047e0d8fa8e7d5adca2a24f2ca3ba2596e0ad Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 14 Apr 2016 22:02:07 +0200 Subject: ensure outdated files are dropped without lists-cleanup Tested via (newly) empty index files, but effects also files dropped from the repository or an otherwise changed repository config. --- apt-pkg/acquire-item.cc | 54 ++++++++++++++++++++++++++-- test/integration/test-apt-update-empty-files | 18 ++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index bc5e91fed..874539625 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -519,6 +519,41 @@ class APT_HIDDEN NoActionItem : public pkgAcquire::Item /*{{{*/ } }; /*}}}*/ +class APT_HIDDEN CleanupItem : public pkgAcqTransactionItem /*{{{*/ +/* This class ensures that a file which was configured but isn't downloaded + for various reasons isn't kept in an old version in the lists directory. + In a way its the reverse of NoActionItem as it helps with removing files + even if the lists-cleanup is deactivated. */ +{ + public: + virtual std::string DescURI() const APT_OVERRIDE {return Target.URI;}; + virtual HashStringList GetExpectedHashes() const APT_OVERRIDE {return HashStringList();}; + + CleanupItem(pkgAcquire * const Owner, pkgAcqMetaClearSig * const TransactionManager, IndexTarget const &Target) : + pkgAcqTransactionItem(Owner, TransactionManager, Target) + { + Status = StatDone; + DestFile = GetFinalFileNameFromURI(Target.URI); + } + bool TransactionState(TransactionStates const state) APT_OVERRIDE + { + switch (state) + { + case TransactionStarted: + break; + case TransactionAbort: + break; + case TransactionCommit: + if (_config->FindB("Debug::Acquire::Transaction", false) == true) + std::clog << "rm " << DestFile << " # " << DescURI() << std::endl; + if (RemoveFile("TransItem::TransactionCommit", DestFile) == false) + return false; + break; + } + return true; + } +}; + /*}}}*/ // Acquire::Item::Item - Constructor /*{{{*/ APT_IGNORE_DEPRECATED_PUSH @@ -1113,10 +1148,12 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ // than invent an entirely new flag we would need to carry for all of eternity. if (Target->Option(IndexTarget::ARCHITECTURE) == "all") { - if (TransactionManager->MetaIndexParser->IsArchitectureSupported("all") == false) - continue; - if (TransactionManager->MetaIndexParser->IsArchitectureAllSupportedFor(*Target) == false) + if (TransactionManager->MetaIndexParser->IsArchitectureSupported("all") == false || + TransactionManager->MetaIndexParser->IsArchitectureAllSupportedFor(*Target) == false) + { + new CleanupItem(Owner, TransactionManager, *Target); continue; + } } bool trypdiff = Target->OptionBool(IndexTarget::PDIFFS); @@ -1126,13 +1163,17 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ { // optional targets that we do not have in the Release file are skipped if (Target->IsOptional) + { + new CleanupItem(Owner, TransactionManager, *Target); continue; + } std::string const &arch = Target->Option(IndexTarget::ARCHITECTURE); if (arch.empty() == false) { if (TransactionManager->MetaIndexParser->IsArchitectureSupported(arch) == false) { + new CleanupItem(Owner, TransactionManager, *Target); _error->Notice(_("Skipping acquire of configured file '%s' as repository '%s' doesn't support architecture '%s'"), Target->MetaKey.c_str(), TransactionManager->Target.Description.c_str(), arch.c_str()); continue; @@ -1141,7 +1182,10 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ // ignore silently as this is pretty much the same as just shipping an empty file. // if we don't know which architectures are supported, we do NOT ignore it to notify user about this if (TransactionManager->MetaIndexParser->IsArchitectureSupported("*undefined*") == false) + { + new CleanupItem(Owner, TransactionManager, *Target); continue; + } } Status = StatAuthError; @@ -1155,13 +1199,17 @@ void pkgAcqMetaBase::QueueIndexes(bool const verify) /*{{{*/ { if (hashes.usable() == false) { + new CleanupItem(Owner, TransactionManager, *Target); _error->Warning(_("Skipping acquire of configured file '%s' as repository '%s' provides only weak security information for it"), Target->MetaKey.c_str(), TransactionManager->Target.Description.c_str()); continue; } // empty files are skipped as acquiring the very small compressed files is a waste of time else if (hashes.FileSize() == 0) + { + new CleanupItem(Owner, TransactionManager, *Target); continue; + } } } diff --git a/test/integration/test-apt-update-empty-files b/test/integration/test-apt-update-empty-files index 42329bb4b..24e40f942 100755 --- a/test/integration/test-apt-update-empty-files +++ b/test/integration/test-apt-update-empty-files @@ -27,3 +27,21 @@ testsuccess apt update -o Debug::pkgAcquire::Worker=1 cp rootdir/tmp/testsuccess.output apt.output testfailure grep 'http:600.*Sources' apt.output testempty find rootdir/var/lib/apt/lists -name '*_Sources' + +msgmsg 'Test lists-cleanup on newly empty' +rm -rf rootdir/var/lib/apt/lists +insertsource 'unstable' 'apt' 'any' '1' +compressfile aptarchive/dists/unstable/main/source/Sources +generatereleasefiles +signreleasefiles +testsuccess apt update -o Debug::pkgAcquire::Worker=1 +cp rootdir/tmp/testsuccess.output apt.output +testsuccess grep 'http:600.*Sources' apt.output +echo -n > aptarchive/dists/unstable/main/source/Sources +compressfile aptarchive/dists/unstable/main/source/Sources +generatereleasefiles 'now + 1hour' +signreleasefiles +testsuccess apt update -o Debug::pkgAcquire::Worker=1 -o APT::Get::List-Cleanup=0 -o Debug::Acquire::Transaction=1 +cp rootdir/tmp/testsuccess.output apt.output +testfailure grep 'http:600.*Sources' apt.output +testempty find rootdir/var/lib/apt/lists -name '*_Sources' -- cgit v1.2.3