Bug 1591763
| Summary: | [RFE] add -n option to crontab(5) to suppress mail when the run was successful | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 8 | Reporter: | Job Snijders <job> | ||||||||
| Component: | cronie | Assignee: | Ondřej Pohořelský <opohorel> | ||||||||
| Status: | CLOSED MIGRATED | QA Contact: | Jan Houska <jhouska> | ||||||||
| Severity: | medium | Docs Contact: | |||||||||
| Priority: | urgent | ||||||||||
| Version: | 8.2 | CC: | duge, hhorak, jhouska, jstanek, kwalker, mmuzila, opohorel, ravpatil, redhat-bugzilla, robert.scheck, sbalasub, sdarade | ||||||||
| Target Milestone: | rc | Keywords: | FutureFeature, MigratedToJIRA, Triaged | ||||||||
| Target Release: | 8.0 | Flags: | pm-rhel:
mirror+
|
||||||||
| Hardware: | Unspecified | ||||||||||
| OS: | Unspecified | ||||||||||
| Whiteboard: | |||||||||||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |||||||||
| Doc Text: | Story Points: | --- | |||||||||
| Clone Of: | Environment: | ||||||||||
| Last Closed: | 2023-09-20 12:41:50 UTC | Type: | Story | ||||||||
| Regression: | --- | Mount Type: | --- | ||||||||
| Documentation: | --- | CRM: | |||||||||
| Verified Versions: | Category: | --- | |||||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||||
| Embargoed: | |||||||||||
| Attachments: |
|
||||||||||
I will prepare a patch for cronie If you do, the best way to submit it would be via pull request on the upstream GitHub repository. I see that '-q' (still) is a valid crontab(5) entry option, so adding '-n' will not conflict with anything that exists and is deployed today. Tomas Mraz - i will fork & submit pull request to https://github.com/cronie-crond/cronie I could not locate the upstream pull request, is this feature still required? If redhat is interested in pulling this in via upstream, I am happy to create a patch. I haven’t done so yet. We would like to see this useful feature as well (however on RHEL 8, because RHEL 7 likely won't get this feature anymore, right?), thus we cross-filed case 02647599 at the Red Hat customer portal. As cronie is a fork of vixie-cron initiated by some Red Hat people years ago, getting this feature into cronie and into RHEL 8.3 shouldn't be hopefully too hard? Hi, Considering the RHEL7 lifecycle, I don't think it would be reasonable to implement this in RHEL7. Therefore, moving this to RHEL8 for future consideration. Thank you for understanding. Marcel, is this already implemented upstream? (or at least consulted?) > To improve the situation I propose to add a simple crontab(5) convenience
> option called "-n" (mnemonic "No mail if run successful").
>
> With this "no mail if success" option you can do things like:
>
> * * * * * -n cp -rv src/ dest/
>
> With the above example crontab(5) entry you'll only receive a mail from
> cron(8) if the cp(1) encountered some kind of error. You'll also have in
> that email up until what point cp(1) actually was able to copy files.
Hi,
I think that adding the '-n' option to the crontab file itself is not a good idea. AFAIK, it would require syntax change of crontab files. New field "options" would need to be added between "day of week" (or "user") field and "command" field.
I think, that a better idea would be to introduce new environment variable for this purpose, eg. MAIL_IF_SUCC. If undefined or set to 1, mail would be send as normal. If set to 0, mail would be sent only if the exit code of the job is not 0;
Hi,
I found out, that cron currently does not use any buffer to store stdout of the user command. It pipes it right to mailer process, meaning that the mailer process is ran in parallel with the user command. It means that the exit code of the user command is not yet known at the ponint when the mailer process is started. This surely could be changed, but I don't know upstreams opinion about it yet.
However there exists workaround. The crontab entry could look like this:
* * * * * if OUT=$(! <USER_COMMAND> 2>&1); then echo "$OUT"; fi
Output (stdout + stderr) of the USER_COMMAND is stored in variable OUT. Only if the user command is successfull, the output is printed on stdout.
The other possible way to achieve this could be to use some wrapper, eg.:
#!/bin/bash
OUT=$($@ 2>&1);
ECODE=$?
if [ $ECODE -ne 0 ]
then
echo "$OUT";
fi
exit $ECODE
The crontab entry would look like this:
* * * * * <PATH_TO_WRAPPER> <USER_COMMAND>
Dear Matej Mužila, Indeed, with an external wrapper similar functionality can be achieved. In my comment from 2018 I pointed out that wrappers exist but are not part of standard cron. :-) FreeBSD, NetBSD, and OpenBSD have integrated "-n" support in their respective forks of vixie-cron, this was possible because the *new* '-n' option is optional, and its use does not conflict with any existing semantics. Using cron variables certainly is possible, but makes for a less readable experience and deviates from what other notable Cron implementations choose to do. Shall I proceed to prepare a pull-request for cronie? (In reply to Job Snijders from comment #13) > Dear Matej Mužila, > > Indeed, with an external wrapper similar functionality can be achieved. In > my comment from 2018 I pointed out that wrappers exist but are not part of > standard cron. :-) > > FreeBSD, NetBSD, and OpenBSD have integrated "-n" support in their > respective forks of vixie-cron, this was possible because the *new* '-n' > option is optional, and its use does not conflict with any existing > semantics. > > Using cron variables certainly is possible, but makes for a less readable > experience and deviates from what other notable Cron implementations choose > to do. > > Shall I proceed to prepare a pull-request for cronie? Hi, if you could prepare a pull request for cronie, it would be great. After it is merged to upstream cronie, I think we could backport it to RHEL 8. Component ownership in bugzilla has changed; reassigning to new owner. Initial patch for the cronie upstream prepared: https://github.com/cronie-crond/cronie/pull/80; now let's see where the discussion will lead. I closed the original PR by accident, and had to open a new issue: https://github.com/cronie-crond/cronie/issues/89. @job, would it be feasible for you to direct further discussion mainly there, until a decision is reached? Anyway, the issues raised by upstream: > I dislike this being a new optional field in the cron entry. > I'd prefer something similar to the - at the beginning of the entry that switches off the logging (for root only). > Or perhaps the suggestion from: https://bugzilla.redhat.com/show_bug.cgi?id=1591763#c11 > That would be also easy to implement. This is a question aimed mainly at @job – would any of these options work for you? Why is it an issue for cronie upstream to stay simply consistent with the *BSD cron implementations as successor/derivate of vixie-cron? As per https://man.openbsd.org/crontab.5 there are even more flags for the command field. Would it be easier for upstream if I file another request for the other not-yet implemented flags, too? I am actually not sure how '-s' could be achieved with cronie...thus it might be a good new feature request anyway. I'd really like to encourage the Linux/BSD communities to come together on this one and provide a consistent interface across all descendants of vixie cron! :-) So far in the *BSD world these options have emerged: '-s': singleton execution, don't start new process if old one still runs '-n': no mail if exit error code is 0 (if the exit error code is 0 just kill the mailer subprocess) '-q': do not log to syslog (this option is weird to me, why would you not want to log a line when you start a process) All three can be combined, and are used in its own dedicated column between the timer field and the command. Examples: 0 * * * * -ns /usr/bin/process_that_is_verbose_and_long_running_but_only_interesting_if_it_fails * * * * * -s -q /usr/bin/run_this_as_often_as_possible_but_never_in_duplicate Putting the column between the timer field and command itself is feasible, because no-one is starting their cron commands with a '-'. Just to have it stated clearly: We are especially interested in '-n' and '-s', which cronie is currently not providing. After discussion of this issue within the engineering team, we decided to not implement this change for the time being. The reasons are mainly two: 1. The proposed design of this feature was not accepted by upstream (see https://github.com/cronie-crond/cronie/pull/80#issuecomment-809392516), and we are strongly opposed to implement this as downstream (Red Hat) only patch. 2. Since this a request for a new feature, it was given a low priority; as can be gleaned from the age of this bug, there is not enough engineering capacity to design, test and implement alternative designs at this moment. If you still wish to see this change included, please work directly with upstream (https://github.com/cronie-crond/cronie) on design and implementation. Once accepted upstream, we would be happy to include/backport the change to Fedora and RHEL. I will leave this open for a while longer in order to gater any feedback, but unless anything changes, this will be closed as WONTFIX. The proposed change is still open at https://github.com/cronie-crond/cronie/issues/89 - the closing of the issue appeared to be a mistake. I concur it to be reasonable to wait for upstream to accept the changeset. Just as a status update,
We are currently standing by for the inclusion of this feature by the upstream community. The previously mentioned request is still open at this time:
https://github.com/cronie-crond/cronie/issues/89
In addition, there is a Merge Request open for implementation.
https://github.com/cronie-crond/cronie/pull/121
As mentioned by Jan previously, it is necessary to standby for the results of those efforts before we can proceed with a possible backport evaluation for downstream RHEL releases. Please continue to monitor this bug for status updates.
The PR[0] implementing this feature has been merged by upstream. I'm currently waiting for upstream to tag a new version of cronie, in order to get this feature tested in Fedora. [0]https://github.com/cronie-crond/cronie/pull/121 (In reply to Ondřej Pohořelský from comment #49) > The PR[0] implementing this feature has been merged by upstream. > I'm currently waiting for upstream to tag a new version of cronie, in order > to get this feature tested in Fedora. > > [0]https://github.com/cronie-crond/cronie/pull/121 We kindly disagree with your suggestion. From our understanding, there should be no dependency on previous patches avoiding an easy backport. Aside of this, the testing scenario is quite easy. If you provide us a source or binary RPM, we are happy to even test this. Created attachment 1940179 [details]
Cronie with -n option implemented
The idea behind waiting for upstream and getting it to Fedora was suggested because of wider testing of this feature.
However, it would be great if you could test it in your environment and provide feedback on this patch.
I'm attaching the x86_64 build of cronie with -n feature implemented.
Ondřej, I unfortunately can not see how the cronie-1.5.2-9.el8 provided with comment #52 would work at all; I applied the following two test scenarios to it: #1: /etc/crontab * * * * * root -n cp -pv /etc/issue /tmp/issue-1 #2: crontab -e (as root) * * * * * -n cp -pv /etc/issue /tmp/issue-2 Resulting log entries in /var/log/cron are: #1: Feb 7 11:29:01 tux CROND[484971]: (root) CMD (-n cp -pv /etc/issue /tmp/issue-1) #2: Feb 7 11:32:01 tux CROND[485086]: (root) CMD (-n cp -pv /etc/issue /tmp/issue-2) While above looks already suspicious (should '-n' appear in the logged command itself?), there is neither /tmp/issue-1 nor /tmp/issue-2. And both of the test scenarios lead to a cron mail with the following body: --- 8< --- /bin/sh: - : invalid option Usage: /bin/sh [GNU long option] [option] ... /bin/sh [GNU long option] [option] script-file ... GNU long options: --debug --debugger --dump-po-strings --dump-strings --help --init-file --login --noediting --noprofile --norc --posix --rcfile --rpm-requires --restricted --verbose --version Shell options: -ilrsD or -c command or -O shopt_option (invocation only) -abefhkmnptuvxBCHP or -o option --- 8< --- Created attachment 1942842 [details]
fixed Cronie with -n option implemented
I'm terribly sorry, I've attached the wrong build. The previous one indeed didn't have the patch backported properly. Thank you for noticing and notifying me.
I'm attaching the correct build
Ondřej, I'm very sorry, but this still isn't working properly for me: The two test scenarios from comment #53 now deliver the output of my successful cp(1) via e-mail, even the exit code is zero. The same behaviour also applies for even more simple test scenarios: #1: /etc/crontab * * * * * root -n date #2: crontab -e (as root) * * * * * -n date Actually, the e-mail should be supressed if the command was run successfully (exit code zero). Ondřej, kind ping? Ondřej, kind re-ping? Created attachment 1988833 [details]
rhel 9.3 cronie with '-n option' patch
I'm adding a rhel-9.3 RPM of cronie with '-n option' patch included.
Could you please test if it works as expected?
Issue migration from Bugzilla to Jira is in process at this time. This will be the last message in Jira copied from the Bugzilla bug. This BZ has been automatically migrated to the issues.redhat.com Red Hat Issue Tracker. All future work related to this report will be managed there. Due to differences in account names between systems, some fields were not replicated. Be sure to add yourself to Jira issue's "Watchers" field to continue receiving updates and add others to the "Need Info From" field to continue requesting information. To find the migrated issue, look in the "Links" section for a direct link to the new issue location. The issue key will have an icon of 2 footprints next to it, and begin with "RHEL-" followed by an integer. You can also find this issue by visiting https://issues.redhat.com/issues/?jql= and searching the "Bugzilla Bug" field for this BZ's number, e.g. a search like: "Bugzilla Bug" = 1234567 In the event you have trouble locating or viewing this issue, you can file an issue by sending mail to rh-issues. You can also visit https://access.redhat.com/articles/7032570 for general account information. Using attachment 1988833 [details], my simple testing scenario from comment #56 works as expected - thank you! And yes, I am aware that the migration to Jira happened, I'll mention it there as well. The needinfo request[s] on this closed bug have been removed as they have been unresolved for 120 days |
Description of problem: Managing the flow of email coming from cron(8) can be a challenge, especially when you manage a lot of machines. A pattern I see in system administration is that either a ton of logic is put in wrappers/scripts to sensibly deal with any output - or even worse all output is zapped with this dreaded pattern: * * * * * command_goes_here 2>&1 >/dev/null # piloting blind In the above example when your cron job fails, you will never know about it. You were depending on cron to backup some files? Screwed! The job has been failing due to filesystem permission errors for weeks - all your files are gone. There are workarounds for cron(8)'s shortcomings: you can either put logic in your scripts to only output when things went wrong, but then you'll not know about what didn't go wrong: "do x || echo error x". Another approach is to use wrappers that buffer all output until it is clear what the exit code of the underlaying command was, and then print the output so cron will email. Shims such as cronic or chronic are popular, but not part of base. To improve the situation I propose to add a simple crontab(5) convenience option called "-n" (mnemonic "No mail if run successful"). With this "no mail if success" option you can do things like: * * * * * -n cp -rv src/ dest/ With the above example crontab(5) entry you'll only receive a mail from cron(8) if the cp(1) encountered some kind of error. You'll also have in that email up until what point cp(1) actually was able to copy files. The "-n" option also encourages folks to be liberal with adding trace options to their shell scripts like "set -o errexit -o nounset -o xtrace", and just focus on making sure the script exits with a sensible exit code. This way when there is some kind of problem, you can read the full context from the cron mail and be more productive; and if there is no problem, you won't receive an email, reducing clutter in your inbox. Additional info: OpenBSD & NetBSD implemented this in their forks of vixie cron OpenBSD: Cover letter https://marc.info/?l=openbsd-tech&m=152874866117948&w=2 / commit: https://github.com/openbsd/src/commit/14eea8168449751553ba549cb1e8725fe289aeaf NetBSD: commit: https://github.com/NetBSD/src/commit/666eac5018f695be8449458fffd3de77d9305eb1