Jimmy Bergman has proposed merging 
lp:~jimmy-sigint/mailman/postfix_relay_domains_map into lp:mailman.

Requested reviews:
  Mailman Coders (mailman-coders)

For more details, see:
https://code.launchpad.net/~jimmy-sigint/mailman/postfix_relay_domains_map/+merge/125241

Writes a domain map that postfix can use as relay_domains automatically on list 
creation/removal, and
documents this in the MTA documentation-file.
-- 
https://code.launchpad.net/~jimmy-sigint/mailman/postfix_relay_domains_map/+merge/125241
Your team Mailman Coders is requested to review the proposed merge of 
lp:~jimmy-sigint/mailman/postfix_relay_domains_map into lp:mailman.
=== modified file 'src/mailman/docs/MTA.rst'
--- src/mailman/docs/MTA.rst	2012-09-06 01:30:35 +0000
+++ src/mailman/docs/MTA.rst	2012-09-19 15:07:31 +0000
@@ -102,17 +102,14 @@
         hash:/path-to-mailman/var/data/postfix_lmtp
     local_recipient_maps =
         hash:/path-to-mailman/var/data/postfix_lmtp
+    relay_domains =
+        hash:/path-to-mailman/var/data/postfix_domains
 
 where `path-to-mailman` is replaced with the actual path that you're running
 Mailman from.  Setting `local_recipient_maps` as well as `transport_maps`
 allows Postfix to properly reject all messages destined for non-existent local
-users.
-
-
-Virtual domains
----------------
-
-TBD: figure out how virtual domains interact with the transport maps.
+users. Setting `relay_domains` means postfix will start to accept mails for
+newly added domains even if they are not part of `mydestination`.
 
 
 Sendmail

=== modified file 'src/mailman/mta/postfix.py'
--- src/mailman/mta/postfix.py	2012-04-26 02:08:22 +0000
+++ src/mailman/mta/postfix.py	2012-09-19 15:07:31 +0000
@@ -64,6 +64,7 @@
         # We can ignore the mlist argument because for LMTP delivery, we just
         # generate the entire file every time.
         self.regenerate()
+        self.regenerate_domain()
 
     delete = create
 
@@ -107,6 +108,46 @@
                 log.error(msg, command, status, errstr)
                 raise RuntimeError(msg % (command, status, errstr))
 
+    def regenerate_domain(self, output=None):
+        """The map for all list domains
+
+        The format for Postfix's LMTP transport map is defined here:
+        http://www.postfix.org/transport.5.html
+        """
+        # Acquire a lock file to prevent other processes from racing us here.
+        lock_file = os.path.join(config.LOCK_DIR, 'mta')
+        with Lock(lock_file):
+            # If output is a filename, open up a backing file and write the
+            # output there, then do the atomic rename dance.  First though, if
+            # it's None, we use a calculated path.
+            if output is None:
+                path = os.path.join(config.DATA_DIR, 'postfix_domains')
+                path_new = path + '.new'
+            elif isinstance(output, basestring):
+                path = output
+                path_new = output + '.new'
+            else:
+                path = path_new = None
+            if path_new is None:
+                self._do_write_file_domains(output)
+                # There's nothing to rename, and we can't generate the .db
+                # file, so we're done.
+                return
+            # Write the file.
+            with open(path_new, 'w') as fp:
+                self._do_write_file_domains(fp)
+            # Atomically rename to the intended path.
+            os.rename(path + '.new', path)
+            # Now that the new file is in place, we must tell Postfix to
+            # generate a new .db file.
+            command = config.mta.postfix_map_cmd + ' ' + path
+            status = (os.system(command) >> 8) & 0xff
+            if status:
+                msg = 'command failure: %s, %s, %s'
+                errstr = os.strerror(status)
+                log.error(msg, command, status, errstr)
+                raise RuntimeError(msg % (command, status, errstr))
+
     def _do_write_file(self, fp):
         """Do the actual file writes for list creation."""
         # Sort all existing mailing list names first by domain, then by local
@@ -137,3 +178,22 @@
                 for alias in aliases:
                     print(ALIASTMPL.format(alias, config, width), file=fp)
                 print(file=fp)
+
+    def _do_write_file_domains(self, fp):
+        """Do the actual file writes of the domain map for list creation."""
+        # Sort all existing mailing list names first by domain, then my local
+        # part.  For postfix we need a dummy entry for the domain.
+        by_domain = []
+        for list_name, mail_host in getUtility(IListManager).name_components:
+            by_domain.append(mail_host)
+        print("""\
+# AUTOMATICALLY GENERATED BY MAILMAN ON {0}
+#
+# This file is generated by Mailman, and is kept in sync with the binary hash
+# file.  YOU SHOULD NOT MANUALLY EDIT THIS FILE unless you know what you're
+# doing, and can keep the two files properly in sync.  If you screw it up,
+# you're on your own.
+""".format(now().replace(microsecond=0)), file=fp)
+        for domain in sorted(by_domain):
+            print("""{0} {0}""".format(domain), file=fp)
+

_______________________________________________
Mailman-coders mailing list
[email protected]
http://mail.python.org/mailman/listinfo/mailman-coders

Reply via email to