Skip to content

feat: add IMAP IDLE support for getmail - #4675

Open
brainkiller wants to merge 2 commits into
docker-mailserver:masterfrom
brainkiller:master
Open

brainkiller wants to merge 2 commits into
docker-mailserver:masterfrom
brainkiller:master

Conversation

@brainkiller

@brainkiller brainkiller commented Mar 6, 2026

Copy link
Copy Markdown
Contributor

Similar to the FETCHMAIL_PARALLEL option which enables the use of IMAP IDLE, this PR provides the same functionality for getmail.
It builds upon the existing code as it doesn't touch the config file generation. Instead it only focusses on the start of getmail.
This should provide the functionality requested in discussion #4667

Type of change

  • Improvement (non-breaking change that does improve existing functionality)
  • This change requires a documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (README.md or the documentation under docs/)
  • If necessary, I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have added information about changes made in this PR to CHANGELOG.md

@github-actions

Copy link
Copy Markdown
Contributor

Documentation preview for this PR is ready! 🎉

Built with commit: b9477ef

@casperklein

Copy link
Copy Markdown
Member

Thank you for your contribution. Just wanted to let you know, that we are quiet busy and review will take same time.

@georglauterbach georglauterbach added kind/new feature A new feature is requested in this issue or implemeted with this PR area/features stale-bot/ignore Indicates that this issue / PR shall not be closed by our stale-checking CI service/getmail labels Mar 28, 2026
@georglauterbach georglauterbach moved this to Rationale Provided in DMS Features & Tasks Mar 28, 2026
@georglauterbach georglauterbach added this to the v17.0.0 milestone Mar 28, 2026
@georglauterbach

Copy link
Copy Markdown
Member

I will also take a look, but all PRs are currently blocked for me because of #4536

@polarathene

Copy link
Copy Markdown
Member

Oh I thought this was scheduled for v16 😓

I've had a glance over the PR diff but I would like to try take a simpler approach which I've outlined here: #4713 (comment)

That's dependent upon upstream and DMS switching back to using the PyPi package instead of the Debian one to benefit from that.

Taking the approach I've outlined would roughly reduce down to this:

[program:getmail-parallel]
numprocs = 2
numprocs_start = 1
process_name = %(program_name)s-%(process_num)s
autorestart = true
stopasgroup = true
command = bash -c 'getmail --getmaildir /var/lib/getmail --rcfile getmailrc-account-%(process_num)s && sleep %(ENV_GETMAIL_POLL)sm'

NOTE: Until such a PR is feasible, any DMS user could add the above as a config mount into /etc/supervisor/conf.d/ and with a complimentary user-patches.sh file (docs) that places the --rcfile referenced entries into the --getmaildir location (using a naming convention that can utilize %(process_num)s), should be simple enough to iterate over and rename/symlink such file names.

For the IDLE support, add the --idle=INBOX option. If you need something more flexible, a script should work. Instead of an ENV to split up, you could use the service process_num expression (perhaps via the supervisord environment setting, similar to what you already did for SERVICE_NAME) and take a list of files and sort them ($(ls -1 /var/lib/getmail | sort)?) then use the index on that to select the appropriate file-name. You could then have a regex for the filename suffix .idle-INBOX to detect when to add --idle and the value to assign it? (seemed simpler than the ENV or a JSON/YAML/TOML mapping)

Or adapt the approach you've got here. It's just more of a hassle to merge a feature when it could be greatly simplified by getting support for the idle setting in config files upstream 😅

@polarathene

polarathene commented Jun 6, 2026

Copy link
Copy Markdown
Member

I spent more time on investigating this integration with upstream.

  • As it stands the --idle option has only been relevant for what mailbox to monitor over IMAP for notification of when to restart Getmail's processing loop.
  • mailboxes must be configured as this is what actually is used to retrieve over IMAP, the --idle is just a trigger event. As such the default mailboxes = ("INBOX",) would result in whatever mailbox --idle subscribes to as pulling from the primary INBOX instead. Something this PR with it's test implementation was not covering, thus not caught.

