Skip to content
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

nixos/systemd: Implement a packages option for tmpfiles #93073

Merged
merged 1 commit into from Jul 20, 2020

Conversation

dasJ
Copy link
Member

@dasJ dasJ commented Jul 13, 2020

Motivation for this change

#66856 (comment)

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

cc @flokli

@dasJ
Copy link
Member Author

dasJ commented Jul 13, 2020

This is a draft since my tests are still building.

@dasJ dasJ changed the title nixos/systemd: Implement a packages option nixos/systemd: Implement a packages option for tmpfiles Jul 13, 2020
@flokli flokli added this to To Do in systemd via automation Jul 13, 2020
@dasJ dasJ marked this pull request as ready for review July 13, 2020 16:27
Copy link
Contributor

@flokli flokli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least kresd and colord could also be updated to make use of the new option, instead of using environment.etc by themselves.

systemd automation moved this from To Do to In Progress Jul 13, 2020
@@ -134,8 +134,7 @@ in {
CacheDirectoryMode = "0750";
};

environment.etc."tmpfiles.d/knot-resolver.conf".source =
"${package}/lib/tmpfiles.d/knot-resolver.conf";
systemd.tmpfiles.packages = package;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
systemd.tmpfiles.packages = package;
systemd.tmpfiles.packages = [ package ];

