In my quick review of systemd, I left a few points hanging for further elaboration.
I mentioned that there are no official stage3 tarballs with systemd. Without them, the only way to get a systemd system is to upgrade via the guide.
As I get used to it, I'm going to need a way to install systemd repeatedly and consistently. I have therefore created my own stage3 tarball.
amd64: <https://dl.condi.me/gentoo-systemd/latest/stage3-systemd.tar.xz>
I have a gist with the various scripts that I wrote. Consider this blog post the README.
In essence, a stage3 tarball is a basic rootfs directory structure with just enough binaries and libraries to install more stuff. Add a kernel, bootloader, some must-have packages and configuration files and you have a bootable snowflake.
They're easy to make, but care needs to be taken to make them sufficiently generic and small enough for distribution. Mine comes in a just over 98MB.
Some things to consider:
You don't have to mess with your real rootfs. --root and --config-root (control the $ROOT and $PORTAGE_CONFIGROOT _variables respectively) are good ways to create new rootfs directory trees. This behaves much like debian's _debootstrap or yum --installroot.
Use binpkgs, we don't need full build logs or compilation artifacts. Emerging with packages also requires a smaller dependency set (no build dependencies on the target), so less packages need to be installed.
This means that creating the final target system occurs in two steps, one_ --buildpkg_ but not --usepkg, then again with --usepkg. These are the chroot-prepare and chroot directories.
The very minimum that emerge needs to know about the target, is the make.profile symlink. This is at ./etc/make.profile relative to $PORTAGE_CONFIGROOT and points to a profile in $PORTDIR/profiles.
root@localhost ~ # ls -l chroot/etc/make.profile
lrwxrwxrwx 1 root root 46 Aug 31 22:10 chroot/etc/make.profile -> /usr/portage/profiles/default/linux/amd64/13.0
Here, emerge (the program itself) and the portage tree (/usr/portage) are located on my real filesystem. I'm actually doing this all in a virtual machine dedicated to building gentoo root filesystems, so "real" is a subjective term.
If I wanted to use the defaults, I could create a naive stage3 tarball in two commands.
# emerge --{config-,}root=chroot world
# tar xzf stage3-naive.tar.gz -C chroot .
To force systemd, I have changed the global USE flags to "-consolekit systemd", so that packages will be compiled with systemd awareness, and added sys-apps/systemd to the world set.
I also added net-misc/dhcpcd, sys-apps/dbus and_ sys-apps/iproute2_ to the world file because they are useful to have and not part of the system set. I have a larger list of world dependencies that include app-editors/vim, app- portage/eix, sys-kernel/dracut (and keywords to unmask it), sys-boot/grub plus some portage, filesystem and networking tools.
Create the binpkgs, saving them to a PKGDIR somewhere. Defaults to /usr/portage/packages.
# EMERGE_FLAGS="--buildpkg --update --jobs"
# mkdir "chroot-prepare" "chroot"
# tar xavpf stage-template.tar.gz -C chroot
# emerge $EMERGE_FLAGS --config-root=chroot --root=chroot-prepare world
This is where most of the time will be spent. It is good to have a strong multicore machine with enough RAM for this stage. Add --jobs (unbounded) and set MAKEOPTS (in_ make.conf_) if you can without crashing the build host. VMs are really useful for this eventuality.
We could tarball up chroot-prepare, but it includes a few extras that we won't necessarily need to get a working stage3. It also misses out something critical that exposes a bug in the portage tree.
# emerge $EMERGE_FLAGS --usepkgonly --config-root=chroot --root=chroot world
Ideally, this command would work. However there are a few bugs in the area where sys-apps/dbus (a dependency of systemd) will not be installed correctly. It has a pkg_setup phase that calls enewgroup and enewuser from the user.eclass eclass. Which, in their current incarnations are not ROOT aware, preventing dbus from starting at boot.
The gist includes a patch to the eclass that I should attempt to get merged. Given the previous attempts by others, and that this only works for recent linux distros I won't hold my breath.
The other half of fixing dbus is that the required programs to call enew{user,group} also require files provided by sys-libs/glibc (for /usr/bin/getent), sys-libs/pam, sys-auth/pambase, sys-apps/shadow and sys-apps/baselayout.
Thanks go to dev-util/strace (and following which open() calls failed because pam was not yet installed) and qfile (of _app-portage/portage- utils___) for hunting down the needed packages. I'm not sure what the proper way to fix this is since my patched eclass requires permission checking in the chroot, not the dbus ebuild itself.
This knowledge lets us create a working stage3.
# DBUS_DEPS="sys-libs/glibc \
sys-libs/pam \
sys-auth/pambase \
sys-apps/shadow \
sys-apps/baselayout"
# emerge $EMERGE_FLAGS --usepkgonly --config-root=chroot --root=chroot \
--oneshot --nodeps $DBUS_DEPS
# emerge $EMERGE_FLAGS --usepkgonly --config-root=chroot --root=chroot \
world
And finally,
# tar cJf stage3-systemd.tar.xz -C chroot .
Phew.