The latest unreleased Getmail commits have added the ability to use --idle= (no value assigned) to exclude a mailbox value and infer it from the first item of mailboxes. I'd still rather push for a breaking change to treat --idle as a boolean toggle like Fetchmail and have that supported in configs, but upstream has been a bit reluctant on this (the project being named getmail6 doesn't lend too well to semver and breaking changes..).

Arguably the feature itself as I have described it (and as it is vaguely documented at the Getmail6 project) is in itself broken and not working as implied/documented.


Furthermore, I'd like to know the benefit of enabling/supporting IDLE, given the single mailbox limitation?

  • What advantages are being sought out with long-lived connections over multiple Getmail instances, instead of polling at a shorter interval?
  • Or rather... Is there an actual problem that IMAP IDLE is solving vs using Polling? How many mailboxes are you configuring, is it more than the standard INBOX per account?

I assume it's very few remote accounts and quite possibly only the default INBOX being monitored. I'm just curious how important the feature actually is to you, or if it's more of just an ick with polling often instead of receiving a notification from the remote server?

Related history for Fetchmail idle support:

@brainkiller

Copy link
Copy Markdown
Contributor Author

Personally I don't consider the single folder a limitation.
As you say, it will mostly only monitor the inbox, except in some odd use cases someone might want to change this (to only get mails filtered by sieve).
If we can get this feature implemented I plan to configure it for 7 accounts to download mails.

The issue I find with polling is that you need to get the interval down to a minute maximum.
Due to all these security featues on various sites where they send you a mail to confirm it's you but these links are only valid for a couple of minutes. If your interval is too long you have to make several attempts before you can successfully login (hoping you don't get locked out after the 5th attempt).

@polarathene

Copy link
Copy Markdown
Member

The issue I find with polling is that you need to get the interval down to a minute maximum.

Fair enough, thank you :)

As you say, it will mostly only monitor the inbox, except in some odd use cases someone might want to change this (to only get mails filtered by sieve).

I've yet to get around to filing a bug report properly upstream, but I have pointed it out to the maintainer already that the --idle flag is implemented poorly.

It is designed to specify a mailbox to receive a notification about updates from, and yet there's no documentation to note that configuring that alone is insufficient if your mailbox is not INBOX. Fetchmail implemented the feature far better.

As this PR lacks a test case for catching that, users are just as likely to make that mistake unaware of it (I'm kind of surprised that it hasn't been raised as a bug report upstream thus far, but perhaps nobody is bothering to use Getmail with mailboxes other than INBOX 🤷‍♂️)


I'll return to this PR after I've approved the Dovecot 2.4 / Debian 13 upgrade PR. I'd much prefer convincing upstream to improve so integration in DMS has reduced complexity.

Apologies for the delay that causes here, but thus far I think you're the only user that's requested support for the feature in DMS 😅 I don't mind supporting integrations that can justify the convenience for users well enough, but I also would very much like it done right so that it's minimal burden to maintainers to carry.

@georglauterbach georglauterbach added priority/low and removed stale-bot/ignore Indicates that this issue / PR shall not be closed by our stale-checking CI labels Aug 30, 2026
@georglauterbach georglauterbach changed the title FEATURE: Add IMAP IDLE support for getmail feat: add IMAP IDLE support for getmail Sep 7, 2026
@georglauterbach georglauterbach moved this from Rationale Provided to In Review in DMS Features & Tasks Sep 7, 2026
@georglauterbach

Copy link
Copy Markdown
Member

@brainkiller It took me a while, but we are now ready to look at this PR again. Please rebase onto the latest master to resolve the conflicts. I will then be reviewing this PR so we can go forward with it.

Note: In general, a discussion is not sufficient to get a new feature in like that because it's likely to be unnoticed by maintainers like me. But looking at the discussion at hand, I think it's fair. Please open an issue next time, though :)

