[Mailman-Developers] Newlist/rmlist update
Marc MERLIN
marc_news@vasoftware.com
Tue, 1 Jan 2002 20:33:01 +0100
As promised, here's a patch that:
1) Adds the SPLIT_DIRS option which does this:
root@gandalf:/var/local/mailman/lists# l
total 16
drwxrwsr-x 4 root mailman 4096 Jan 1 20:03 ./
drwxrwsr-x 19 mailman mailman 4096 Jan 1 09:55 ../
drwxrwsr-x 3 root mailman 4096 Jan 1 19:46 m/
lrwxrwxrwx 1 root mailman 43 Jan 1 20:01 mailman-owner -> /var/local/mailman/lists/m/ma/mailman-owner/
drwxrwsr-x 3 root mailman 4096 Jan 1 12:18 t/
lrwxrwxrwx 1 root mailman 34 Jan 1 20:02 test -> /var/local/mailman/lists/t/te/test/
lrwxrwxrwx 1 root mailman 35 Jan 1 20:03 test2 -> /var/local/mailman/lists/t/te/test2/
root@gandalf:/var/local/mailman/archives/private# l
total 16
drwxrws--x 4 root mailman 4096 Jan 1 20:03 ./
drwxrwsr-x 4 root mailman 4096 Jan 1 09:55 ../
drwxrwsr-x 3 root mailman 4096 Jan 1 19:46 m/
lrwxrwxrwx 1 root mailman 54 Jan 1 20:01 mailman-owner -> /var/local/mailman/archives/private/m/ma/mailman-owner/
lrwxrwxrwx 1 root mailman 59 Jan 1 20:01 mailman-owner.mbox -> /var/local/mailman/archives/private/m/ma/mailman-owner.mbox/
drwxrwsr-x 3 root mailman 4096 Jan 1 12:18 t/
lrwxrwxrwx 1 root mailman 45 Jan 1 20:02 test -> /var/local/mailman/archives/private/t/te/test/
lrwxrwxrwx 1 root mailman 46 Jan 1 20:03 test2 -> /var/local/mailman/archives/private/t/te/test2/
lrwxrwxrwx 1 root mailman 51 Jan 1 20:03 test2.mbox -> /var/local/mailman/archives/private/t/te/test2.mbox/
lrwxrwxrwx 1 root mailman 50 Jan 1 20:02 test.mbox -> /var/local/mailman/archives/private/t/te/test.mbox/
This gets around the 32K link / directory limit in many filesystems
(limiting mailman to 16K lists)
2) Creates the pipermail html dir at list creation time so that you don't
get an http error when you view the archive of a list that doesn't have
messages yet
3) rmlist now does what it advertises with -a (you couldn't erase archives
after erasing a list)
root@gandalf:/var/local/mailman/bin# ./rmlist test2
Not removing archives. Reinvoke with -a to remove them.
Removing list info
Removing list info
root@gandalf:/var/local/mailman/bin# ./rmlist -a test2
List test2 does not exist or was already deleted, trying to remove archives.
Removing private archives
Removing private archives
Removing private archives
Removing private archives
Removing public archives
test2 public archives not found as /var/local/mailman/archives/public/t/te/test2
Removing public archives
test2 public archives not found as /var/local/mailman/archives/public/t/te/test2.mbox
If everyone is cool with this, I'll write a tool to convert an existing
installation to the new (optional) directory layout (I need this for
lists.sourceforge.net)
diff -urN mailman/Mailman/Archiver/Archiver.py mailman.subdirs/Mailman/Archiver/Archiver.py
--- mailman/Mailman/Archiver/Archiver.py Fri Oct 26 23:57:47 2001
+++ mailman.subdirs/Mailman/Archiver/Archiver.py Tue Jan 1 11:07:56 2002
@@ -76,6 +76,10 @@
# listname.mbox
# listname/
# lots-of-pipermail-stuff
+ # (note that if mm_cfg.SPLIT_DIRS is set, we create subdirectories and
+ # use symlinks (this gets around a 32k directories limit in some
+ # filesystems linked to a 32k hardlink limit per inode -- Marc))
+ #
# public/
# listname.mbox@ -> ../private/listname.mbox
# listname@ -> ../private/listname
@@ -89,7 +93,25 @@
omask = os.umask(0)
try:
try:
- os.mkdir(self.archive_dir()+'.mbox', 02775)
+ listname=self.internal_name();
+ if mm_cfg.SPLIT_DIRS:
+ archprivdir=os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR,
+ listname[0], listname[0:2], listname + '.mbox')
+ os.makedirs(archprivdir, 02775)
+ os.symlink(archprivdir, self.archive_dir()+'.mbox')
+ else:
+ os.mkdir(self.archive_dir()+'.mbox', 02775)
+ # We also create an empty pipermail archive directory (pipermail
+ # would create it, but in the meantime lists with no archives
+ # return errors when you browse the non existant archive dir)
+ # Besides, pipermail won't know about mm_cfg.SPLIT_DIRS -- Marc
+ if mm_cfg.SPLIT_DIRS:
+ archprivdir=os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR,
+ listname[0], listname[0:2], listname)
+ os.makedirs(archprivdir, 02775)
+ os.symlink(archprivdir, self.archive_dir())
+ else:
+ os.mkdir(self.archive_dir(), 02775)
except OSError, e:
if e.errno <> errno.EEXIST: raise
finally:
diff -urN mailman/Mailman/Archiver/pipermail.py mailman.subdirs/Mailman/Archiver/pipermail.py
--- mailman/Mailman/Archiver/pipermail.py Fri Nov 30 09:07:32 2001
+++ mailman.subdirs/Mailman/Archiver/pipermail.py Tue Jan 1 11:28:15 2002
@@ -252,6 +252,9 @@
self.database = database
# If the directory doesn't exist, create it
+ # This code shouldn't get run anymore, we create the directory in
+ # Archiver.py. It should only get used by legacy lists created that
+ # are only receiving their first message in the HTML archive now -- Marc
try:
os.stat(self.basedir)
except os.error, errdata:
diff -urN mailman/Mailman/Defaults.py.in mailman.subdirs/Mailman/Defaults.py.in
--- mailman/Mailman/Defaults.py.in Tue Jan 1 08:29:01 2002
+++ mailman.subdirs/Mailman/Defaults.py.in Tue Jan 1 12:50:35 2002
@@ -62,6 +62,13 @@
HOME_PAGE = 'index.html'
MAILMAN_SITE_LIST = 'mailman'
+# Set to '1' to have mailman start creating lists in directories like
+# ~mailman/lists/l/li/listname/ (same thing for the archives) to get around
+# the 32K directory limitation in some filesystems.
+# Because this sets symlinks to the expected positions, it is fully forward
+# and backward compatible -- Marc
+SPLIT_DIRS = 0
+
#####
diff -urN mailman/Mailman/MailList.py mailman.subdirs/Mailman/MailList.py
--- mailman/Mailman/MailList.py Tue Jan 1 08:29:02 2002
+++ mailman.subdirs/Mailman/MailList.py Tue Jan 1 10:40:25 2002
@@ -388,7 +388,13 @@
Utils.ValidateEmail(admin)
omask = os.umask(0)
try:
- os.makedirs(os.path.join(mm_cfg.LIST_DATA_DIR, name), 02775)
+ listdir=os.path.join(mm_cfg.LIST_DATA_DIR, name)
+ if mm_cfg.SPLIT_DIRS:
+ splitdir=os.path.join(mm_cfg.LIST_DATA_DIR, name[0], name[0:2], name)
+ os.makedirs(splitdir, 02775)
+ os.symlink(splitdir, listdir)
+ else:
+ os.makedirs(listdir, 02775)
finally:
os.umask(omask)
self._full_path = os.path.join(mm_cfg.LIST_DATA_DIR, name)
diff -urN mailman/bin/rmlist mailman.subdirs/bin/rmlist
--- mailman/bin/rmlist Sat Sep 8 01:18:47 2001
+++ mailman.subdirs/bin/rmlist Tue Jan 1 12:35:35 2002
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! /usr/bin/python
#
# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
#
@@ -78,11 +78,6 @@
usage(1)
listname = args[0].lower().strip()
- if not Utils.list_exists(listname):
- usage(1, _('No such list: %(listname)s'))
-
- mlist = MailList.MailList(listname, lock=0)
-
removeArchives = 0
for opt, arg in opts:
if opt in ('-a', '--archives'):
@@ -90,28 +85,57 @@
elif opt in ('-h', '--help'):
usage(0)
+ if not Utils.list_exists(listname):
+ if not removeArchives:
+ usage(1, _('No such list (or list already deleted): %(listname)s'))
+ else:
+ print _('List %(listname)s does not exist or was already deleted, trying to remove archives.')
+
if not removeArchives:
print _('Not removing archives. Reinvoke with -a to remove them.')
- # Do the MTA-specific list deletion tasks
- if mm_cfg.MTA:
- modname = 'Mailman.MTA.' + mm_cfg.MTA
- __import__(modname)
- sys.modules[modname].remove(mlist)
- REMOVABLES = [('lists/%s', 'list info'),
- ]
+ listsplitsubdir = os.path.join(listname[0], listname[0:2], listname)
+ listmboxsplitsubdir = os.path.join(listname[0], listname[0:2], listname + ".mbox")
+ REMOVABLES = [ ]
+ if Utils.list_exists(listname):
+ mlist = MailList.MailList(listname, lock=0)
+
+ # Do the MTA-specific list deletion tasks
+ if mm_cfg.MTA:
+ modname = 'Mailman.MTA.' + mm_cfg.MTA
+ __import__(modname)
+ sys.modules[modname].remove(mlist)
+
+ REMOVABLES = [
+ (os.path.join('lists', listname), _('list info')),
+ (os.path.join('lists', listsplitsubdir), _('list info'))
+ ]
+
if removeArchives:
- REMOVABLES.extend(
- [('archives/private/%s', _('private archives')),
- ('archives/private/%s.mbox', _('private archives')),
- ('archives/public/%s', _('public archives')),
- ('archives/public/%s.mbox', _('public archives')),
- ])
+ REMOVABLES.extend ([
+ (os.path.join('archives', 'private', listname),
+ _('private archives')),
+ (os.path.join('archives', 'private', listsplitsubdir),
+ _('private archives')),
+ (os.path.join('archives', 'private', listname + '.mbox'),
+ _('private archives')),
+ (os.path.join('archives', 'private', listmboxsplitsubdir),
+ _('private archives')),
+
+ (os.path.join('archives', 'public', listname),
+ _('public archives')),
+ (os.path.join('archives', 'public', listsplitsubdir),
+ _('public archives')),
+ (os.path.join('archives', 'public', listname + '.mbox'),
+ _('public archives')),
+ (os.path.join('archives', 'public', listmboxsplitsubdir),
+ _('public archives'))
+ ])
for dirtmpl, msg in REMOVABLES:
- dir = os.path.join(mm_cfg.VAR_PREFIX, dirtmpl % listname)
+ dir = os.path.join(mm_cfg.VAR_PREFIX, dirtmpl)
remove_it(listname, dir, msg)
--
Microsoft is to operating systems & security ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/ | Finger marc_f@merlins.org for PGP key