-
-
Notifications
You must be signed in to change notification settings - Fork 14.9k
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
logrotate: update to freeform #162063
logrotate: update to freeform #162063
Conversation
@martinetd regarding the build error for the manual:
this is related to a new todo item in the PRs' template:
|
b7c0fed
to
8a64038
Compare
Mostly fixed what I wanted, still need to figure out why the manual check fails now (+ stray tab but that one is easy and isn't related)... out of time for today, later! |
Is it possible to add the ability to specify several different files?
Result:
|
It was meant to be possible yes! I don't think I changed this part and didn't test but this obviously doesn't work as you've pointed out... |
I'm finishing this up but for your question this actually works, the problem is the usage -- I'm actually curious nix doesn't error on this for you, when I try I get this error as appropriate:
There are two errors:
And generates the following, which should work (I think):
(daily and rotate 20 come from default values of frequency and keep; the current version will also have plenty of empty lines that I've trimmed in an update I'm planning to push as soon as I understand why manual stopped building...) |
8a64038
to
2097eba
Compare
2097eba
to
d5f547e
Compare
Okay, I think we're good this time. Style aside I see no more big problem.
Happy to adjust things as requested, please have a look @ius @Artturin @aanderse @dasJ ! thanks! |
3058cc8
to
d3c9e54
Compare
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.
For a consistent code source style, you may run nixpkgs-fmt on the .nix
files (in a dedicated commit to facilitate reviewing).
Great work @martined! Thanks for having taken time to revamp this service with so much attention to corner cases. :)
(mapAttrsToList generateLine settings) | ||
++ [ | ||
# user and group must be handled together | ||
(if (settings.user or null != null && settings.group or null != null) |
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.
Since user
and group
have default values this should be equivalent to settings.user != null
and settings.group != null
. If you ever need to see if a module option has been defined, you may add options
to the { config, lib, pkgs, ... }:
and use options.services.logrotate.settings.foo.isDefined
.
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 and no, that would be true for paths
attrsets but generateSection
is also used with services.logrotate.settings
which doesn't have default values there.
# logrotate --debug also checks that users specified in config | ||
# file exist, but we only have sandboxed users here so brown these | ||
# out. according to man page that means su, create and createolddir. | ||
# XXX find a way to use real /etc/passwd and /etc/groups |
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 don't think it's possible to use the real /etc/passwd
and /etc/groups
at build time, especially when mutableUsers == true
.
nixos/tests/logrotate.nix
Outdated
machine = { ... }: { | ||
nodes = { | ||
# default machine | ||
defMachine = { ... }: { |
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.
defaultMachine
would be clearer and needs no comment.
@@ -36,15 +33,17 @@ let | |||
type = with types; nullOr str; | |||
default = null; | |||
description = '' | |||
The user account to use for rotation. | |||
The user account to use for rotation. This setting is deprecated, please use |
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.
If that settings is to be deprecated I would use mkRemovedOptionModule
with a message indicating to use su
, because a simple change in the description goes easily unnoticed.
And simplify the module and test by removing the new code to support the backward compatibility.
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 wanted to leave a window with the setting deprecated but still working, it's possible by adding warnings by setting config.warnings conditionally (plenty of examples about) but I didn't get around to it yet.
I agree the description isn't enough in itself, but I think warnings can be added in a subsequent PR so as not to slow this down -- I don't really like PRs growing in scope all the time and prefer to keep goals somewhat constrainted... But if I get around to it fast enough I'll update this PR when I'm done.
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.
(that being said, if the consensus is to deprecate settings the hard way, it'll definitely make this module a bit simpler and I don't particularly mind for myself. We can easily remove everywhere I've marked deprecated and most of the exceptions I added to generateConfig)
default = null; | ||
description = '' | ||
Extra lines prepended to logrotate configuration file. | ||
Deprecated, use settings instead. |
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.
For a prettier rendering, you may use: <xref linkend="opt-services.logrotate.settings"/>
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.
Thanks for the review! I'll fix the two suggestions I didn't reply to tonight, and check nixpkgs-fmt as well.
@@ -36,15 +33,17 @@ let | |||
type = with types; nullOr str; | |||
default = null; | |||
description = '' | |||
The user account to use for rotation. | |||
The user account to use for rotation. This setting is deprecated, please use |
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 wanted to leave a window with the setting deprecated but still working, it's possible by adding warnings by setting config.warnings conditionally (plenty of examples about) but I didn't get around to it yet.
I agree the description isn't enough in itself, but I think warnings can be added in a subsequent PR so as not to slow this down -- I don't really like PRs growing in scope all the time and prefer to keep goals somewhat constrainted... But if I get around to it fast enough I'll update this PR when I'm done.
(mapAttrsToList generateLine settings) | ||
++ [ | ||
# user and group must be handled together | ||
(if (settings.user or null != null && settings.group or null != null) |
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 and no, that would be true for paths
attrsets but generateSection
is also used with services.logrotate.settings
which doesn't have default values there.
@martinetd i am currently writing the logrotate configuration with extraConf. The resulting file looks like this:
Instead of this variant:
It is possible to generate this variant:
Will work too. |
Another option would be to add the option of writing all the parameters to the very top of the configuration, which are used by default. The parameters specified below in the file overwrite the upper parameters. |
|
Thanks for your review! I've opened a PR with option removal (as draft) and added a comment with a link to it. |
8e6c6a2
to
a279768
Compare
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.
Seems fine
Built a vm and compared the new generated file to the old one and it was ok
21c9129
to
4a466cb
Compare
squashed locally to preserve commit messages |
4a466cb
to
1647fd2
Compare
Thanks! I prefer to keep things split slightly though to illustrate logical changes, I've fixed the history up so all fixes commits are squashed with their appropriate counterpart, and we can just e.g. revert the logrotate-checkconf service commit if this becomes needed later, or simply for easier history reading while keeping the system bisectable (well, at least I've checked that nixosTests.logrotate passes for each commit individually, so logrotate is "instantiable" at all time) You can check this results in no code change:
I appreciate your effort of manually squashing though, and have kept your squashed commit around in a local branch if you strongly prefer a single commit for merging (just push it back or tell me to and I will) |
having pkgs.logrotate depend on mailutils brings in quite a bit of dependencies through mailutil itself and recursive dependency to guile when most people do not need it. Remove mailutils dependency from the package, and conditionally add it to the service if the user specify the mail option either at top level or in a path Fixes NixOS#162001
Running once now will make further patches formatting easier
using freeform is the new standard way of using modules and should replace extraConfig. In particular, this will allow us to place a condition on mails
Now the service no longer starts immediately, check if the config we generated makes sense as soon as possible. The check isn't perfect because logrotate --debug wants to check users required, there are two problems: - /etc/passwd and /etc/group are sandboxed and we don't have visibility of system users - the check phase runs as nixbld which cannot su to other users and logrotate fails on this Until these two problems can be addressed, users-related checks are filtered out, it's still much better than no check. The check can be disabled with services.logrotate.checkConfig if required (bird also has a preCheck param, to prepare the environment before check, but we can add it if it becomes necessary) Since this makes for very verbose builds, we only show errors: There is no way to control log level, but logrotate hardcodes 'error:' at common log level, so we can use grep, taking care to keep error codes Some manual tests: ───────┬────────────────────────────────────────── │ File: valid-config.conf ───────┼────────────────────────────────────────── 1 │ missingok ───────┴────────────────────────────────────────── logrotate --debug ok grep ok ───────┬────────────────────────────────────────── │ File: postrotate-no-end.conf ───────┼────────────────────────────────────────── 1 │ missingok 2 │ /file { 3 │ postrotate 4 │ test 5 │ } ───────┴────────────────────────────────────────── error: postrotate-no-end.conf:prerotate, postrotate or preremove without endscript ───────┬────────────────────────────────────────── │ File: missing-file.conf ───────┼────────────────────────────────────────── 1 │ "test" { daily } ───────┴────────────────────────────────────────── error: stat of test failed: No such file or directory ───────┬────────────────────────────────────────── │ File: unknown-option.conf ───────┼────────────────────────────────────────── 1 │ some syntax error ───────┴────────────────────────────────────────── logrotate --debug ok error: unknown-option.conf:1 unknown option 'some' -- ignoring line ───────┬────────────────────────────────────────── │ File: unknown-user.conf ───────┼────────────────────────────────────────── 1 │ su notauser notagroup ───────┴────────────────────────────────────────── error: unknown-user.conf:1 unknown user 'notauser' In particular note that logrotate would not error on unknown option (it just ignores the line) but this change makes the check fail.
the build-time check is not safe (e.g. doesn't protect from bad users or nomissingok paths missing), so add a new unit for configuration switch time check
1647fd2
to
829c611
Compare
aa0f27a introduced a small conflict so I've rebased the branch to today's master. @aanderse my suggestion to review the final form in #164169 instead still stands if you |
@ofborg test logrotate gitlab nginx systemd You have written tests so if these pass I think ill merge |
The tests passed! thanks! |
Thanks for your work |
🚀 |
}; | ||
|
||
mailOption = | ||
if foldr (n: a: a || n ? mail) false (attrValues cfg.settings) |
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.
Sorry for the late comment, but this doesn't seem to be accounting for when the user sets mail = false
(so that nomail
appears in the appropriate section in logrotate.conf
).
In other words, if the user sets mail = false
in one of the sections in the settings, the --mail
option will get added even though no section in the settings actually sets mail = true
.
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.
good point, I'll update it to a || n.mail or false
in a new PR (EDIT: when I get home, so now + ~7 hours)
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.
Done in #177106
|
||
mailOption = | ||
if foldr (n: a: a || n ? mail) false (attrValues cfg.settings) | ||
then "--mail=${pkgs.mailutils}/bin/mail" |
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.
Again, sorry for the late comment, but shouldn't this be something like:
if /* ... */
then "\"--mail=${pkgs.mailutils}/bin/mail -s\""
else ""
i.e., shouldn't the -s
argument be specified?
The logrotate
man page says (about the --mail
option):
This command should accept two arguments: 1) the subject of the message, and 2) the recipient.
(...)
The default mail command is/bin/mail -s
.
Please note that I haven't actually tested sending mail, though (neither with nor without the -s
option).
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.
hm, this comes straight from what we had in the package, from the recent diff:
- ] ++ lib.optionals (mailutils != null) [
- "--with-default-mail-command=${mailutils}/bin/mail"
];
So if this doesn't work then it's likely sending mails from logrotate never worked...
I'll admit I never tested either myself, I'll give it a try this weekend unless someone beats me to it.
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.
from logrotate changelog:
106: - remove `-s` from `DEFAULT_MAIL_COMMAND` and improve its documentation (#152)
You might be looking at old man page? that dates 3.13.0 (2017)....
looking at the code and not testing I think we're fine, my setup is half broken so it's a pain to test and I'll leave it at code inspection...
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, I think you are correct.
I was looking at https://linux.die.net/man/8/logrotate, which is what man configuration.nix
pointed me at, but it seems that this man page is not up-to-date.
Motivation for this change
logrotate is much bigger than intended through its mailutils dependency as reported in #162001
This attempts to resolve the problem by making the dependency only appear when required.
Notes:
setting paths user/group doesn't work and was commented(EDIT: looking around I quite like what nixos/modules/services/networking/bird.nix is doing with a checkPhase on a file that can be disabled through cfg.checkConfig in pkgs.writeTextFile. We can do this easily, I'm mostly done with that)
(EDIT2: done, but doesn't check users -- if someone knows how to do that it'd be great...)
EDIT: I have no idea why the manual update check fails -- updating an existing section is not allowed?Things done
./result/bin/
)