@brainkiller

Copy link
Copy Markdown
Contributor Author

Damn looks like I closed this PR accidently while trying to re-base. I'm re-opening it with my proposed changes

@brainkiller brainkiller reopened this Sep 12, 2026
@brainkiller
brainkiller marked this pull request as ready for review September 12, 2026 21:54
@georglauterbach

Copy link
Copy Markdown
Member

No worries, I'll be looking into it shortly.

@georglauterbach georglauterbach left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Requesting changes for two blocking issues: GETMAIL_IDLE account matching is a substring glob (wrong configs/mailboxes can get --idle), and _filter_service_log now looks inside the container, which redirects other test suites away from /var/log/mail. Inline comments have the details.

done
GETMAIL_OPTS=()
# If the getmailrc file contains IMAP configuration and the GETMAIL_IDLE variable is set to "auto" or contains the specific getmailrc file, enable IMAP IDLE for this getmailrc file.
if grep -q 'IMAP' "${RC_FILE}" && [[ ${GETMAIL_IDLE} == "auto" || ${GETMAIL_IDLE} == *$(basename "${RC_FILE}")* ]]; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

GETMAIL_IDLE is matched with unquoted substring globs (*$(basename "${RC_FILE}")*), including the inner check on line 124. A value of user4 also matches configs named user, user4-backup, or myuser4, and can attach the wrong --idle= mailbox. Compare the token before : with an exact equality against the rc basename (the .cf stem in /etc/getmailrc.d/).

local FILE="/var/log/supervisor/${SERVICE}.log"
# Alternative log location fallback:
[[ -f ${FILE} ]] || FILE="/var/log/mail/${SERVICE}.log"
_exec_in_container test -f ${FILE} || FILE="/var/log/mail/${SERVICE}.log"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This used to run [[ -f ... ]] on the host, so /var/log/supervisor/${SERVICE}.log was never found and every caller fell back to /var/log/mail/. Checking inside the container makes any supervised program (notably rspamd) prefer an often-empty or stdout-only supervisor log. Getmail’s _log messages do belong in supervisor logs; assert that in getmail.bats (or a dedicated helper) instead of changing this shared helper.

VARS[FETCHMAIL_POLL]="${FETCHMAIL_POLL:=300}"
VARS[GETMAIL_POLL]="${GETMAIL_POLL:=5}"
VARS[GETMAIL_PARALLEL]="${GETMAIL_PARALLEL:=0}"
VARS[GETMAIL_IDLE]="${GETMAIL_IDLE:=auto}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Defaulting GETMAIL_IDLE to auto means GETMAIL_PARALLEL=1 turns on --idle for every IMAP rc, with no documented off switch (mailserver.env is also not updated). Default it empty/off, and treat auto as an explicit opt-in.


##### GETMAIL_IDLE

- **auto** => `getmail` Specify which getmail configs should be started with the --idle flag. By default it shall look for the folder INBOX. This can be changed by specifying the folder with a colon. If auto is set, it will be enable for ever IMAP config. Default: auto.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This describes the selector as account1, and __usage in getmail-service.sh uses getmail-1.rc, but matching uses the config filename without .cf (e.g. user3). Please document that token, and that --idle=FOLDER only watches that folder for notifications — getmail still fetches mailboxes (default INBOX).

_init_with_defaults
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'

CONTAINER_NAME=${CONTAINER3_NAME}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

setup_file leaves CONTAINER_NAME set to CONTAINER3_NAME, so the original sequential tests run against the parallel+IDLE container. Export CONTAINER_NAME=${CONTAINER1_NAME} in those tests. The new cases only grep debug log strings; a pgrep --full --idle= check would catch argv mistakes the logs can miss.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/features kind/new feature A new feature is requested in this issue or implemeted with this PR priority/low service/getmail

Projects

Development

Successfully merging this pull request may close these issues.

4 participants