Currently, mkosi image builds can differ depending on the host they
were built from. This can happen because we execute all kinds of
binaries to build the image and depending on the host these binaries
can differ. Usually, it's different versions of tools causing issues,
but it can also be due to different build configurations, such as rpm
writing its database in a different format depending on whether it's
executed from CentOS, Fedora, or Opensuse.
To allow for more reproducibility in image builds regardless of the
host system, this commit adds a new option --tools-tree= that allows
specifying a tree in which we look up most of the programs that we
execute during an image build.
Of course, that still leaves the question of what tree should be passed
to --tools-tree=. To solve that problem, --tools-tree= can be used
together with presets, so that as the first preset, a "bootstrap" image
can be built which can then be used with --tools-tree= in later presets.
Note that we only use /usr from the given tree. If tools end up using
config files from /etc or such, we expect those tools to expose a knob
to specify a different configuration file (instead of us overmounting
/etc).
Note that in a few cases, we don't yet execute tools in the given tree:
- systemd-analyze in GenericVersion() can't be executed in the tree
because it could be executed during config parsing when we don't
know the tree to use yet.
- newuidmap/newgidmap have to be executed before we can run
bubblewrap so we can't run them in bubblewrap itself
- Figuring out the credentials is inherently tied to the host system
so we execute all scripts and tools to figure out credentials on
the host system as well
- mount because bubblewrap does not propagate mounts to the real root
so any mounts we do within bubblewrap don't survive the bubblewrap
process
- systemd-dissect for the same reason