~launchpad-pqm/launchpad/devel

8687.15.18 by Karl Fogel
Add the copyright header block to files under lib/canonical/.
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4897.4.4 by Barry Warsaw
Refactor starting and stopping Mailman so that both the 'make run' target and
3
4
"""Start and stop the Mailman processes."""
5
6
__metaclass__ = type
4897.4.23 by Barry Warsaw
final cleanups
7
__all__ = [
8
    'start_mailman',
9
    'stop_mailman',
10
    ]
4897.4.4 by Barry Warsaw
Refactor starting and stopping Mailman so that both the 'make run' target and
11
12
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
13
import errno
4897.4.4 by Barry Warsaw
Refactor starting and stopping Mailman so that both the 'make run' target and
14
import os
6732.9.5 by barry at canonical
Fix all the non-email sending tests.
15
import signal
4897.4.4 by Barry Warsaw
Refactor starting and stopping Mailman so that both the 'make run' target and
16
import subprocess
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
17
import sys
4897.4.4 by Barry Warsaw
Refactor starting and stopping Mailman so that both the 'make run' target and
18
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
19
import canonical
11568.1.1 by Curtis Hovey
Move mailman to lp.services. Fixed staging.txt and logging.txt that were broken by
20
from lp.services.mailman.config import configure_prefix
21
from lp.services.mailman.monkeypatches import monkey_patch
4897.4.4 by Barry Warsaw
Refactor starting and stopping Mailman so that both the 'make run' target and
22
23
6793.4.2 by Barry Warsaw
Try to debug and fix the infloop crasher. Now, _get_subscriptions() will only
24
def mailmanctl(command, quiet=False, config=None, *additional_arguments):
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
25
    """Run mailmanctl command.
26
27
    :param command: the command to use.
28
    :param quiet: when this is true, no output will happen unless, an error
29
        happens.
14605.1.3 by Curtis Hovey
Renamed CanonicalConfig to LaunchpadConfig because that is what it is doing.
30
    :param config: The LaunchpadConfig object to take configuration from.
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
31
        Defaults to the global one.
6793.4.2 by Barry Warsaw
Try to debug and fix the infloop crasher. Now, _get_subscriptions() will only
32
    :param additional_arguments: additional command arguments to pass to the
33
        mailmanctl program.
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
34
    :raises RuntimeError: when quiet is True and the command failed.
35
    """
36
    if config is None:
14605.1.1 by Curtis Hovey
Moved canonical.config to lp.services.
37
        config = lp.services.config.config
5863.9.7 by Curtis Hovey
Refacortings per review.
38
    mailman_path = configure_prefix(config.mailman.build_prefix)
11568.1.1 by Curtis Hovey
Move mailman to lp.services. Fixed staging.txt and logging.txt that were broken by
39
    mailman_bin = os.path.join(mailman_path, 'bin')
6793.4.2 by Barry Warsaw
Try to debug and fix the infloop crasher. Now, _get_subscriptions() will only
40
    args = ['./mailmanctl']
41
    args.extend(additional_arguments)
42
    args.append(command)
5723.8.7 by Barry Warsaw
Add support for testing the mlist-sync.py script, and also merge the changes
43
    if quiet:
6732.9.5 by barry at canonical
Fix all the non-email sending tests.
44
        stdout = subprocess.PIPE
45
        stderr = subprocess.STDOUT
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
46
    else:
6732.9.5 by barry at canonical
Fix all the non-email sending tests.
47
        stdout = None
48
        stderr = None
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
49
    env = dict(os.environ)
50
    env['LPCONFIG'] = config.instance_name
6732.9.5 by barry at canonical
Fix all the non-email sending tests.
51
    process = subprocess.Popen(
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
52
        args, cwd=mailman_bin, stdout=stdout, stderr=stderr, env=env)
6732.9.5 by barry at canonical
Fix all the non-email sending tests.
53
    code = process.wait()
4897.4.4 by Barry Warsaw
Refactor starting and stopping Mailman so that both the 'make run' target and
54
    if code:
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
55
        if quiet:
56
            raise RuntimeError(
57
                'mailmanctl %s failed: %d\n%s' % (
7064.1.3 by Barry Warsaw
Port the rest of the tests to AppServerProcessController.
58
                    command, code, process.stdout.read()))
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
59
        else:
