distri supersilverhaze (2020-05-16)
If you’re not familiar, distri is a Linux distribution to research fast package management.
You can read more about distri starting in my introduction blog post, then in my series of blog posts about distri.
Please direct any questions or feedback to the distri mailing list.
Changes since the last release
The following sections briefly cover new features in distri, with links to more details.
If you’re curious, you can also browse the commits since the last release.
minitrd
Building a distri disk image (using e.g. make image
or distri pack
directly)
is now significantly faster, because the most time-consuming step has been
replaced: initrds are no longer built with dracut
, but with minitrd
, a custom
from-scratch implementation optimized for
speed.
Whereas it previously took ≈40 seconds, a full distri disk image can now be generated in 4 seconds (with warm caches)!
Debugging
I have previously written about the debugging experience in Debian, which left a lot to be desired. This release of distri comes with two features that result in what I consider the gold standard of debugging experience.
Debugging: package sources
All package sources are now available under /usr/src/
,
e.g. /usr/src/procps-ng-amd64-3.3.15-8/
. This is powered by:
-
The
srcfs
service, which (likedebugfs
for/ro-dbg
) is adistri fuse
daemon which lazily downloads packages from the repository when they are accessed. -
distri build
now writes a source squashfs images. Files which are referenced by debug info and cannot be found in the source directory will be taken from the build directory. This makes generated files available for debugging at source level.
Caveat: 15 packages contain at least one generated source code file which is unavailable, to be fixed at a later date.
Debugging: DWARF debug symbols
The DWARF debug symbols of all packages
are available through /ro-dbg
,
e.g. /ro-dbg/emacs-amd64-26.3-15/debug/.build-id/d8/149e8d4e11dc451ac5e718dfc44344c610e23e.debug
. While
the backing debugfs
service was already included in the previous release, its
reliability has been improved: distri fuse -autodownload
now keeps retrying
when started without network connectivity.
Caveat: 16 packages do not currently ship debug symbols, even though they should. A number of other packages do not ship debug symbols because they do not contain ELF files.
FUSE performance
distri fuse
: avoid running out of file descriptors with many packages by increasing the open file limitdistri fuse
: significant optimizations in scanPackages (now >3x as fast)- Cache file lookups resulting in
-ENOENT
. This speeds up dynamic library loading when starting programs. - issue #59 contains an overview of FUSE optimizations that were applied and are yet to be explored.
Package build performance
Improving the package build performance results in faster batch builds, and a better interactive development experience when iterating on a single package.
make
4.3 fixes performance issues with heavily concurrent builds, e.g.linux
(down from over an hour to merely 10 minutes).distri batch
anddistri build
now write a chrome://tracing profile by default (including CPU user/sys counters and MemAvailable counter)- The FUSE performance optimizations listed in the previous section significantly speed up package building, too. E.g.
gtk+-2
now builds twice as fast (≈2 minutes down to ≈1 minute). - see https://github.com/distr1/distri/issues/59 for details
- use
${DISTRI_JOBS}
instead of hard-coded-j8
, adddistri build -jobs
flag distri build
: ninja: explicitly specify -j, ninja falls back to 3 without the/proc
file system
txtpbfmt
We now use the txtpbfmt
Go package (and
program) to enforce consistent
formatting of build.textproto
files across the repository.
Furthermore, txtpbfmt
allows for programmatic modification of build.textproto
files. The distri scaffold
subcommand uses txtpbfmt
to only update the upstream url
, hash
and version
fields when the package build.textproto
file already exists. In particular, this means that manual additions (including comments!) are preserved.
To make upgrading packages to more recent upstream versions even more convenient, the distri scaffold
subcommand now has a -pull
flag which will heuristically (see repobrowser for more details) pull in a new upstream version:
distri scaffold -pull google-chrome
2020/05/12 09:23:25 not up to date: updating from 80.0.3987.106-1 to 81.0.4044.138-1
diff --git i/pkgs/google-chrome/build.textproto w/pkgs/google-chrome/build.textproto
index 91e4113..589300a 100644
--- i/pkgs/google-chrome/build.textproto
+++ w/pkgs/google-chrome/build.textproto
@@ -1,6 +1,6 @@
-source: "http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_80.0.3987.106-1_amd64.deb"
-hash: "33bdf0232923d4df0a720cce3a0c5a76eba15f88586255a91058d9e8ebf3a45d"
-version: "80.0.3987.106-1-15"
+source: "http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_81.0.4044.138-1_amd64.deb"
+hash: "9d13d41d79ce1f04d1f150b5d22fffd31779224cc7d8274f8479b06bcfe6846a"
+version: "81.0.4044.138-1-16"
pull: {
debian_packages: "https://dl.google.com/linux/chrome/deb/dists/stable/main/binary-amd64/Packages"
}
repobrowser
The distri repo browser is now available at https://browse.distr1.org!
Similar to https://godoc.org/, the distri repo browser can visualize the contents of any distri repository. The public instance at https://browse.distr1.org is restricted to repositories hosted on https://repo.distr1.org for the time being.
The repo browser displays not only the current versions of all packages in the repository, but also flags packages as out of date in case a more recent upstream version is known.
repobrowser: upstream check heuristic
Checking upstream for newer versions is done largely heuristically. For a few popular services (GitHub, GitLab, Go modules, etc.), service-specific APIs are used. More specific code can be added where required, but thus far, the heuristic covers the vast majority of packages.
34 packages (6.2%) are currently not categorized because the upstream check failed.
For some packages, this is expected: for example autoconf2.13
is technically
out of date (autoconf
2.69 is current), but mozjs
specifically requires the
older 2.13, so we will need to keep that outdated package around.
In other cases, upstream is unreachable. Either temporarily (server issues, like
recently with freedesktop.org) or permanently, e.g. giblib
, where the upstream
URL results in a connection refused error for years.
Sometimes the heuristic results in a false-positive result: the package is shown
as up-to-date, but a new major version is available in a different
subdirectory. Some projects (e.g. util-linux
) publish release within a major
version in their own subdirectory,
e.g. https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.32/util-linux-2.32.1.tar.xz.
The heuristic should be changed to detect that situation, which is tracked in issue #68.
Tab completion
Tab completion for package installation is now available by default:
Press the tab key after entering distri install
and you will be presented
with a list of available packages.
This is powered by distri list
, which fetches the repository metadata on demand.
Side note: the default shell for the root
account was switched from bash
to
zsh
for this, which also enables history by default.
New packages
A few new packages have been added, typically because I needed them on my test machine:
bluez, dnsmasq, dunst, encfs, intel-ucode, linux-cpupower, mesa-demos, nano, pigz, screen, tmux, upower, vim, wget, xclip, xwininfo
New upstream versions
A number of packages has been updated to their current upstream versions:
- 432 packages (79.56%) are up to date
- 68 packages (12.52%) have a newer upstream available
- 43 packages are go modules with a newer minor version
- 25 packages are not go modules, but upstream packages where something blocks us from updating, e.g. new bugs or build failures with downstreams
Hygiene
- All
distri(1)
commands now handle interruptions (SIGINT
,SIGTERM
) and clean up temporary files. distri build
now actually mounts the source directory read-only (Linux ignores theMS_RDONLY
flag for bind mounts).distri patch
now provides a proper interactive shell.distri build
now logs the whole build output (including distri messages), not just the build steps.distri build
’s-debug
flag now accepts the name of a stage when to spawn a debug shell, e.g.after-install
.
Microcode
GRUB 2.04 now applies CPU microcode updates for Intel CPUs at early boot (amd-ucode
is just not yet packaged).
Makefile
- The
kgdb=
andkernel=
parameters allow easier kernel debugging - The
screen
target starts a developmentscreen(1)
session - The
usb
target writes the distri image to e.g. a USB stick:
make usb USB_DISK_ID=usb-SanDisk_Extreme_Pro_12345678D99C-0:0
autobuilder
More work went into the autobuilder, but it is not deployed yet.
The autobuilder should eventually build every git commit, so that we have quick, automated feedback regarding possible breakages, and an easy way to test the current version of distri, whether released or not.
Due to the large data volume (dozens of gigabytes per commit) and operational challenges (building a single commit from scratch takes ≈2 hours on an Intel Core i9-9900K), this setup requires careful tweaking.
Update instructions
To set expectations: due to its experimental nature, distri does not make any guarantees that updates will work. We try to make them work, as long as you follow the update instructions described here. Good luck! :)
Ensuring enough free disk space
The jackherer
disk image is 7 GB in size, which is not sufficient to hold the default installation in both versions (temporarily). Double the image in size on the host:
truncate -s +$((7*1024*1024*1024)) distri-disk.img
…and enlarge the file systems within the image:
distri install golang && go get github.com/google/embiggen-disk && ~/go/bin/embiggen-disk -verbose /
Consider switching from dracut to minitrd
To switch from dracut to minitrd, use:
echo minitrd > /etc/distri/initramfs-generator
This will be effective upon the next installation of the linux
package, including the one in the distri update
step below.
Updating packages
Switch to the new release’s package repository:
echo https://repo.distr1.org/distri/supersilverhaze > /etc/distri/repos.d/distr1.repo
Workaround: Update the distri1
package, which contains the distri(1)
command, before any others:
distri install distri1
This is required for the next command to work properly, and should have been an automatic step. Unfortunately, the previously released version has a bug: it accidentally ran the same old version again instead of the newly installed one.
distri update
Because systemctl
fully resolves symlinks when creating symbolic links in
/etc/systemd/system
to enable a unit, the old version of e.g. SSH remains
enabled, and the new version explicitly needs to be enabled (improvements tracked in issue
#69):
systemctl --root=/ disable ssh
systemctl --root=/ enable ssh
Reboot into the new system to pick up all new package versions:
reboot
If you want, you can delete the old packages from your package store:
distri gc
…but you can also keep them so that you can use older versions to reproduce or work around a bug.
© 2018 Michael Stapelberg and contributors