VAR_PREFIX should be runtime-configurable

Bug #925502 reported by Zenon Panoussis
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Mailman
Invalid
Wishlist
Mark Sapiro

Bug Description

While there are many good and even pressing reasons to put the list files someplace other than in /var/lib/mailman, VAR_PREFIX is a compile-time option that cannot be set in mm_cfg. As a result, you have to choose *either* the benefits of moving the list files out of /var/lib *or* the benefits of running a distro with automatic updates; you can't have both.

RFE: please make VAR_PREFIX configurable from mm_cfg.py.

See also https://bugzilla.redhat.com/show_bug.cgi?id=786822

Revision history for this message
Mark Sapiro (msapiro) wrote :

VAR_PREFIX is configurable in mm_cfg.py. The problem is that 22 other directories/files are defined directly or indirectly in Defaults.py following the definition of VAR_PREFIX. mm_cfg.py imports everything from Defaults and then allows you to override any of the imported values. Simply changing VAR_PREFIX in mm_cfg.py doesn't change the definitions of these other 22 variables already defined in Defaults.py.

If you redefine VAR_PREFIX in mm_cfg .py, you need to copy all the dependent definitions after that as follows:

VAR_PREFIX = 'new/value'

LIST_DATA_DIR = os.path.join(VAR_PREFIX, 'lists')
LOG_DIR = os.path.join(VAR_PREFIX, 'logs')
LOCK_DIR = os.path.join(VAR_PREFIX, 'locks')
DATA_DIR = os.path.join(VAR_PREFIX, 'data')
SPAM_DIR = os.path.join(VAR_PREFIX, 'spam')

PUBLIC_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 'archives', 'public')
PRIVATE_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 'archives', 'private')

QUEUE_DIR = os.path.join(VAR_PREFIX, 'qfiles')
INQUEUE_DIR = os.path.join(QUEUE_DIR, 'in')
OUTQUEUE_DIR = os.path.join(QUEUE_DIR, 'out')
CMDQUEUE_DIR = os.path.join(QUEUE_DIR, 'commands')
BOUNCEQUEUE_DIR = os.path.join(QUEUE_DIR, 'bounces')
NEWSQUEUE_DIR = os.path.join(QUEUE_DIR, 'news')
ARCHQUEUE_DIR = os.path.join(QUEUE_DIR, 'archive')
SHUNTQUEUE_DIR = os.path.join(QUEUE_DIR, 'shunt')
VIRGINQUEUE_DIR = os.path.join(QUEUE_DIR, 'virgin')
BADQUEUE_DIR = os.path.join(QUEUE_DIR, 'bad')
RETRYQUEUE_DIR = os.path.join(QUEUE_DIR, 'retry')
MAILDIR_DIR = os.path.join(QUEUE_DIR, 'maildir')

PIDFILE = os.path.join(DATA_DIR, 'master-qrunner.pid')
SITE_PW_FILE = os.path.join(DATA_DIR, 'adm.pw')
LISTCREATOR_PW_FILE = os.path.join(DATA_DIR, 'creator.pw')

Changed in mailman:
assignee: nobody → Mark Sapiro (msapiro)
importance: Undecided → Wishlist
status: New → Invalid
Revision history for this message
Zenon Panoussis (oracle-9) wrote :

Mark, thanks for this meticulous list in comment #1. It is a solution to the problem, albeit a cumbersome one.

Based on what you wrote, I am assuming that mailman first reads Defaults.py and then reads mm_cfg.py, so that the latter overrides the variables that happen to be set in both.

If that is so, then the elegant way to allow any variable in mm_cfg.py to override Defaults.py, would be to reverse the order in which the two files are read. In other words, first read mm_cfg.py and set all the variables in it. Then run through Defaults.py conditionally: if var is unset, then set, else skip. The end result would be that you can set VAR_PREFIX or any other variable with children in mm_cfg.py and still leave the children definitions in Defaults.py untouched as long as they just follow their parent.

Revision history for this message
Mark Sapiro (msapiro) wrote :

Various Mailman modules get the settings via the Python statement

from Mailman import mm_cfg

This causes Python to read mm_cfg.py and execute all the statements therein. The first executable statement in mm_cfg.py, at least as distributed, is

from Defaults import *

This causes Python to read Defaults.py and execute all the statements therein and then make every name from that module available in the current namespace. Thus, at this point, everything defined in Defaults.py is available with its default value. Python then continues to execute the remaining statements in mm_cfg.py which normally serve to redefine some of the defaults.

If the order were reversed, i.e. if the

from Defaults import *

statement were at the end of mm_cfg.py instead of the beginning, all the default definitions would override anything previously set in mm_cfg.py which obviously wouldn't work. Additionally, It would also cause any statements in mm_cfg.py which depend on definitions in Defaults.py such as the helper functions add_virtualhost() to fail.

To do what you suggest in the way you suggest would require implementing a special purpose Python parser within Mailman to read Defaults .py and set only those things which were unset. Also, the problem of the helper functions being undefined at mm_cfg.py time would still exist. This is not a viable approach.

If we were doing this from scratch, we could split Defaults.py into two pieces, one which set all the direct variables and one which set all those things defined in terms of things set in the first piece. Then mm_cfg.py could import all the definitions from the first part at the beginning and all those from the second part at the end, but this is not viable for two reasons.

It would break every installation with an existing mm_cfg.py, i.e. every existing installation.

It would make it impossible to override any of the things defined in the second part.

If you can come up with a patch to do what you want that would work in all cases and not break any existing mm_cfg.py files, I would consider it. In the mean time, you have the solution in comment #1.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.