@@ -26,7 +26,7 @@ in {

systemd.packages = [ pkgs.colord ];

environment.etc."tmpfiles.d/colord.conf".source = "${pkgs.colord}/lib/tmpfiles.d/colord.conf";
systemd.tmpfiles.packages = pkgs.colord;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
systemd.tmpfiles.packages = pkgs.colord;
systemd.tmpfiles.packages = [ pkgs.colord ];

Comment on lines 1011 to 1025
"tmpfiles.d".source = (pkgs.symlinkJoin {
name = "tmpfiles.d";
paths = cfg.tmpfiles.packages;
}) + "/lib/tmpfiles.d";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we check here every package in the list exposes a lib/tmpfiles.d and fail otherwise?

This should make it easier to spot accidentially passing in the wrong output, as described in #93006 (comment).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like this?

@ajs124 ajs124 force-pushed the tmpfiles-packages branch 2 times, most recently from 0dfd7b6 to e4e2801 Compare July 14, 2020 00:12
for i in $(cat $pathsPath); do
test -d $i/lib/tmpfiles.d || (
echo "ERROR: The path $i was passed to systemd.tmpfiles.packages but does not contain the folder lib/tmpfiles.d"
exit 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to exit the entire shell?
I think bash / sh will only exit the subshell here..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm >90% sure this works and tested it with systemd.tmpfiles.packages = [ pkgs.hello ];.
Actually… yeah, this probably only exits the subshell, but all phases run with set -e, so this does fail the whole build.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right, set -e will make it fail. Sorry for the noise!

<filename><replaceable>pkg</replaceable>/lib/tmpfiles.d</filename>
will be included.

If a <filename>lib</filename> output is available, rules are searched there.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should somehow describe it then /only/ looks in the lib output

(and maybe explain the whole fallback depending on which outputs the package has (lib -> out -> default output)), but I'm struggling with how to write this in a more explicit and less misunderstandable way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about: "If a lib output is available, rules are searched there and only there. If there is lib it will fall back to out and if that does not exist either, the default output will be used."

Although this should maybe just be documented somewhere "generically". As in, explain getOutput in some part of the manual and reference if for options like this, because there are probably a bunch of them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let's refactor it to a more generic place as soon as there's more than 2 things trying to document it :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#93006 isn't trying to document it right now, but it also does apply = map getLib;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change this to "If a lib output is available, rules are searched there and only there. If there is lib it will fall back to out and if that does not exist either, the default output will be used." for now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


"tmpfiles.d/home.conf".source = "${systemd}/example/tmpfiles.d/home.conf";
"tmpfiles.d/journal-nocow.conf".source = "${systemd}/example/tmpfiles.d/journal-nocow.conf";
"tmpfiles.d/portables.conf".source = "${systemd}/example/tmpfiles.d/portables.conf";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! This isn't there as we currently build systemd with -Dportabled=false, which is fine for now.

ln -s "${systemd}/example/tmpfiles.d/static-nodes-permissions.conf"
ln -s "${systemd}/example/tmpfiles.d/systemd.conf"
ln -s "${systemd}/example/tmpfiles.d/systemd-nologin.conf"
ln -s "${systemd}/example/tmpfiles.d/systemd-nspawn.conf"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We we should add this during nixos/modules/system/boot/systemd-nspawn.nix (but unconditionally, as we want to have the tmpfiles set up when running systemd-nspawn imperatively)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment below about x11

ln -s "${systemd}/example/tmpfiles.d/systemd-tmp.conf"
ln -s "${systemd}/example/tmpfiles.d/tmp.conf"
ln -s "${systemd}/example/tmpfiles.d/var.conf"
ln -s "${systemd}/example/tmpfiles.d/x11.conf"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved to nixos/modules/services/x11/xserver.nix

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? It's part of the systemd package. Putting it in nixos/modules/services/x11/xserver.nix would just result in

systemd.tmpfiles.packages = [(pkgs.runCommand "x11-tmpfiles" {} ''
  mkdir -p $out/lib/tmpfiles.d
  cd $out/lib/tmpfiles.d

  ln -s "${systemd}/example/tmpfiles.d/x11.conf"
'')];

Is that really better?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it contains x11-specific tmpfile rules, which we probably don't really want on a nongraphical system. But eh, this specific one only removes files, so 🤷

<filename><replaceable>pkg</replaceable>/lib/tmpfiles.d</filename>
will be included.

If a <filename>lib</filename> output is available, rules are searched there and only there. If there is no <filename>lib</filename> output it will fall back to <filename>out</filename> and if that does not exist either, the default output will be used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you reflow this?


All found files in
<filename><replaceable>pkg</replaceable>/lib/tmpfiles.d</filename>
will be included.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add "If none of these files can be found, this will return an error."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, right now we actually check if this folder exist, not if any files are in there. Maybe we should change that check (in addition to documenting it).

Also drop the `portables` tmpfiles because the file is missing in the
systemd derivation.
@flokli flokli merged commit f14799c into NixOS:master Jul 20, 2020
systemd automation moved this from In Progress to Done Jul 20, 2020
@ajs124 ajs124 deleted the tmpfiles-packages branch July 20, 2020 22:35
@ajs124 ajs124 mentioned this pull request Jul 25, 2020
10 tasks
"tmpfiles.d/systemd-tmp.conf".source = "${systemd}/example/tmpfiles.d/systemd-tmp.conf";
"tmpfiles.d/tmp.conf".source = "${systemd}/example/tmpfiles.d/tmp.conf";
"tmpfiles.d/var.conf".source = "${systemd}/example/tmpfiles.d/var.conf";
"tmpfiles.d/x11.conf".source = "${systemd}/example/tmpfiles.d/x11.conf";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously I could disable tmp.conf (to keep /tmp across reboots) with environment.etc."tmpfiles.d/tmp.conf".text = "# disabled by me";. This does not work anymore. How shall I achieve that now? May these .source lines be restored? (I do not see the benefit of the new way.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof. @ajs124 Can files be overridden with a package that is later in the list?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dasJ No, I don't think so. We could probably do this in nix instead of a derivation, then you could mkForce the option.
@orivej the benefit, like with other similar systemd module options, is that we can use tmpfile files from upstream packages easily.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ajs124 I see the purpose of systemd.tmpfiles.packages in general, but I do not see the benefit of the new synthetic packages "systemd-default-tmpfiles" and "nixos-tmpfiles.d" over the old environment.etc."tmpfiles.d/00-nixos.conf".text = …; "tmpfiles.d/tmp.conf".source = .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose that using solely systemd.tmpfiles.packages for managing /etc/tmpfiles.d is good for uniformity, but it looses the well thought out infrastructure for customizing /etc via environment.etc settings. I think that systemd.tmpfiles.packages should be empty by default to allow the user an easy choice between using unmodified upstream tmpfiles.d and custom alternatives.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A simple solution would be maintaining a exclude list of .conf files, which shouldn't be added to /etc in the end.

This sounds good if we would exclude all files in environment.etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also lib.mkForce the list to get rid of the default packages.

This is not acceptable because I want to keep all other systemd tmpfiles.d installed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds good if we would exclude all files in environment.etc.

Not sure if I understand. /etc/tmpfiles.d would still symlink into the nix store, but the code assembling it could have an exclusion list.

Also, what do you think about using buildEnv, and its priorities mechanism?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just opened #96755 to track this.

Also, what do you think about using buildEnv, and its priorities mechanism?

Sounds like an improvement to me as it doesn't require Nixpkgs patches anymore but it's likely still a pretty verbose solution that isn't that use friendly (though I would be ok with it and I'm not sure if we could easily do better).

I guess a pretty compact snipped to use this would look something like this:

systemd.tmpfiles.packages = [
  (lib.hiPrio (pkgs.writeTextDir "lib/tmpfiles.d/tmp.conf" ''
    # Disabled
  ''))
];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flokli See #96766, I'm using environment.etc as the exclusion list.

buildEnv seems incompatible with mutable /etc and the way environment.etc is implemented.

@flokli flokli mentioned this pull request Aug 15, 2020
orivej added a commit to orivej/nixpkgs that referenced this pull request Aug 31, 2020
…nt.etc

This allows the user to configure systemd tmpfiles.d via
`environment.etc."tmpfiles.d/X.conf".text = "..."`, which after NixOS#93073
causes permission denied (with new X.conf):

```
ln: failed to create symbolic link '/nix/store/...-etc/etc/tmpfiles.d/X.conf': Permission denied
builder for '/nix/store/...-etc.drv' failed with exit code 1
```

or collision between environment.etc and systemd-default-tmpfiles
packages (with existing X.conf, such as tmp.conf):

```
duplicate entry tmpfiles.d/tmp.conf -> /nix/store/...-etc-tmp.conf
mismatched duplicate entry /nix/store/...-systemd-246/example/tmpfiles.d/tmp.conf <-> /nix/store/...-etc-tmp.conf
builder for '/nix/store/...-etc.drv' failed with exit code 1
```

Fixes NixOS#96755
orivej-nixos pushed a commit that referenced this pull request Sep 2, 2020
…nt.etc (#96766)

This allows the user to configure systemd tmpfiles.d via
`environment.etc."tmpfiles.d/X.conf".text = "..."`, which after #93073
causes permission denied (with new X.conf):

```
ln: failed to create symbolic link '/nix/store/...-etc/etc/tmpfiles.d/X.conf': Permission denied
builder for '/nix/store/...-etc.drv' failed with exit code 1
```

or collision between environment.etc and systemd-default-tmpfiles
packages (with existing X.conf, such as tmp.conf):

```
duplicate entry tmpfiles.d/tmp.conf -> /nix/store/...-etc-tmp.conf
mismatched duplicate entry /nix/store/...-systemd-246/example/tmpfiles.d/tmp.conf <-> /nix/store/...-etc-tmp.conf
builder for '/nix/store/...-etc.drv' failed with exit code 1
```

Fixes #96755
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
systemd
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

7 participants