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.tmpfiles: add structured attrs #97702
Conversation
What do I use as an attribute name when I want to do both "d /tmp ..." and "Z /tmp ..."? If I can't use the path as the attribute name then there isn't any sane merging and you're no further ahead than you were with a list. |
Good point, never used it with 2 times the same path. |
Or you can use /tmp_2 as attribute name and set tmp_2.path = "/tmp" |
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.
@Kloenk I congratulate you on the initiative. This has been talked over for quiet some time now, e.g: https://discourse.nixos.org/t/nixpkgs-policy-as-for-systemd-prestart-setup-scripts-vs-systemd-tmpfiles/5839/7 . I wanted to do this myself for a long time!
description = '' | ||
Rules for creating and cleaning up temporary files | ||
automatically. See | ||
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> | ||
for the exact format. | ||
''; |
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.
The description should distinguish itself from systemd.tmpfiles.rules
- rules
is an array and this one isn't.
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.
What about:
Attributes to automaticly create and remove files. See
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the exact format.
cfg.services) ++ optional (cfg.tmpfiles.rules != [ ]) '' | ||
systemd.tmpfiles.`rules` is deprecated, please use systemd.tmpfiles.`paths`. | ||
''; |
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.
After the design of this new option will be reviewed and approved, perhaps we should also sprint over all the services that use rules
, and switch them to paths
?
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.
Yes, just wanted to keep this pr small for the beginning, so it's easier to review.
I use some tmpfiles rules more then once and for some paths I use different as well. This idea has been bothering me so much that I now suffer from this warning when I
Generally, the motivation should be to make sure anyone, including services between each other, are capable of overriding rules for certain paths.
To answer @aanderse's question, I think we should split the whole attribute set to types, i.e the example should be: "d" = {
"/var/lib/my/path" = {
mode = " ..";
user = "...";
group = "....";
# ..
};
"a" = {
"/var/lib/my/path" = {
# ...
}; |
@doronbehar Sounds good as well, will try to implement it in the following days |
This invalidates the benefit of merging/overwriting. As it currently stands I think this PR makes In summary, to reiterate, attribute sets most often provide value because of merging/overwriting and I would expect merging/overwriting to be the main motivation for rewriting this option - this PR makes makes overwriting more confusing to the end user. |
@aanderse |
Something along those lines is definitely an improvement 👍 I'll point out that there is still the issue that we have I look forward to hearing some opinions of other people, some of whom I know who have already thought about this in more detail than I have. |
What if during activation, we'd read the packages' tmpfiles rules and use |
Yes, the insert new text, but in a different file. IIRC those get merged by systemd, following the filename of the files. |
Changed it to the other format. What do we do about the merging with tmpfiles.packages? Is the merging from systemd enough for that? |
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.
What do we do about the merging with tmpfiles.packages? Is the merging from systemd enough for that?
That's a good question. According to tmpfiles.d(5)
, all of the rules are concatenated by systemd before processing (after filepath based override is also processed, but it's not relevant for us). Here's an example of an experience of a not ideal conflict resolution I slightly suffer from, where the conflict is not with a package's tmpfiles, but with another NixOS' modules' rules, which is close enough I think, considering systemd's rules merging policy.
I got these two lines in my /etc/tmpfiles/00-nixos.conf
:
d /var/lib/mpd/playlists 2777 mpd syncthing
d '/var/lib/mpd/playlists' - mpd syncthing - -
Which originate from this:
# see https://github.com/NixOS/nixpkgs/blob/37198dda88b46d155ad9e7fdaf6bb3af18d56372/nixos/modules/services/audio/mpd.nix#L190
services.mpd.enable = true;
And from a "manual" insertion of a tmpfiles rule by my self (done here).
Systemd uses my permissions instead of the module's permissions, perhaps because mine are more specific. I do get this warning in the journal of systemd-tmpfiles-setup.service
, and during activation:
/etc/tmpfiles.d/00-nixos.conf:71: Duplicate line for path "/var/lib/mpd/playlists", ignoring.
Where 71
is the line that the NixOS module sets - meaning Nixpkgs' modules' tmpfiles rules are added after the my rules from their configuration.nix
. And thankfully, it seems that systemd uses the first line which just happens to be the user's (my) line.
To summarize, the changes look good, though I haven't tested them. I think that if we'll settle down on the current or any other design we'd agree on, and then sprint over all of our modules and convert their tmpfiles rules to paths
, at least we'll be able to deal with conflicts between ourselves. As for dealing with conflicts with packages' rules, in the worst case we could advise people to use
environment.etc."tmpfiles.d".<package's tmpfiles file name>.source = "/dev/null"
I.e disable the package's tmpfiles rules inclusion, per the last line here.
path = mkOption { | ||
type = types.str; | ||
default = name; | ||
description = "The path to the file to create"; | ||
}; |
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.
I know many such attribute set options exist in NixOS (e.g syncthing's declarative folders / devices), but is it really necessary? I remember it was rather confusing to me, to read the example and to see this option together.
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.
I tried to disable a tmpfile rule which was an default. With the new option type <type>.<path>.enable = false
this is more doable.
So should I convert every nixos module now, is there something left to discuss, or should the change be a separate pr? |
I'd wait and hear more opinions. |
Seems like there are no more opinions? |
Honestly I'm still not that keen on this. I'd really like to hear from at least one of @arianvp, @flokli, or @infinisil before anyone consider merging this. |
I completely missed this PR. I'll have a look this week. Just back from
holidays :)
…On Sun, Sep 27, 2020, 23:12 Aaron Andersen ***@***.***> wrote:
Honestly I'm still not that keen on this. I'd really like to hear from at
least one of @arianvp <https://github.com/arianvp>, @flokli
<https://github.com/flokli>, or @infinisil <https://github.com/Infinisil>
before anyone consider merging this.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#97702 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEZNI2F3KIO4UCUXAQQDYDSH6TDNANCNFSM4RFYJANQ>
.
|
For one, I think the interface should be {
systemd.tmpfiles.paths = {
"/tmp".d = {
mode = "1777";
age = "10d";
};
} This corresponds to "declaring a set of rules for a file", which makes much more sense than the other way around ( But now I wonder: Can't we create a more descriptive API for this? And could we perhaps create an abstraction that doesn't rely on How about something like {
pathOperations = {
"/tmp" = {
type = "directory";
setMode = "1777";
cleanEvery = "10d";
};
"/var/lib/foo" = {
type = "directory";
setUserRecursive = "foo";
# Only run when /var/lib/foo isn't owned by foo
condition.user.foo = false;
};
"/home/paul" = {
setUser = "paul";
copyFrom = ./home-skeleton;
condition.exists = false;
};
} I think there's a lot of potential to make a much better user interface. |
@infinisil this interface also seemed to me the most straight forward at first, but I think, it's not easy (or maybe not even possible?) to make it override-able. Consider what would happen if a service file declares:
And then a user would want to add:
Hence since the directory's path could be used more then once in |
That could probably be done by specifying the merging policy in the |
But isn't the attribute's name, of the directory, has to be unique?
…On 29 September 2020 0:04:14 GMT+03:00, Silvan Mosberger ***@***.***> wrote:
That could probably be done by specifying the merging policy in the `argument` option. So that both arguments specified are joined together.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#97702 (comment)
|
Nope, that's the nice thing about the module system, it allows you to specify e.g. attributes multiple times, and it merges the values according to the specified type. E.g. this would work: {
imports = [{
systemd.tmpfiles.paths."/tmp".d.mode = "1777";
}];
systemd.tmpfiles.paths."/tmp".d.age = "10d";
} |
OK maybe I was wrong, let's take another example: Say a module imported defines: systemd.tmpfiles.paths = {
"/var/lib/mpd/music" = {
d = {
mode = "2775";
user = "mpd";
group = "syncthing";
};
};
}; And you want:
So you write: systemd.tmpfiles.paths = {
"/var/lib/mpd/music" = {
a = {
options = [ "group:syncthing:rwx" "other::rx" ];
};
};
}; Will it merge eventually into this?: systemd.tmpfiles.paths = {
"/var/lib/mpd/music" = {
a = {
options = [ "group:syncthing:rwx" "other::rx" ];
};
d = {
mode = "2775";
user = "mpd";
group = "syncthing";
};
};
}; Or will it evaluate to this?: systemd.tmpfiles.paths = {
"/var/lib/mpd/music" = {
a = {
options = [ "group:syncthing:rwx" "other::rx" ];
};
};
}; To my humble experience, it seems like the later will be the final result, since the |
We discussed about this a bit during the NixOS systemd meeting. Merging these is non-trivial, is somewhat hard to get right, and would need even more documentation and testing. Given we're slowly deprecating usage of tmpfiles in favor of |
Ok with me as I currently don't have time to work on it. |
NixOS systems meetings? Can you invite me to them? Could be interesting for me and my work homed |
Alright, I'll close it them. Yeah, most of this discussion is happening in |
In every distro, the level of control one has with tmpfiles compared to that of Perhaps if StateDirectory will become more widely adopted in the future, we could reconsider - as less tmpfiles rules will need to be rewritten with attributs. |
@flokli theres my broken irc setup again. Sometime I have to host a own matrix irc bridge, so I can join. @doronbehar maybe write me an exact interface you would like (5 rules for example or so) than I can see if I find the time in my holidays. |
The problem with Also, tmpfiles run "imperatively" once during system boot (
|
I would say it creates a benefit of working with /tmp for example. I think there is some default for /tmp, but you could override it to give it a own btrfs device or so |
The current implementation of https://gitlab.com/doronbehar/nixos-configs/blob/master/mpd.nix#L67-79 With this, plus
Luckily the line that is ignored is the line that gets written because of the nixpkgs' mpd service, and not my own, so I get the behavior I want, but that's not ideal IMO. In general, what (upstream) tmpfiles can do that StateDirectory and friends can't is to set advanced permissions on the directories. I need these special permissions so that syncthing and mpd which are on part of the same unix group on my machine and they share directories among each other. I also come and go in these directories manually and I need the permissions there to have the acl attributes I want. These are also directories that should survive boots as they have precious data like my music library etc. |
You can just drop the The
|
Maybe I should open a PR to replace the usage of |
I can't because I want different permissions there -
And what would you do? |
Well... I was going to file a PR for |
Ran fine for me with:
|
🤷♂️ |
Our commands are equivallent and we are 4 commits apart, and I ran mine with Whatever the reason maybe, what did you want to change in the mpd module? |
I would remove the usage of For a number of reasons it is too difficult to make valid assumptions about a systems filesystem layout, networked mounts, ACLs, and other unknown unknowns. This makes using I'll likely file a PR to do this sometime soon... something like this. |
See #106697 for PR. |
Motivation for this change
providing an non array way to work with systemd tmpfiles rules.
Things done
create the attribute set options
systemd.tmpfiles.paths
.sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)