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

cyr_expire: add noexpire_until annotation #4533

Merged
merged 5 commits into from
Jul 26, 2023
Merged

cyr_expire: add noexpire_until annotation #4533

merged 5 commits into from
Jul 26, 2023

Conversation

rsto
Copy link
Member

@rsto rsto commented Jun 14, 2023

This PR includes fixes and enhancements for cyr_expire:

  • It fixes a bug in which the expire/delete/archive mailbox annotations were only read for a given mailbox, rather than looking its value up in all the parent mailboxes.
  • It removes a noisy and unhelpful debug message from logging
  • It adds support for non-day durations in the expire/delete/archive annotations by use of the Cyrus-config supported duration format. cyr_expire already had included support to read such values, but they could only be set as command line flags.
  • It adds the noexpire_until annotation that allows to block expiring and deleting until a given future date, or indefinitely.

This PR best is read commit by commit.

@rsto rsto requested review from ksmurchison and elliefm June 14, 2023 12:01
Copy link
Contributor

@ksmurchison ksmurchison left a comment

Choose a reason for hiding this comment

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

LGTM

@elliefm
Copy link
Contributor

elliefm commented Jun 16, 2023

CI shows this failing these two tests:

[FAILED] Cyrus::Metadata.private
[FAILED] Cyrus::Metadata.shared

Copy link
Contributor

@elliefm elliefm left a comment

Choose a reason for hiding this comment

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

Two failing tests under CI, though they might just be stale tests following these changes.

Of greater concern to me is the syntax incompatibility within cyr_expire between durations as received from the command line vs durations read from annotations. This needs to be carefully documented, or perhaps homogenised... and then carefully documented. Details within. :)

Comment on lines 381 to 384
time_t until;
if (get_time_annotation(mbname_intname(mbname),
IMAP_ANNOT_NS "noexpire_until", &until, false))
ret = !until || progtime < until;
Copy link
Contributor

Choose a reason for hiding this comment

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

time_t is signed, so there's an odd discontinuity in the value range here like:
| [valid negative times] [0=infinity] [valid positive times] |.

I'm not sure if that's likely to be a problem here, but it would be easier to reason about if the ret = ... line was unfolded into separate checks for each possibility.

Copy link
Member Author

Choose a reason for hiding this comment

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

These conditionals should be fine. Quoting GNU libc documentation:

On POSIX-conformant systems, time_t is an integer type and its values represent the number of seconds elapsed since the epoch, which is 00:00:00 on January 1, 1970, Coordinated Universal Time.

Also, the annotation value type in annotate.c is defined be an unsigned integer, so any negative value will be rejected on write.

I'm not sure if there's a need to break up the lines, still?

Copy link
Contributor

Choose a reason for hiding this comment

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

In that case it might be worth putting a comment there, so the next reader doesn't need to wrack their brain wondering whether there's a bad edge case for pre-1970 dates (negative time_t)

Copy link
Member Author

Choose a reason for hiding this comment

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

Comment on lines +48 to +50
The first three mailbox annotations specify the age of messages in the
given mailbox that should be expired/archived/deleted. The
age is specified as a duration, the default unit are days.
Copy link
Contributor

Choose a reason for hiding this comment

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

Need to describe the valid annotation durations here (or refer them to imapd.conf(5), which already describes them), and also need to be explicit that these are different from the durations supported in the command line arguments (which are described under the heading for -D, --delete-duration).

The command line durations are parsed by parse_duration(), a static function in cyr_expire.c, which allows and understands decimal places (e.g. 1.5d) for whatever reason, though it reduces to integer seconds in the end. config_parseduration() doesn't accept decimals because we didn't think it necessary -- the same thing can be expressed as 36h or 1d12h, for example (the latter of which parse_duration() can't handle). So as presently implemented, valid command line durations and valid annotation/config durations are superficially similar, but aren't strictly interchangeable.

An approach here might be to just get rid of parse_duration(), and switch to using config_parseduration() for the command-line options too. We'd need to document the change loudly when we release 3.10, in case anyone had been relying on the decimal parsing, but at least then all our "durations" will be consistent (unless there's others hiding somewhere...). If we decide decimals are important enough to keep after all, we could probably extend config_parseduration() to support them. (Though that could get messy... what should 1.5h12m do?)

The description in imapd.conf(5) comes from here: https://github.com/cyrusimap/cyrus-imapd/blob/master/lib/imapoptions#L87-L94. But you can't just copy and paste that into an RST document, it's in the wrong format (for silly historical reasons). If you want to copy and paste this text, first make man so that docsrc/imap/reference/manpages/configs/imapd.conf.rst gets generated, then copy and paste from that.

The RST syntax for linking to one of our man pages is:

:cyrusman:`imapd.conf(5)`

Copy link
Member Author

Choose a reason for hiding this comment

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

Argh, thanks for this. I was totally not aware of this.

Copy link
Contributor

Choose a reason for hiding this comment

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

cyr_expire is a mess and it feels everything we try to clean up in it shakes out more chaos 😅

Copy link
Member Author

Choose a reason for hiding this comment

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

I now replaced custom cyr_expire durations with config_parseduration: cf10431

rsto added 3 commits June 19, 2023 15:51
cyr_expire already supports reading durations such as '1h'
but only numeric durations defaulting to day units could
be set via IMAP.

Signed-off-by: Robert Stepanek <[email protected]>
cyr_expire annotations are either set on a mailbox or any of its
parents. But looking up annotations on the parent mailboxes got
broken in 2018 during mailbox name to mailbox id migration.

Signed-off-by: Robert Stepanek <[email protected]>
It's just noisy and in its current form does not provide
enough context for debugging anyway.

Signed-off-by: Robert Stepanek <[email protected]>
Copy link
Contributor

@elliefm elliefm left a comment

Choose a reason for hiding this comment

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

That looks good, thanks.

The two Metadata tests are still failing in CI. I haven't looked closely at them; I assume they're probably just out of date wrt these changes and need to be updated, but they might be complaining about something real. They failed for me locally last time I reviewed, and I assume they would do the same again, but I haven't actually pulled the branch and built/tested it this time.

@rsto
Copy link
Member Author

rsto commented Jun 21, 2023

The two Metadata tests are still failing in CI.

Fixed now.

@rsto rsto merged commit f5cb034 into master Jul 26, 2023
2 checks passed
@rsto rsto deleted the cyr_expire_noexpire branch July 26, 2023 11:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants