Browse Source

allow fetcher setup without directory creation

apt-get download and changelog as well as apt-helper reuse the acquire
system for their own proposes without requiring the directories the
fetcher wants to create, which is a problem if you run them as non-root
and the directories do not exist as it greets you with:
E: Archives directory /var/cache/apt/archives/partial is missing. -
Acquire (13: Permission denied)

Closes: 762898
tags/debian/1.1.exp4
David Kalnischkies 7 years ago
parent
commit
43acd01979
7 changed files with 66 additions and 28 deletions
  1. +17
    -13
      apt-pkg/acquire.cc
  2. +4
    -1
      apt-pkg/acquire.h
  3. +5
    -4
      cmdline/apt-get.cc
  4. +2
    -1
      cmdline/apt-helper.cc
  5. +6
    -0
      test/integration/test-apt-get-changelog
  6. +25
    -2
      test/integration/test-apt-get-download
  7. +7
    -7
      test/integration/test-apt-helper

+ 17
- 13
apt-pkg/acquire.cc View File

@@ -73,23 +73,27 @@ pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : LockFD(-1), Queues(0), Wor
// ---------------------------------------------------------------------
/* Do everything needed to be a complete Acquire object and report the
success (or failure) back so the user knows that something is wrong… */
bool pkgAcquire::Setup(pkgAcquireStatus *Progress, string const &Lock)
bool pkgAcquire::Setup(pkgAcquireStatus *Progress, string const &Lock,
bool const createDirectories)
{
Log = Progress;

// check for existence and possibly create auxiliary directories
string const listDir = _config->FindDir("Dir::State::lists");
string const partialListDir = listDir + "partial/";
string const archivesDir = _config->FindDir("Dir::Cache::Archives");
string const partialArchivesDir = archivesDir + "partial/";

if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false &&
CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false)
return _error->Errno("Acquire", _("List directory %spartial is missing."), listDir.c_str());

if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::Cache"), partialArchivesDir) == false &&
CreateAPTDirectoryIfNeeded(archivesDir, partialArchivesDir) == false)
return _error->Errno("Acquire", _("Archives directory %spartial is missing."), archivesDir.c_str());
if (createDirectories == true)
{
string const listDir = _config->FindDir("Dir::State::lists");
string const partialListDir = listDir + "partial/";
string const archivesDir = _config->FindDir("Dir::Cache::Archives");
string const partialArchivesDir = archivesDir + "partial/";

if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::State"), partialListDir) == false &&
CreateAPTDirectoryIfNeeded(listDir, partialListDir) == false)
return _error->Errno("Acquire", _("List directory %spartial is missing."), listDir.c_str());

if (CreateAPTDirectoryIfNeeded(_config->FindDir("Dir::Cache"), partialArchivesDir) == false &&
CreateAPTDirectoryIfNeeded(archivesDir, partialArchivesDir) == false)
return _error->Errno("Acquire", _("Archives directory %spartial is missing."), archivesDir.c_str());
}

if (Lock.empty() == true || _config->FindB("Debug::NoLocking", false) == true)
return true;


+ 4
- 1
apt-pkg/acquire.h View File

@@ -352,8 +352,11 @@ class pkgAcquire
* \param Lock defines a lock file that should be acquired to ensure
* only one Acquire class is in action at the time or an empty string
* if no lock file should be used.
* \param createDirectories can be used to disable the creation of directories,
* e.g. if the fetcher is used with different directories later on
*/
bool Setup(pkgAcquireStatus *Progress = NULL, std::string const &Lock = "");
bool Setup(pkgAcquireStatus *Progress = NULL, std::string const &Lock = "",
bool const createDirectories = true);

void SetLog(pkgAcquireStatus *Progress) { Log = Progress; }



+ 5
- 4
cmdline/apt-get.cc View File

@@ -626,14 +626,14 @@ static bool DoDownload(CommandLine &CmdL)

APT::CacheSetHelper helper(c0out);
APT::VersionSet verset = APT::VersionSet::FromCommandLine(Cache,
CmdL.FileList + 1, APT::VersionSet::CANDIDATE, helper);
CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper);

if (verset.empty() == true)
return false;

AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet", 0));
pkgAcquire Fetcher;
if (Fetcher.Setup(&Stat) == false)
if (Fetcher.Setup(&Stat, "", false) == false)
return false;

pkgRecords Recs(Cache);
@@ -1536,7 +1536,7 @@ static bool DoChangelog(CommandLine &CmdL)
APT::CacheSetHelper helper(c0out);
APT::VersionList verset = APT::VersionList::FromCommandLine(Cache,
CmdL.FileList + 1, APT::VersionList::CANDIDATE, helper);
CmdL.FileList + 1, APT::CacheSetHelper::CANDIDATE, helper);
if (verset.empty() == true)
return false;
pkgAcquire Fetcher;
@@ -1551,7 +1551,8 @@ static bool DoChangelog(CommandLine &CmdL)
}

AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
Fetcher.Setup(&Stat);
if (Fetcher.Setup(&Stat, "",false) == false)
return false;

bool const downOnly = _config->FindB("APT::Get::Download-Only", false);



+ 2
- 1
cmdline/apt-helper.cc View File

@@ -51,7 +51,8 @@ static bool DoDownloadFile(CommandLine &CmdL)

pkgAcquire Fetcher;
AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0));
Fetcher.Setup(&Stat);
if (Fetcher.Setup(&Stat, "", false) == false)
return false;
std::string download_uri = CmdL.FileList[1];
std::string targetfile = CmdL.FileList[2];
std::string hash;


+ 6
- 0
test/integration/test-apt-get-changelog View File

@@ -13,6 +13,12 @@ setupaptarchive --no-update
changetowebserver
testsuccess aptget update

# simulate normal user with non-existent root-owned directories
rm -rf rootdir/var/cache/apt/archives/
mkdir rootdir/var/cache/apt/archives/
addtrap 'prefix' "chmod -f -R +w $PWD/rootdir/var/cache/apt/archives || true;"
chmod -R -w rootdir/var/cache/apt/archives

echo 'Apt::Changelogs::Server "http://localhost:8080/";' > rootdir/etc/apt/apt.conf.d/changelog.conf

testequal "'http://localhost:8080//pool/apt_1.0/changelog'" aptget changelog apt --print-uris


+ 25
- 2
test/integration/test-apt-get-download View File

@@ -20,10 +20,19 @@ testdownload() {
fi
msgtest "Test download of package file $1 with" "$APT"
testsuccess --nomsg aptget download ${APT}
testsuccess test -f $1
rm $1
testsuccess test -f "$1"
rm -f "$1"
}

# normal case as "root"
testdownload apt_2.0_all.deb apt

# simulate normal user with non-existent root-owned directories
rm -rf rootdir/var/cache/apt/archives/
mkdir rootdir/var/cache/apt/archives/
addtrap 'prefix' "chmod -f -R +w $PWD/rootdir/var/cache/apt/archives || true;"
chmod -R -w rootdir/var/cache/apt/archives

# normal case(es)
testdownload apt_1.0_all.deb apt stable
testdownload apt_2.0_all.deb apt
@@ -45,3 +54,17 @@ rm -f apt_1.0_all.deb apt_2.0_all.deb
testsuccess aptget download apt apt apt/unstable apt=2.0
testsuccess test -s apt_2.0_all.deb

# restore "root" rights
chmod -f -R +w $PWD/rootdir/var/cache/apt/archives
rm -rf rootdir/var/cache/apt/archives/

# file: debs aren't copied to archives, so change to http which obviously are
changetowebserver
testsuccess aptget update

# test with already stored deb
testsuccess aptget install -d apt
testsuccess test -s rootdir/var/cache/apt/archives/apt_2.0_all.deb
mv aptarchive/pool/apt_2.0_all.deb aptarchive/pool/apt_2.0_all.deb.gone
testdownload apt_2.0_all.deb apt
mv aptarchive/pool/apt_2.0_all.deb.gone aptarchive/pool/apt_2.0_all.deb

+ 7
- 7
test/integration/test-apt-helper View File

@@ -5,30 +5,30 @@ TESTDIR=$(readlink -f $(dirname $0))
. $TESTDIR/framework

setupenvironment
configarchitecture "i386"
configarchitecture 'i386'

changetohttpswebserver

test_apt_helper_download() {
echo "foo" > aptarchive/foo
echo 'foo' > aptarchive/foo

msgtest 'apt-file download-file md5sum'
msgtest 'apt-file download-file' 'md5sum'
apthelper -qq download-file http://localhost:8080/foo foo2 MD5Sum:d3b07384d113edec49eaa6238ad5ff00 && msgpass || msgfail
testfileequal foo2 'foo'

msgtest 'apt-file download-file sha1'
msgtest 'apt-file download-file' 'sha1'
apthelper -qq download-file http://localhost:8080/foo foo1 SHA1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 && msgpass || msgfail
testfileequal foo1 'foo'

msgtest 'apt-file download-file sha256'
msgtest 'apt-file download-file' 'sha256'
apthelper -qq download-file http://localhost:8080/foo foo3 SHA256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c && msgpass || msgfail
testfileequal foo3 'foo'

msgtest 'apt-file download-file no-hash'
msgtest 'apt-file download-file' 'no-hash'
apthelper -qq download-file http://localhost:8080/foo foo4 && msgpass || msgfail
testfileequal foo4 'foo'
msgtest 'apt-file download-file wrong hash'
msgtest 'apt-file download-file' 'wrong hash'
if ! apthelper -qq download-file http://localhost:8080/foo foo5 MD5Sum:aabbcc 2>&1 2> download.stderr; then
msgpass
else


Loading…
Cancel
Save