remail/pipe: Add command line option to handle config updates

When using pipe mode configuration updates are not handled until the next
mail is sent to the list. That means that e.g. welcome mails are delayed.

Add a command line option to allow the invocation of remail_pipe just to
deal with configuration updates without trying to process mail from stdin.

The update handling is serialized against concurrent incoming mail via the
folder lock, so no extra serialization is required. Whichever comes first
handles it.

Reported-by: Konstantin Ryabitsev <>
Signed-off-by: Thomas Gleixner <>
Tested-by: Konstantin Ryabitsev <>
This commit is contained in:
Thomas Gleixner 2020-09-19 01:43:07 +02:00
parent 3237b7ee67
commit 05ac7bb6ac
3 changed files with 17 additions and 3 deletions

View file

@ -24,6 +24,14 @@ Options
-h, --help
Show this help message and exit
-c, --cfgupdate
Read the configuration update and do not process mail from stdin. That
allows to send out welcome mails after a list configuration file was
updated. Otherwise the welcome mails are delayed until actual mail
delivery happens. The update and welcome mail processing is serialized
via the lock file in the working directory; no external serialization
against a concurrent mail delivery required.
-s syslog, --syslog
Use syslog for logging. Default is stderr
@ -59,7 +67,7 @@ Exit codes
.. list-table::
* - 0
- Mail was successfully delivered
- Mail was successfully delivered or config update was successful
* - 1
- No enabled mailinglist found for delivery
* - 2

View file

@ -370,13 +370,16 @@ class remaild(object):
return self.should_stop()
# The pipe handling interface
def handle_pipe(self):
def handle_pipe(self, cfgupdate):
self._should_reload = True
if not self.enabled:
return 1
if cfgupdate:
return 0
policy = EmailPolicy(utf8=True)
msg = message_from_file(sys.stdin, policy=policy)
return self.process_msg(msg, 'pipe input')

View file

@ -19,6 +19,9 @@ def exit_daemon(logger, res):
if __name__ == '__main__':
parser = ArgumentParser(description='remail pipe')
parser.add_argument('config', help='Config file')
parser.add_argument('--cfgupdate', '-c', dest='cfgupdate',
help='Handle config file update. No mail processing.')
parser.add_argument('--syslog', '-s', dest='syslog', action='store_true',
help='Use syslog for logging. Default is stderr')
parser.add_argument('--verbose', '-v', dest='verbose', action='store_true',
@ -46,7 +49,7 @@ if __name__ == '__main__':
exit_daemon(logger, 11)
res = rd.handle_pipe()
res = rd.handle_pipe(args.cfgupdate)
except Exception as ex:
Exceptions which reach here are fatal