summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2008-03-21 13:01:48 -0400
committerBarry Warsaw2008-03-21 13:01:48 -0400
commitcdd63be688b07e44414ec9d2b3c6a9843134cb77 (patch)
treecebc7c4bfab53823f04076cdb0b7a404f312c3cd
parent7b1832826ba0603bc156a42849909a18a55b0759 (diff)
downloadmailman-cdd63be688b07e44414ec9d2b3c6a9843134cb77.tar.gz
mailman-cdd63be688b07e44414ec9d2b3c6a9843134cb77.tar.zst
mailman-cdd63be688b07e44414ec9d2b3c6a9843134cb77.zip
Added a common option parsing class, and converted master to it.
Diffstat (limited to '')
-rw-r--r--mailman/bin/master.py68
-rw-r--r--mailman/options.py62
2 files changed, 96 insertions, 34 deletions
diff --git a/mailman/bin/master.py b/mailman/bin/master.py
index 4170ac4f4..6577a0079 100644
--- a/mailman/bin/master.py
+++ b/mailman/bin/master.py
@@ -15,6 +15,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
+"""Master sub-process watcher."""
+
from __future__ import with_statement
__metaclass__ = type
@@ -30,7 +32,6 @@ import errno
import signal
import socket
import logging
-import optparse
from datetime import timedelta
from locknix import lockfile
@@ -42,19 +43,19 @@ from mailman import loginit
from mailman.configuration import config
from mailman.i18n import _
from mailman.initialize import initialize
+from mailman.options import Options
DOT = '.'
LOCK_LIFETIME = Defaults.days(1) + Defaults.hours(6)
-parser = None
-
-def parseargs():
- parser = optparse.OptionParser(version=Version.MAILMAN_VERSION,
- usage=_("""\
-Master queue runner watcher.
+class MasterOptions(Options):
+ """Options for the master watcher."""
+
+ usage = _("""\
+Master sub-process watcher.
Start and watch the configured queue runners and ensure that they stay alive
and kicking. Each are fork and exec'd in turn, with the master waiting on
@@ -74,35 +75,36 @@ its own log files on receipt of a SIGHUP. The master also leaves its own
process id in the file `data/master-qrunner.pid` but you normally don't need
to use this pid directly.
-Usage: %prog [options]"""))
- parser.add_option('-n', '--no-restart',
- dest='restartable', default=True, action='store_false',
- help=_("""\
+Usage: %prog [options]""")
+
+ def add_options(self):
+ self.parser.add_option(
+ '-n', '--no-restart',
+ dest='restartable', default=True, action='store_false',
+ help=_("""\
Don't restart the qrunners when they exit because of an error or a SIGUSR1.
Use this only for debugging."""))
- parser.add_option('-f', '--force',
- default=False, action='store_true',
- help=_("""\
+ self.parser.add_option(
+ '-f', '--force',
+ default=False, action='store_true',
+ help=_("""\
If the master watcher finds an existing master lock, it will normally exit
with an error message. With this option,the master will perform an extra
level of checking. If a process matching the host/pid described in the lock
file is running, the master will still exit, requiring you to manually clean
up the lock. But if no matching process is found, the master will remove the
apparently stale lock and make another attempt to claim the master lock."""))
- parser.add_option('-r', '--runner',
- dest='runners', action='append', default=[],
- help=_("""\
+ self.parser.add_option(
+ '-r', '--runner',
+ dest='runners', action='append', default=[],
+ help=_("""\
Override the default set of queue runners that the master watch will invoke
instead of the default set. Multiple -r options may be given. The values for
-r are passed straight through to bin/qrunner."""))
- parser.add_option('-C', '--config',
- help=_('Alternative configuration file to use'))
- options, arguments = parser.parse_args()
- if len(arguments) > 0:
- parser.error(_('Too many arguments'))
- parser.options = options
- parser.arguments = arguments
- return parser
+
+ def sanity_check(self):
+ if len(self.arguments) > 0:
+ self.parser.error(_('Too many arguments'))
@@ -175,7 +177,7 @@ def acquire_lock_1(force):
return acquire_lock_1(force=False)
-def acquire_lock():
+def acquire_lock(force):
"""Acquire the master queue runner lock.
:return: The master queue runner lock or None if the lock couldn't be
@@ -183,7 +185,7 @@ def acquire_lock():
error.
"""
try:
- lock = acquire_lock_1(parser.options.force)
+ lock = acquire_lock_1(force)
return lock
except lockfile.TimeOutError:
status = master_state()
@@ -403,22 +405,20 @@ qrunner %s reached maximum restart limit of %d, not restarting.""",
def main():
"""Main process."""
- global log, parser
-
- parser = parseargs()
- initialize(parser.options.config)
+ options = MasterOptions()
+ initialize(options.options.config)
# Acquire the master lock, exiting if we can't acquire it. We'll let the
# caller handle any clean up or lock breaking. No with statement here
# because Lock's constructor doesn't support a timeout.
- lock = acquire_lock()
+ lock = acquire_lock(options.options.force)
try:
with open(config.PIDFILE, 'w') as fp:
print >> fp, os.getpid()
- loop = Loop(lock, parser.options.restartable, parser.options.config)
+ loop = Loop(lock, options.options.restartable, options.options.config)
loop.install_signal_handlers()
try:
- loop.start_qrunners(parser.options.runners)
+ loop.start_qrunners(options.options.runners)
loop.loop()
finally:
loop.cleanup()
diff --git a/mailman/options.py b/mailman/options.py
new file mode 100644
index 000000000..78cf617c4
--- /dev/null
+++ b/mailman/options.py
@@ -0,0 +1,62 @@
+# Copyright (C) 2008 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+"""Common argument parsing."""
+
+__metaclass__ = type
+__all__ = ['Options']
+
+
+from optparse import OptionParser
+
+from mailman.Version import MAILMAN_VERSION
+from mailman.configuration import config
+from mailman.i18n import _
+
+
+
+class Options:
+ """Common argument parser."""
+
+ # Subclasses should override.
+ usage = None
+
+ def __init__(self):
+ self.parser = OptionParser(version=MAILMAN_VERSION, usage=self.usage)
+ self.add_common_options()
+ self.add_options()
+ options, arguments = self.parser.parse_args()
+ self.options = options
+ self.arguments = arguments
+ # Also, for convenience, place the options in the configuration file
+ # because occasional global uses are necessary.
+ config.options = self
+ self.sanity_check()
+
+ def add_options(self):
+ """Allow the subclass to add its own specific arguments."""
+ pass
+
+ def sanity_check(self):
+ """Allow subclasses to do sanity checking of arguments."""
+ pass
+
+ def add_common_options(self):
+ """Add options common to all scripts."""
+ self.parser.add_option(
+ '-C', '--config',
+ help=_('Alternative configuration file to use'))