~launchpad-pqm/launchpad/devel

4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
1
#! /usr/bin/python2.4
2
#
3
# Copyright 2007 Canonical Ltd.  All rights reserved.
4
5
import os
6
import grp
7
import pwd
8
import sys
9
import errno
7064.1.4 by Barry Warsaw
Response to Francis's review.
10
import socket
4897.4.6 by Barry Warsaw
The first step toward a comprehensive Launchpad/Mailman integration test.
11
import tempfile
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
12
import subprocess
13
4002.5.26 by Barry Warsaw
Branch fixes based on salgado's review.
14
from canonical.config import config
5863.9.1 by Curtis Hovey
Updated configs and code to used simple datatypes. Changes may still be needed aftert testing.
15
from canonical.launchpad.mailman.config import (
7064.1.4 by Barry Warsaw
Response to Francis's review.
16
    configure_prefix, configure_siteowner)
4002.5.31 by Barry Warsaw
Updates to the mmbuild branch based on feedback from SteveA and spiv over
17
from canonical.launchpad.mailman.monkeypatches import monkey_patch
7465.5.1 by Gary Poster
integrate lazr.config and lazr.delegates
18
from lazr.config import as_username_groupname
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
19
from configs import generate_overrides
20
5863.9.1 by Curtis Hovey
Updated configs and code to used simple datatypes. Changes may still be needed aftert testing.
21
basepath = [part for part in sys.path if part]
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
22
23
24
def build_mailman():
25
    # Build and install Mailman if it is enabled and not yet built.
5863.9.7 by Curtis Hovey
Refacortings per review.
26
    if not config.mailman.build:
5863.9.1 by Curtis Hovey
Updated configs and code to used simple datatypes. Changes may still be needed aftert testing.
27
        # There's nothing to do.
5415.1.1 by Barry Warsaw
If there is no <mailman> or <mailman-build> section, there's nothing to build, so return immediately.
28
        return 0
5863.9.7 by Curtis Hovey
Refacortings per review.
29
    mailman_path = configure_prefix(config.mailman.build_prefix)
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
30
    mailman_bin = os.path.join(mailman_path, 'bin')
5863.9.1 by Curtis Hovey
Updated configs and code to used simple datatypes. Changes may still be needed aftert testing.
31
    var_dir = os.path.abspath(config.mailman.build_var_dir)
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
32
33
    # If we can import the package, we assume Mailman is properly built and
34
    # installed.  This does not catch re-installs that might be necessary
35
    # should our copy in sourcecode be updated.  Do that manually.
36
    sys.path.append(mailman_path)
37
    try:
38
        import Mailman
39
    except ImportError:
40
        pass
41
    else:
42
        return 0
43
44
    # Make sure the target directories exist and have the correct
45
    # permissions, otherwise configure will complain.
7064.1.4 by Barry Warsaw
Response to Francis's review.
46
    user, group = as_username_groupname(config.mailman.build_user_group)
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
47
    # Now work backwards to get the uid and gid
5373.2.8 by Barry Warsaw
Solve a few other problems related to staging's Mailman configs.
48
    try:
49
        uid = pwd.getpwnam(user).pw_uid
50
    except KeyError:
51
        print >> sys.stderr, 'No user found:', user
52
        sys.exit(1)
53
    try:
54
        gid = grp.getgrnam(group).gr_gid
55
    except KeyError:
56
        print >> sys.stderr, 'No group found:', group
57
        sys.exit(1)
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
58
59
    # Ensure that the var_dir exists, is owned by the user:group, and has
60
    # the necessary permissions.  Set the mode separately after the
61
    # makedirs() call because some platforms ignore mkdir()'s mode (though
62
    # I think Linux does not ignore it -- better safe than sorry).
63
    try:
64
        os.makedirs(var_dir)
65
    except OSError, e:
4002.5.26 by Barry Warsaw
Branch fixes based on salgado's review.
66
        if e.errno != errno.EEXIST:
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
67
            raise
68
    os.chown(var_dir, uid, gid)
69
    os.chmod(var_dir, 02775)
70
71
    mailman_source = os.path.join('sourcecode', 'mailman')
7064.1.4 by Barry Warsaw
Response to Francis's review.
72
    if config.mailman.build_host_name:
73
        build_host_name = config.mailman.build_host_name
74
    else:
75
        build_host_name = socket.getfqdn()
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
76
5427.2.1 by Barry Warsaw
Correct a bald-faced lie. Mailman's buildout for Launchpad /does/ need to set
77
    # Build and install the Mailman software.  Note that we don't care about
78
    # --with-cgi-gid because we're not going to use that Mailman subsystem.
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
79
    configure_args = (
80
        './configure',
81
        '--prefix', mailman_path,
82
        '--with-var-prefix=' + var_dir,
83
        '--with-python=' + sys.executable,
84
        '--with-username=' + user,
85
        '--with-groupname=' + group,
5427.2.1 by Barry Warsaw
Correct a bald-faced lie. Mailman's buildout for Launchpad /does/ need to set
86
        '--with-mail-gid=' + group,
5863.9.1 by Curtis Hovey
Updated configs and code to used simple datatypes. Changes may still be needed aftert testing.
87
        '--with-mailhost=' + build_host_name,
88
        '--with-urlhost=' + build_host_name,
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
89
        )
