[Mailman-Developers] Mailman 2.0.5 patch

Barry A. Warsaw barry@digicool.com
Fri, 4 May 2001 16:25:52 -0400


>>>>> "MM" == Marc MERLIN <marc_news@valinux.com> writes:

    MM> The uprade procedure was a bit painful, because once again,
    MM> update touched all my lists as root, recreated all the
    MM> config.db files as root, which broke all the lists on my
    MM> system (admittedly, that's my fault for having restricted
    MM> hardlinks)

    | This, in the update process, is what is screwing me over:
    | - updating old public mbox file
    |     looks like you have a really recent CVS installation...
    |     you're either one brave soul, or you already ran me

Close, but not quite.  There's a step in bin/update, function
dolist(), which sets some list attributes unconditionally.  Of course,
to do this, it must lock the list, change the attrs and save the
list.

There's a similar step in main() where the old gate_watermarks file is
transformed into the usenet_watermark attribute, but that step isn't
done if the gate_watermarks file isn't found (which it won't be for
any 2.0.x upgrade).

The problem is that while the dolist() step happens unconditionally,
it only needs to be done if it updates the archive_directory or
private_archive_file_dir attributes.  Below is a patch to skip this
step if those attrs don't need to be upgraded.

    MM> Would you accept a patch that made update change its uid to
    MM> mailman (requiring make install to be ran as root or mailman)
    MM> for everyone?

I'm not so sure.  Say I install Mailman as user `barry', I don't want
to be running the upgrade as user `mailman'.

Probably a better approach is to refuse to run update if the effective
uid doesn't equal mm_cfg.MAILMAN_UID.  On the other hand, the attached
patch might be enough.  On the third hand, maybe bin/update should
just be culled of all ability to upgrade from a pre-2.0 revision?  In
that case, I'll bet bin/update can just go away.

-Barry

-------------------- snip snip --------------------
Index: update
===================================================================
RCS file: /cvsroot/mailman/mailman/bin/update,v
retrieving revision 1.24.2.1
diff -u -r1.24.2.1 update
--- update	2001/03/02 23:19:33	1.24.2.1
+++ update	2001/05/04 20:25:01
@@ -80,28 +80,25 @@
 def dolist(listname):
     errors = 0
     mlist = MailList.MailList(listname, lock=0)
-    try:
-        mlist.Lock(0.5)
-    except TimeOutError:
-        print 'WARNING: could not acquire lock for list:', listname
-        return 1
-
-    mbox_dir = make_varabs('archives/private/%s.mbox' % (listname))
-    mbox_file = make_varabs('archives/private/%s.mbox/%s' % (listname,
-                                                             listname))
+
+    mbox_dir = make_varabs('archives/private/%s.mbox' % listname)
+    mbox_file = make_varabs('archives/private/%s.mbox/%s' %
+                            (listname, listname))
 
-    o_pub_mbox_file = make_varabs('archives/public/%s' % (listname))
-    o_pri_mbox_file = make_varabs('archives/private/%s' % (listname))
+    o_pub_mbox_file = make_varabs('archives/public/%s' % listname)
+    o_pri_mbox_file = make_varabs('archives/private/%s' % listname)
 
     html_dir = o_pri_mbox_file
-    o_html_dir = makeabs('public_html/archives/%s' % (listname))
+    o_html_dir = makeabs('public_html/archives/%s' % listname)
     #
     # make the mbox directory if it's not there.
     #
     if not os.path.exists(mbox_dir):
         ou = os.umask(0)
-        os.mkdir(mbox_dir, 02775)
-        os.umask(ou)
+        try:
+            os.mkdir(mbox_dir, 02775)
+        finally:
+            os.umask(ou)
     else:
         # this shouldn't happen, but hey, just in case
         if not os.path.isdir(mbox_dir):
@@ -197,10 +194,17 @@
     # save the new variables and
     # let it create public symlinks if necessary
     #
-    mlist.archive_directory = make_varabs('archives/private/%s' % (listname))
-    mlist.private_archive_file_dir = make_varabs('archives/private/%s.mbox' %
-                                                 listname)
-    mlist.Save()
+    archivedir = make_varabs('archives/private/%s' % listname)
+    if mlist.archive_directory <> archivedir or \
+           mlist.private_archive_file_dir <> mbox_dir:
+        print "    I have to update the list's archive directory attributes"
+        mlist.Lock()
+        try:
+            mlist.archive_directory = archivedir
+            mlist.private_archive_file_dir = mbox_dir
+            mlist.Save()
+        finally:
+            mlist.Unlock()
     #
     # check to see if pre-b4 list-specific templates are around
     # and move them to the new place if there's not already
@@ -222,8 +226,6 @@
             else:
                 print "- both %s and %s exist, leaving untouched" \
                       % (o_tmpl, n_tmpl)
-    # Avoid eating filehandles with the list lockfiles
-    mlist.Unlock()
     return 0
 
 
@@ -296,18 +298,14 @@
             if listname not in listnames:
                 # this list no longer exists
                 continue
-            mlist = MailList.MailList(listname, lock=0)
+            mlist = MailList.MailList(listname)
             try:
-                mlist.Lock(0.5)
-            except TimeOutError:
-                print 'WARNING: could not acquire lock for list:', listname
-                errors = errors + 1
-            else:
                 # Pre 1.0b7 stored 0 in the gate_watermarks file to indicate
                 # that no gating had been done yet.  Without coercing this to
                 # None, the list could now suddenly get flooded.
                 mlist.usenet_watermark = d[listname] or None
                 mlist.Save()
+            finally:
                 mlist.Unlock()
         os.unlink(wmfile)
         print '- usenet watermarks updated and gate_watermarks removed'