Utilities for carving out root filesystems/filesystem layers from Gentoo Linux systems
Project description
Egatrop
Installing
Ideally, through use of uv, it's a matter of running uv tool install egatrop.
What is it
Utilities for running the Gentoo Portage system, in a sense, "in reverse".
It's something like Nix's nix-copy-closure but for Gentoo.
That is, given an existing Gentoo system, create the dependency tree as it is for that particular system for some package or set of packages. Then it can either show you that dependency tree, or export the files installed by those packages to somewhere (some new root filesystem, for instance).
You can use the resulting filesystem tree as a container layer, or for making an initrd, or a rescue disk, or ...
What good does that do
Suppose you'd want to setup some minimal container root filesystem, with only postgresql-18, bash and busybox installed. And you want to have it be based on Gentoo, with its excellent customization system — say in this instance you want to leave out PostgreSQL's JIT so as not to end up shipping llvm in your container filesystem, and perhaps you're applying some custom patches on top of it.
Debian-based distros have debootstrap. Arch Linux has pacstrap. Gentoo has nothing like that, because there is no canonical setup; customizability is the whole point of Gentoo, so we'll first have to create a Gentoo system that contains PostgreSQL and other things we need, cooked to perfection.
Creating that Gentoo system is not the issue. Create a chroot, do the usual. Let's consider that done. But we don't want to ship that whole system, as it contains way way more than the minimally needed — it'll contain the Gentoo build system itself (including a whole compiler toolchain), some version of Python used for running emerge, it'll contain all the package definitions, etc. etc. None of that stuff is needed for running PostgreSQL. In our container we don't want the Gentoo base system, or any build-time dependency. We want something akin to Nix's nix-copy-closure, but for Gentoo.
quickpkg can't do that, because it doesn't follow dependencies.
Using emerge --emptytree --buildpkg and then extracting from the resultant packages won't achieve the goal either, as it will pull in the whole build chain and Gentoo system.
But with the egreme utility in this package, we can pull it off!
Dive right in
If you want to dive right in, just run egreme --help and take it from there. But a bit of reading on might save befuddlement later.
Example usages
Using the graph: A look at the dependency tree
Here's the dependency tree of the package set app-shells/bash + sys-apps/coreutils of some minimized Gentoo installation.
We specify the graph subcommand, as we just want to see the dependency graph for now.
We specify app-shells/bash and sys-apps/coreutils as positional arguments. They get resolved to the concrete versions as installed on that system. We could have passed those concrete specifications instead if we'd preferred.
As we're not operating on our root Gentoo system, but rather on a mimimized system created in a chroot, we have to specify where to find the package database for that chroot using --dbpath.
$ egreme graph app-shells/bash sys-apps/coreutils --dbpath /var/lib/machines/my-gentoo-chroot/var/db/pkg
=app-shells/bash-5.3_p9-r1:0
=sys-libs/ncurses-6.5_p20250802:0/6
=sys-libs/glibc-2.42-r5:2.2
=net-dns/libidn2-2.3.8:0/2
=dev-libs/libunistring-1.3:0/5
=virtual/libintl-0-r2:0
=sys-libs/readline-8.3_p3:0/8
=sys-apps/coreutils-9.9-r12:0
=sys-apps/acl-2.3.2-r3:0
=sys-apps/attr-2.5.2-r1:0
=dev-libs/openssl-3.5.5-r2:0/3
One thing to note is that the dependency tree is not exhaustive: in this example, on this system, both bash and coreutils depend on ncurses, but with the above incantation ncurses is not repeated under coreutils. To see a dependency tree expanded like that, with full attribution, there are other tools (eg emerge --tree --pretend). Here we do incremental dependency attribution only.
Exporting the closure
We were promised something akin to Nix's nix-copy-closure, but for Gentoo. So how do we copy out the dependency tree? As follows, with the clone subcommand:
$ mkdir /dev/shm/outfs
$ egreme.py clone app-shells/bash --infs /var/lib/machines/my-gentoo-chroot --dbpath /var/lib/machines/my-gentoo-chroot/var/db/pkg --outfs /dev/shm/outfs
Cloning =app-shells/bash-5.3_p9-r1:0
Cloning =sys-libs/ncurses-6.5_p20250802:0/6
Cloning =sys-libs/glibc-2.42-r5:2.2
Cloning =net-dns/libidn2-2.3.8:0/2
Cloning =dev-libs/libunistring-1.3:0/5
Cloning =virtual/libintl-0-r2:0
Cloning =sys-libs/readline-8.3_p3:0/8
The directory /dev/shm/outfs now contains the bare minimum for running bash. Obviously this can be a varying amount of software, depending on the choices made when setting up the mother filesystem (at /var/lib/machines/my-gentoo-chroot).
Look into egreme --help to see some options one might want to use for the clone operation.
Working with "cuts"
Let's look at a deptree for just dev-db/postgresql:18 on some system, of which the first part happens to look like this:
$ egreme graph dev-db/postgresql:18
=dev-db/postgresql-18.3:18
=app-eselect/eselect-postgresql-2.4-r1:0
=app-admin/eselect-1.4.31:0
=sys-apps/coreutils-9.9-r12:0
=sys-apps/acl-2.3.2-r3:0
=sys-apps/attr-2.5.2-r1:0
=sys-libs/glibc-2.42-r5:2.2
=net-dns/libidn2-2.3.8:0/2
=dev-libs/libunistring-1.3:0/5
(following 73 lines omitted for brevity)
While Gentoo has app-eselect/eselect-postgresql as a runtime dependency of PostgreSQL, seasoned users may know that actually, that's just a utility for setting some symlinks. In some cases one might not need it, but it does come with a bit of baggage here. Can we leave it out? Yes. For that we can supply a "cut" positional argument to specify that we don't want that package (nor any of its exclusive dependencies). The incantation will become some variant of:
egreme graph dev-db/postgresql:18 --cut app-eselect/eselect-postgresql
Specify as many cuts as you wish as positional arguments.
Working with "furcations"
Sometimes, a dependency can be fulfilled in several ways. Suppose we want to create a container that runs net-misc/mosh. Mosh requires an ssh, but that requirement can be fulfilled with either net-misc/openssh or net-misc/dropbear. Installation of either of those fullfills the virtual/ssh package on which net-misc/mosh concretely depends. Here's an (abbreviated) depgraph, for net-misc/mosh, of a system that has it plus the two SSH implementations installed:
$ egreme graph net-misc/mosh
=net-misc/mosh-1.4.0-r1:0
[...]
=virtual/ssh-0-r2:0
AtomFurcation@299628531972363860: net-misc/dropbear | virtual/openssh
=net-misc/dropbear-2025.89:0
[...]
=virtual/openssh-0-r1:0
=net-misc/openssh-10.2_p1:0
[...]
The deptree includes both paths. Isn't that a problem? Yes, as we'll find out when we ask to export the packages:
$ egreme clone net-misc/mosh --outfs /dev/shm/my-container-layer
Furcation 299628531972363860: via =net-misc/mosh-1.4.0-r1:0
furcates: False deps: 66 pkg: =net-misc/dropbear-2025.89:0
furcates: False deps: 65 pkg: =virtual/openssh-0-r1:0
Unresolved furcations present. Please supply furcdirs.
Egreme will exit nonzero and tells you to direct which way you want to go at this fork (furcation) in the road.
The output lists furcations, with a stable unique ID for each, together with some info about whether a specific path furcates further onward, and the total dependencies for each path. Of course, for choosing which path to take it's important to look at each dependency tree by itself to judge which one has the smallest installed size, if that is the criterion. Here openssh may have 1 fewer dependency, yet perhaps the dependencies are much larger than dropbear's. The dependency count is thus just an indication.
Expliciting the choice is easy. Here we'll go with dropbear, and use the furcation ID from the above output together with that choice as a positional argument after --furcdirs. This works for all subcommands (be it clone, graph, or furcations).
We can check whether we resolved all furcations by trying to list any remaining using the furcations command:
$ egreme furcations net-misc/mosh --furcdirs 299628531972363860:net-misc/dropbear
No output — no news is good news, we've resolved all furcations and should be able to use the clone command now (supplying this furcation directive, of course).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file egatrop-0.0.1.tar.gz.
File metadata
- Download URL: egatrop-0.0.1.tar.gz
- Upload date:
- Size: 17.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Gentoo","version":"2.18","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1f41b8905fd0fc40224068940cc151a9666e36b4de00105ee0f64428a9f6cfd
|
|
| MD5 |
69b057d8f4fa8ae32eadcfa241d8e86a
|
|
| BLAKE2b-256 |
3d03673ae29bb4efaa8c67c6f9f6c0ae1514690902914ecbb26cd129cc9a4d80
|
File details
Details for the file egatrop-0.0.1-py3-none-any.whl.
File metadata
- Download URL: egatrop-0.0.1-py3-none-any.whl
- Upload date:
- Size: 19.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Gentoo","version":"2.18","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6c6f7ef65eb0680644ec8c0181d25fe85717fb5f13bbfc6eff373a2c2245ed8
|
|
| MD5 |
d3d5931087aced2e0e4486047b6e2c3b
|
|
| BLAKE2b-256 |
4508773c63c68b78dfef23fa0f66f9ba830d4fd4ec03775c8af69ccb4c0488ee
|