90
    retcode = subprocess.call(configure_args, cwd=mailman_source)
91
    if retcode:
92
        print >> sys.stderr, 'Could not configure Mailman:'
93
        sys.exit(retcode)
94
    retcode = subprocess.call(('make',), cwd=mailman_source)
95
    if retcode:
96
        print >> sys.stderr, 'Could not make Mailman.'
97
        sys.exit(retcode)
98
    retcode = subprocess.call(('make', 'install'), cwd=mailman_source)
99
    if retcode:
100
        print >> sys.stderr, 'Could not install Mailman.'
101
        sys.exit(retcode)
102
    # Try again to import the package.
103
    try:
7064.1.4 by Barry Warsaw
Response to Francis's review.
104
        # pylint: disable-msg=W0404
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
105
        import Mailman
106
    except ImportError:
107
        print >> sys.stderr, 'Could not import the Mailman package'
108
        return 1
4002.5.31 by Barry Warsaw
Updates to the mmbuild branch based on feedback from SteveA and spiv over
109
110
    # Check to see if the site list exists.  The output can go to /dev/null
111
    # because we don't really care about it.  The site list exists if
112
    # config_list returns a zero exit status, otherwise it doesn't
113
    # (probably).  Before we can do this however, we must monkey patch
114
    # Mailman, otherwise mm_cfg.py won't be set up correctly.
115
    monkey_patch(mailman_path, config)
116
117
    import Mailman.mm_cfg
118
    retcode = subprocess.call(
119
        ('./config_list', '-o', '/dev/null',
120
         Mailman.mm_cfg.MAILMAN_SITE_LIST),
121
        cwd=mailman_bin,
122
        stdout=subprocess.PIPE, stderr=subprocess.PIPE)
123
124
    if retcode:
5863.9.7 by Curtis Hovey
Refacortings per review.
125
        addr, password = configure_siteowner(
126
            config.mailman.build_site_list_owner)
4002.5.31 by Barry Warsaw
Updates to the mmbuild branch based on feedback from SteveA and spiv over
127
128
        # The site list does not yet exist, so create it now.
129
        retcode = subprocess.call(
130
            ('./newlist', '--quiet',
5863.9.1 by Curtis Hovey
Updated configs and code to used simple datatypes. Changes may still be needed aftert testing.
131
             '--emailhost=' + build_host_name,
4002.5.31 by Barry Warsaw
Updates to the mmbuild branch based on feedback from SteveA and spiv over
132
             Mailman.mm_cfg.MAILMAN_SITE_LIST,
133
             addr, password),
134
            cwd=mailman_bin)
135
        if retcode:
136
            print >> sys.stderr, 'Could not create site list'
4483.4.25 by Barry Warsaw
Last round of changes in response to bac's comments (who took over in BjornT's
137
            return retcode
4002.5.31 by Barry Warsaw
Updates to the mmbuild branch based on feedback from SteveA and spiv over
138
5046.3.2 by Barry Warsaw
Some modifications in response to Francis's comments.
139
    retcode = configure_site_list(
140
        mailman_bin, Mailman.mm_cfg.MAILMAN_SITE_LIST)
141
    if retcode:
142
        print >> sys.stderr, 'Could not configure site list'
143
        return retcode
144
145
    # Create a directory to hold the gzip'd tarballs for the directories of
146
    # deactivated lists.
147
    try:
148
        os.mkdir(os.path.join(Mailman.mm_cfg.VAR_PREFIX, 'backups'))
149
    except OSError, e:
150
        if e.errno != errno.EEXIST:
151
            raise
152
153
    return 0
154
155
156
def configure_site_list(mailman_bin, site_list_name):
157
    """Configure the site list.
158
159
    Currently, the only thing we want to set is to not advertise the site list.
160
    """
4897.4.6 by Barry Warsaw
The first step toward a comprehensive Launchpad/Mailman integration test.
161
    fd, config_file_name = tempfile.mkstemp()
162
    try:
163
        os.close(fd)
164
        config_file = open(config_file_name, 'w')
165
        try:
166
            print >> config_file, 'advertised = False'
167
        finally:
168
            config_file.close()
5046.3.2 by Barry Warsaw
Some modifications in response to Francis's comments.
169
        return subprocess.call(
170
            ('./config_list', '-i', config_file_name, site_list_name),
171
            cwd=mailman_bin)
4897.4.6 by Barry Warsaw
The first step toward a comprehensive Launchpad/Mailman integration test.
172
    finally:
173
        os.remove(config_file_name)
174
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
175
176
def main():
177
    # Sort ZCML overrides for our current config
178
    generate_overrides()
179
180
    # setting python paths
181
    program = sys.argv[0]
182
183
    src = 'lib'
184
    here = os.path.dirname(os.path.abspath(program))
185
    srcdir = os.path.join(here, src)
186
    sys.path = [srcdir, here] + basepath
187
    return build_mailman()
4002.5.31 by Barry Warsaw
Updates to the mmbuild branch based on feedback from SteveA and spiv over
188
4002.5.14 by Barry Warsaw
Changes to address jamesh's review comments.
189
190
191
if __name__ == '__main__':
192
    return_code = main()
193
    sys.exit(return_code)