3

As part of an OS deployment, I need to maintain sets of debian packages independently of the host operating system. It's pretty straightforward to override the Apt settings for the cache and lists, but not the dpkg setting for the admindir. For example:

apt-get -o Dir::Etc::Sourcelist='/path/to/sources.list' \
        -o Dir::Cache::Archives='/path/to/cache/apt/archives' \
        -o Dir::State::Lists='/path/to/lib/apt/lists' \
        -o DPkg::Options::='--admindir=/path/to/lib/dpkg' update

This correctly reads my sources out of /path/to/sources.list, and builds the package available lists in /path/to/lib/apt/lists/*. However, at the end of the update command, I still get the following error:

E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)

This is despite the last option attempting to override the default dpkg admindir of '/var/lib/dpkg'. What am I doing wrong? According to guides like this, what I'm doing with DPkg::Options ought to work.

Alex G
  • 376
  • 1
  • 4
  • 13

1 Answers1

1

Yeah, one would think that this was about the dpkg --admindir option, but in this case it turns out that apt-get is deriving the AdminDir from the Dir::State::status value. I ended up downloading the source code for apt, and found the following snippet in ./apt-pkg/deb/debsystem.cc.

// Create the lockfile
string AdminDir = flNotFile(_config->Find("Dir::State::status"));
d->LockFD = GetLock(AdminDir + "lock");
if (d->LockFD == -1)
{
   if (errno == EACCES || errno == EAGAIN)
      return _error->Error(_("Unable to lock the administration directory (%s), "
                             "is another process using it?"),AdminDir.c_str());
   else
      return _error->Error(_("Unable to lock the administration directory (%s), "
                             "are you root?"),AdminDir.c_str());
}

So for the purpose of this exercise setting Dir::State::status to /foo/bar/status will translate into the AdminDir /foo/bar and the lock file /foo/bar/lock.

I haven't investigated this further, but for me apt-get assumed that the status file already existed. Creating an empty file using touch worked well enough to at least not make apt-get complain.

andol
  • 6,848
  • 28
  • 43