6732.9.5 by barry at canonical
Fix all the non-email sending tests.
60
            print >> sys.stderr, 'mailmanctl %s failed: %d' % (command, code)
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
61
62
63
def stop_mailman(quiet=False, config=None):
64
    """Alias for mailmanctl('stop')."""
6793.4.2 by Barry Warsaw
Try to debug and fix the infloop crasher. Now, _get_subscriptions() will only
65
    mailmanctl('stop', quiet, config)
6732.9.5 by barry at canonical
Fix all the non-email sending tests.
66
    # Further, if the Mailman master pid file was not removed, then the
67
    # master watcher, and probably one of its queue runners, did not die.
68
    # Kill it hard and clean up after it.
69
    if config is None:
14605.1.1 by Curtis Hovey
Moved canonical.config to lp.services.
70
        config = lp.services.config.config
6732.9.5 by barry at canonical
Fix all the non-email sending tests.
71
    mailman_path = configure_prefix(config.mailman.build_prefix)
72
    master_pid_path = os.path.join(mailman_path, 'data', 'master-qrunner.pid')
73
    try:
74
        master_pid_file = open(master_pid_path)
75
    except IOError, error:
76
        if error.errno == errno.ENOENT:
77
            # It doesn't exist, so we're all done.
78
            return
79
        raise
80
    try:
81
        master_pid = int(master_pid_file.read().strip())
82
    finally:
83
        master_pid_file.close()
84
    try:
85
        # Kill the entire process group.
86
        os.kill(master_pid, -signal.SIGKILL)
87
    except OSError, error:
88
        if error.errno == errno.ESRCH:
89
            # The process does not exist.  It could be a zombie that has yet
90
            # to be waited on, but let's not worry about that.
91
            return
92
        raise
93
    try:
94
        os.remove(master_pid_path)
95
    except OSError, error:
96
        if error.errno != errno.ENOENT:
97
            raise
98
    lock_dir = os.path.join(mailman_path, 'locks')
99
    for filename in os.listdir(lock_dir):
100
        os.remove(os.path.join(lock_dir, filename))
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
101
102
103
def start_mailman(quiet=False, config=None):
5046.4.1 by Barry Warsaw
Merge old mlist-subs-3 branch
104
    """Start the Mailman master qrunner.
105
106
    The client of start_mailman() is responsible for ensuring that
107
    stop_mailman() is called at the appropriate time.
108
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
109
    :param quiet: when this is true, no output will happen unless, an error
110
        happens.
14605.1.3 by Curtis Hovey
Renamed CanonicalConfig to LaunchpadConfig because that is what it is doing.
111
    :param config: The LaunchpadConfig object to take configuration from.
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
112
        Defaults to the global one.
113
    :raises RuntimeException: when Mailman fails to start successfully.
5046.4.1 by Barry Warsaw
Merge old mlist-subs-3 branch
114
    """
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
115
    if config is None:
14605.1.1 by Curtis Hovey
Moved canonical.config to lp.services.
116
        config = lp.services.config.config
5046.4.1 by Barry Warsaw
Merge old mlist-subs-3 branch
117
    # We need the Mailman bin directory so we can run some of Mailman's
118
    # command line scripts.
5863.9.7 by Curtis Hovey
Refacortings per review.
119
    mailman_path = configure_prefix(config.mailman.build_prefix)
11568.1.1 by Curtis Hovey
Move mailman to lp.services. Fixed staging.txt and logging.txt that were broken by
120
    mailman_bin = os.path.join(mailman_path, 'bin')
6697.4.2 by Francis J. Lacoste
Created a mailmanctl wrapper that takes an arbitrary config object and is silent.
121
4897.4.4 by Barry Warsaw
Refactor starting and stopping Mailman so that both the 'make run' target and
122
    # Monkey-patch the installed Mailman 2.1 tree.
123
    monkey_patch(mailman_path, config)
6793.4.2 by Barry Warsaw
Try to debug and fix the infloop crasher. Now, _get_subscriptions() will only
124
    # Start Mailman.  Pass in the -s flag so that any stale master pid files
125
    # will get deleted.  "Stale" means the process that owned the pid no
126
    # longer exists, so this can't hurt anything.
127
    mailmanctl('start', quiet, config, '-s')