Re: Using python-apt's apt_pkg with a chroot

Sebastiaan Couwenberg <[email protected]> Tue, 2 Dec 2025 19:44:29 +0100
Newsgroups gmane.linux.debian.apt.devel
Message-ID <[email protected]>
On 12/2/25 7:17 PM, Johannes Schauer Marin Rodrigues wrote:
> Quoting Sebastiaan Couwenberg (2025-12-02 18:36:00)
>> Using python-apt's apt_pkg with a chroot turns out to be non-trivial unlike apt.cache.
>>
>> I'm running a script [0] on a trixie system and need to interact with the cache in a testing chroot.
>>
>> The chroot is created with mmdebstrap --mode=unshare, and the script is run via unshare as well.
> 
> maybe this is an XY problem.
> 
> Why do you need a full chroot for something that is as far as I get from the
> script just a "I want apt to resolve the dependencies with my custom
> sources.list"? This sounds like something like chdist is doing?

I want to use apt to resolve dependencies for packages (both source & binary) in testing (and unstable), but the code won't be running on a testing (or unstable) system.

See #1120799 for context.

> Maybe the mmdebstrap man page has an example which helps you. It is a snippet
> which is the very bare-bones of what mmdebstrap does with a few thousand more
> lines of code:
> 
>      mkdir -p "$2/etc/apt" "$2/var/cache" "$2/var/lib"
>      cat << END > "$2/apt.conf"
>      Apt::Architecture "$(dpkg --print-architecture)";
>      Apt::Architectures "$(dpkg --print-architecture)";
>      Dir "$(cd "$2" && pwd)";
>      Dir::Etc::Trusted "$(eval "$(apt-config shell v Dir::Etc::Trusted/f)"; printf %s "$v")";
>      Dir::Etc::TrustedParts "$(eval "$(apt-config shell v Dir::Etc::TrustedParts/d)"; printf %s "$v"
> 
>      END
>      echo "deb http://deb.debian.org/debian/ $1 main" > "$2/etc/apt/sources.list"
>      APT_CONFIG="$2/apt.conf" apt-get update
>      APT_CONFIG="$2/apt.conf" apt-get --yes --download-only install '?essential'
>      for f in "$2"/var/cache/apt/archives/*.deb; do dpkg-deb --extract "$f" "$2"; done
>      chroot "$2" sh -c "dpkg --install --force-depends /var/cache/apt/archives/*.deb"

How would python-apt's apt_pkg use this?

>> Setting RootDir in the config does not result in the chroot paths to be used:
> 
> I think you need Dir.

Not according to the apt.conf(5):

"
   The configuration item RootDir has a special meaning. If set, all paths will be relative to RootDir, even paths that are specified absolutely. So, for instance, if RootDir is set to /tmp/staging and Dir::State::status is set to /var/lib/dpkg/status, then the status file will be looked up in /tmp/staging/var/lib/dpkg/status. If you want to prefix only relative paths, set Dir instead.
"

Using Dir fails in the same way:

  $ unshare --map-auto --map-user=65536 --map-group=65536 --keep-caps -- ~/git/release-team/release.debian.org/bin/resolve-dependencies.py -vdp opencv -u 2>&1 | tee /tmp/resolve-dependencies.log
  Resolving dependencies for: opencv
  Chroot already exists: /var/tmp/testing-chroot
  config:
  Dir "/var/tmp/testing-chroot";

  list:
  [<apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie-updates' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://security.debian.org/debian-security/' dist='trixie-security' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie-backports' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://debug.mirrors.debian.org/debian-debug/' dist='trixie-debug' is_trusted='1'>]
  Reading package lists... Done
  Building dependency tree... Done
  Reading state information... Done
  Traceback (most recent call last):
    File "/home/bas/git/release-team/release.debian.org/bin/resolve-dependencies.py", line 216, in <module>
      sys.exit(main())
               ~~~~^^
    File "/home/bas/git/release-team/release.debian.org/bin/resolve-dependencies.py", line 212, in main
      return resolve_dependencies()
    File "/home/bas/git/release-team/release.debian.org/bin/resolve-dependencies.py", line 97, in resolve_dependencies
      cache.update(apt.progress.text, source_list)
      ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  apt_pkg.Error: E:Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied), E:Unable to lock directory /var/lib/apt/lists/

>>    apt_pkg.Error: E:Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied), E:Unable to lock directory /var/lib/apt/lists/
> 
> This sounds like you are trying to access something created for the unshared
> user as the normal user?

No, this is python-apt running outside the chroot as also hinted by the sources.list for trixie.

Running the script directory instead of via unshare fails in the same way because my unprivileged user is not allowed to write those directories:

  $ ~/git/release-team/release.debian.org/bin/resolve-dependencies.py -vdp opencv -u 2>&1 | tee /tmp/resolve-dependencies.log
  Resolving dependencies for: opencv
  Chroot already exists: /var/tmp/testing-chroot
  config:
  RootDir "/var/tmp/testing-chroot";

  list:
  [<apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie-updates' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://security.debian.org/debian-security/' dist='trixie-security' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie-backports' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://debug.mirrors.debian.org/debian-debug/' dist='trixie-debug' is_trusted='1'>]
  Reading package lists... Done
  Building dependency tree... Done
  Reading state information... Done
  Traceback (most recent call last):
    File "/home/bas/git/release-team/release.debian.org/bin/resolve-dependencies.py", line 216, in <module>
      sys.exit(main())
               ~~~~^^
    File "/home/bas/git/release-team/release.debian.org/bin/resolve-dependencies.py", line 212, in main
      return resolve_dependencies()
    File "/home/bas/git/release-team/release.debian.org/bin/resolve-dependencies.py", line 97, in resolve_dependencies
      cache.update(apt.progress.text, source_list)
      ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  apt_pkg.Error: E:Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied), E:Unable to lock directory /var/lib/apt/lists/

Running the script as root does not fail on update, but it works with the trixie data instead of the testing:

  $ su -c "~bas/git/release-team/release.debian.org/bin/resolve-dependencies.py -vdp opencv -u" 2>&1 | tee /tmp/resolve-dependencies.log
  Password:
  Resolving dependencies for: opencv
  Chroot already exists: /var/tmp/testing-chroot
  config:
  RootDir "/var/tmp/testing-chroot";

  list:
  [<apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie-updates' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://security.debian.org/debian-security/' dist='trixie-security' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://ftp.nl.debian.org/debian/' dist='trixie-backports' is_trusted='1'>,
   <apt_pkg.MetaIndex object: type='deb', uri:'http://debug.mirrors.debian.org/debian-debug/' dist='trixie-debug' is_trusted='1'>]
  Reading package lists... Done
  Building dependency tree... Done
  Reading state information... Done
  Error in function start
  TypeError: AcquireProgress.start() missing 1 required positional argument: 'self'
  [...]
  Error in function stop
  TypeError: AcquireProgress.stop() missing 1 required positional argument: 'self'
  Package: opencv
  Version: 4.10.0+dfsg-5
  Build-Depends: [...]

This the version in trixie, I need the data for forky:

  $ rmadison -s stable,testing opencv
  opencv     | 4.10.0+dfsg-5 | stable     | source
  opencv     | 4.10.0+dfsg-6 | testing    | source

Kind Regards,

Bas

-- 
  PGP Key ID: 4096R/6750F10AE88D4AF1
Fingerprint: 8182 DE41 7056 408D 6146  50D1 6750 F10A E88D 4AF1