-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More flexible systemd expression for minimal builds #72802
Conversation
(NixOS tests still compiling, I’ll keep you updated.) |
This looks really nice, but we should replace some of these optionals with multiple outputs, like debian has separate packages for the container management, remote journal and coredump functionality. In NixOS, we don't really want to override systemd system-wide, because it'd rebuild a lot of things. Multiple outputs are much nicer, because we can teach the NixOS systemd module on how to compose these outputs. Regular systems could still ship the full feature set, while smaller things like the minimal installer could ship a reduced feature set. |
Thank you very much for that work! After a short sweep it looks fine. Can you elaborate how the intended use case for initramfs systemd is? Would the daemon remain after switching to stage2 or is it just to have the systemd tooling around in stage1? If the daemon would stay alive I'd rather have just one build for both stage1 & stage2 or we must do a re-exec aka "upgrade" when entering stage2. (I am aware that using it in stage1 is just one of the use cases this enables and that it is still out of scope for this PR.) |
@andir My plan is to build the most bare-bones version of systemd that I can without abusing their build system, in order to get the smallest possible closure size, throw it into initramfs and use to boot the system. When switching root for stage2 it will also re-exec into a fully-featured version of itself, hopefully correctly passing on all the accumulated state (I haven’t tried this yet, but I looked at the code, and I believe it should work.) |
@flokli I am all in favour of splitting outputs, my only concern is that it falls into the “abusing their build system” category. I am not saying it is bad, I am just saying that it might require some work initially and then will incur maintenance costs. But even assuming that we will be able to get more outputs, I think that a) Exposing parameters as in this PR might still be useful; b) I would still like to get the re-exec thing working because |
Hmmmmmm
That’s weird. Did I break it? 😕 |
|
systemd-based initramfs usually uses https://www.freedesktop.org/wiki/Software/systemd/InitrdInterface/ this manpage explains what a systemd-based initrd should look like: |
Ok, very funny 494d2de |
This should be targeted against staging since it's a mass-rebuild. I'd suggest rebasing the branch on the last common commit of master and staging in order to avoid pinging everyone when retargeting:
and only then retarget. |
Alright, an unscientifically chosen subset of tests ( |
0af663a
to
282f686
Compare
282f686
to
8a81558
Compare
The problem with vlock is that it pulls in PAM, and PAM is quite large, while kbd is a pretty basic package that might be very useful for basic console-related activities, such as setting font during early boot.
util-linux minial is meant to be minimal and PAM is not minimal.
Alrighty, there is a conflict with #70352, should not be too hard to resolve, but I’ll need some time to make sure the minimal closure is not affected. |
This is mostly a readability commit. It essentially doesn’t change anything in the expression, except that it splits the expression parameters into logical groups and reorders the configuration options to split them into logical groups as well and to have them in the order that more closely resembles that of the upstream documentation and configuration scripts. The only two changes to the semantics of the expression are: * `withSelinux` is removed and replaced with `selinux != null`. * `lz4` is not forced-enabled, instead the build system will detect whether it is available or not.
This allowd for a minimalistic build of systemd for embedded applications or stage1 initramfs.
Make sure the following optional dependencies are truly optional: * pam * gnu-efi * libidn2 * curl * gnutar * gnupg Add a missing importd dependency (also optional): * zlib
Resolving these conflicts was no fun at all, but I hope I managed to. Let’s merge this pls before anyone decided to make other changes to systemd :). (Can’t test right now, I’ll wait until Hydra has at least some cache.) |
@kirelagin thanks for following up, and sorry this made a rebase necessary. I don't see the minimal systemd being used somewhere, so I don't think it'll be built by hydra. Did you only meant to test the regular systemd? Depending on how we want to intend to use that minimal systemd, it might make a lot of sense to run some of the basis systemd tests with the minimal systemd aswell - WDYT? It might make sense to align these changes with the "port tests to the python test runner" efforts: #71684 |
This looks very interesting! I might have a good use case for this. My goal is to build an encrypted bootable USB for secure key management. I was trying to use nix to build an image with encrypted partition, but ran into some problem. Although I could try to use nix-plugins to solve it, I think a better solution is to let the USB drive encrypts itself on first boot. So now what I want is on first boot, it should ask for a passphrase, and then encrypt the root partition, and reboot. Next boot grub will prompt for passphrase to decrypt the USB drive before continuing. However, in order to encrypt the disk, I cannot have root partition already mounted. So I'm thinking either using two partitions, or let the first boot only use initramfs, so the actual root partition an be encrypted using So what is the size of an initramfs with systemd that this PR will enable me to build? P.S. I'm not exactly sure if I need systemd for my purpose, but something close to a fully functioning system will save me quite some effort. |
Yes, I’m only testing regular systemd. There is nothing to test about the minimal systemd yet, since, you are right, it is not used anywhere :). However, testing that it build probably makes sense indeed, so, do you think, I should add a top-level expression for it?
That would be amazing, but I have no idea how to approach this. I couldn’t find anything like this done in nixpkgs before, maybe I wasn’t looking good enough. Anyway, I’ll look into it later.
So, as I mentioned, by ultimate goal is replacing current stage1 with one based on minimal systemd. Once this is done, the boot.nix test will get us covered. For now I am not sure what can be done... in theory, we can try to boot a regular systemd with minimal systemd and run some of the already existing |
@ninegua I don’t think you really need systemd for this, if your initramfs will be as simple as encrypting a partition, a bash script that runs If you still decide to go the systemd-in-initramfs route, you might be interested in watching #72401. As to the sizes, current initramfs that I have is 107M uncompressed, 24M compressed. But you have to keep in mind that it a) includes systemd linked with glibc rather than musl; b) has no luks support; c) doesn’t work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really about optimized build, or about cross compilation?
How does gcc-ar
differ from ${stdenv.cc.targetPrefix}gcc-ar
?
That’s a fixup commit for the “Do optimised build” commit. The line itself, as the comment, indicates, is for LTO. The fixup is for cross-compilation. |
@kirelagin can you squash a80a719 into 62593e7, and while doing so, rebase on latest staging? I think this is in general pretty useful, but wonder if we should make sure a minimal systemd gets built somewhere, too (so we see if it suddenly fails to build or dramatically increases in size). I'd be fine with merging it in as-is, but with using it, we'd decrease the risk of bitrot. |
@kirelagin What's the status on this? |
I think this is in general very useful. I'm a bit concerned about a more minimal version of systemd breaking without us noticing it, however. @kirelagin This needs a rebase on latest staging (since #85334, we don't use a custom fork, but the upstream repo and NixOS-specific patches on top) and a squash as described in #72802 (comment). Also, do you have any thoughts on how we could test a more minimal systemd in a VM test? |
This PR just gives you the ability to override some meson flags; it doesnt introduce a minimal systemd package yet; just gives people to ability to make one through Personally I just would expose all systemd flags as nix flags instead of a now a curated set At least we should also exposed What do you think? |
IMHO, we should only introduce options that are somewhat working (and by some test coverage, ensured to be not silently breaking). If someone wants to tackle |
Hi everyone. The status is that there were conflicts with other work going on on the systemd expression at that time, so it didn’t get merged at that time, and then I kinda forgot about the project (systemd-based initramfs) that I was doing this for. I am sure I am going to get back to it, I am just not sure when. Hopefully, soon. If someone needs this and has some specific use-cases in mind, I can prioritise it on my todo list.
Basically, once I have my initramfs ready, I’m sure I’ll be able to extract some basic code from it that will be a reasonable VM test. But it will be just stage1, I think it is good enough, let me know if you think otherwise. |
Thanks for the feedback! I mostly just want to avoid having untested combinations in the systemd expression that might silently break. If you're not currently actively working on this, let's get back to this after #66856 - which is needed to natively handle crypto volumes with systemd in initrd anyways. |
Would that not mean that a system closure contains to 2 systemd, one with and one without homed (the one without to build dbus, for the one with homed). Should we disable everything, except the features used for dbus? Can we maybe link dbus's systemd dependency to /run/current-system? So we only need one systemd per generation? |
Let's do that discussion in #98094. Also, is most of this PR included in #98299? |
Yes, I build my systemd part after looking into this pr. So this is the code I used to build #98299 |
Then let's close this in favor of #98299. Thanks for the work so far! |
Motivation for this change
The primary motivation is #72401. The essence of this PR is exposing more configuration options and making sure that optional dependencies are actually treated as optional. This way a minimalistic build for embedded systems or starge1 initramfs can disable everything it doesn’t need to ensure small closure size.
The first two commits are changed to the dependencies of systemd. The third commit of the series is just a refactoring: some parameters and configuration options are merely reordered for readability. Then follows the actual meat of the PR, which I tried to organise into logical commits to make reviewing them more enjoyable.
My hope is that without any overrides the only difference is that
utillinuxMinimal
no longer depends on PAM and usesshadow
that does not depend on it. The default configuration ofsystemd
, I hope, will remain the same as before.Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nix-review --run "nix-review wip"
./result/bin/
)nix path-info -S
before and after)Notify maintainers
cc maintainers @edolstra @andir @Mic92
cc mobile-nixos crowd @lheckemann @samueldr
cc a random subset of people I saw in git log @worldofpeace @FRidh @abbradar