~loggerhead-team/loggerhead/trunk-rich

167 by Michael Hudson
make serve-branches.py executable
1
#!/usr/bin/env python
183.2.1 by John Arbash Meinel
Add Copyright information to most files.
2
# This program is free software; you can redistribute it and/or modify
3
# it under the terms of the GNU General Public License as published by
4
# the Free Software Foundation; either version 2 of the License, or
5
# (at your option) any later version.
6
#
7
# This program is distributed in the hope that it will be useful,
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
# GNU General Public License for more details.
11
#
12
# You should have received a copy of the GNU General Public License
13
# along with this program; if not, write to the Free Software
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
16
"""Search for branches underneath a directory and serve them all."""
17
174 by Michael Hudson
misc logging improvements:
18
import logging
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
19
import os
165.1.4 by Michael Hudson
change serve-branches.py to be easier to document :)
20
import sys
21
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
22
from optparse import OptionParser
23
270.1.1 by Michael Hudson
defer loading of plugins until after we've set up the logging
24
from bzrlib.plugin import load_plugins
25
165.1.4 by Michael Hudson
change serve-branches.py to be easier to document :)
26
from paste import httpserver
264 by Michael Hudson
error if you run serve-branches behind proxy when paste.deploy is not available
27
from paste.httpexceptions import HTTPExceptionHandler, HTTPInternalServerError
165.1.4 by Michael Hudson
change serve-branches.py to be easier to document :)
28
from paste.translogger import TransLogger
29
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
30
from loggerhead import __version__
31
from loggerhead.apps.filesystem import (
32
    BranchesFromFileSystemRoot, UserBranchesFromFileSystemRoot)
219.1.2 by Guillermo Gonzalez
* update NEWS and serve-branches man page
33
from loggerhead.util import Reloader
217.1.4 by Guillermo Gonzalez
* new apps module: "error" and ErrorHandlerApp middleware
34
from loggerhead.apps.error import ErrorHandlerApp
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
35
36
37
def command_line_parser():
38
    parser = OptionParser("%prog [options] <path>")
39
    parser.set_defaults(
40
        user_dirs=False,
41
        show_version=False,
217.1.4 by Guillermo Gonzalez
* new apps module: "error" and ErrorHandlerApp middleware
42
        log_folder=None,
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
43
        )
44
    parser.add_option("--user-dirs", action="store_true", dest="user_dirs",
45
                      help="Serve user directories as ~user.")
46
    parser.add_option("--trunk-dir", metavar="DIR",
47
                      help="The directory that contains the trunk branches.")
215.1.1 by Martin Albisetti
* Allow specifying a custom port
48
    parser.add_option("--port", dest="user_port",
230.1.1 by Steve 'Ashcrow' Milner
Updated to follow pep8.
49
                      help=("Port Loggerhead should listen on "
50
                            "(defaults to 8080)."))
215.1.1 by Martin Albisetti
* Allow specifying a custom port
51
    parser.add_option("--host", dest="user_host",
52
                      help="Host Loggerhead should listen on.")
314.1.1 by Paul Hummer
Added MemoryProfiling middleware
53
    parser.add_option('--memory-profile', action='store_true',
54
                      dest='memory_profile',
55
                      help='Profile the memory usage using heapy.')
215.1.2 by Martin Albisetti
Add --prefix option for hosts
56
    parser.add_option("--prefix", dest="user_prefix",
57
                      help="Specify host prefix.")
232.1.1 by Paul Hummer
Added profile flag for profiling loggerhead
58
    parser.add_option("--profile", action="store_true", dest="profile",
232.1.7 by Robert Collins
Allow lsprofile data on requests to be gathered.
59
                      help="Generate callgrind profile data to "
60
                        "%d-stats.callgrind on each request.")
219.1.1 by Guillermo Gonzalez
* added --reload option
61
    parser.add_option("--reload", action="store_true", dest="reload",
219.1.2 by Guillermo Gonzalez
* update NEWS and serve-branches man page
62
                      help="Restarts the application when changing python"
63
                           " files. Only used for development purposes.")
217.2.1 by Michael Hudson
whitespace, style, typos
64
    parser.add_option('--log-folder', dest="log_folder",
65
                      type=str, help="The directory to place log files in.")
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
66
    parser.add_option("--version", action="store_true", dest="show_version",
67
                      help="Print the software version and exit")
68
    return parser
69
70
71
def main(args):
72
    parser = command_line_parser()
73
    (options, args) = parser.parse_args(sys.argv[1:])
74
75
    if options.show_version:
76
        print "loggerhead %s" % __version__
77
        sys.exit(0)
78
79
    if len(args) > 1:
80
        parser.print_help()
81
        sys.exit(1)
82
    elif len(args) == 1:
83
        [path] = args
84
    else:
85
        path = '.'
86
87
    if not os.path.isdir(path):
88
        print "%s is not a directory" % path
89
        sys.exit(1)
90
91
    if options.trunk_dir and not options.user_dirs:
92
        print "--trunk-dir is only valid with --user-dirs"
93
        sys.exit(1)
217.2.1 by Michael Hudson
whitespace, style, typos
94
219.1.1 by Guillermo Gonzalez
* added --reload option
95
    if options.reload:
219.1.2 by Guillermo Gonzalez
* update NEWS and serve-branches man page
96
        if Reloader.is_installed():
97
            Reloader.install()
219.1.1 by Guillermo Gonzalez
* added --reload option
98
        else:
219.1.2 by Guillermo Gonzalez
* update NEWS and serve-branches man page
99
            return Reloader.restart_with_reloader()
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
100
101
    if options.user_dirs:
102
        if not options.trunk_dir:
103
            print "You didn't specify a directory for the trunk directories."
104
            sys.exit(1)
105
        app = UserBranchesFromFileSystemRoot(path, options.trunk_dir)
106
    else:
107
        app = BranchesFromFileSystemRoot(path)
217.2.1 by Michael Hudson
whitespace, style, typos
108
217.1.4 by Guillermo Gonzalez
* new apps module: "error" and ErrorHandlerApp middleware
109
    # setup_logging()
110
    logging.basicConfig()
111
    logging.getLogger('').setLevel(logging.DEBUG)
112
    logger = getattr(app, 'log', logging.getLogger('loggerhead'))
113
    if options.log_folder:
114
        logfile_path = os.path.join(options.log_folder, 'serve-branches.log')
115
    else:
116
        logfile_path = 'serve-branches.log'
117
    logfile = logging.FileHandler(logfile_path, 'a')
118
    formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(name)s:'
119
                                  ' %(message)s')
120
    logfile.setFormatter(formatter)
121
    logfile.setLevel(logging.DEBUG)
122
    logger.addHandler(logfile)
314.1.7 by Paul Hummer
Fixed logging for memory profiling
123
124
    memprofile = logging.getLogger('loggerhead-memprofile')
125
    memprofile.setLevel(logging.DEBUG)
126
    memprofile.addHandler(logging.FileHandler('loggerhead-memprofile'))
127
217.1.4 by Guillermo Gonzalez
* new apps module: "error" and ErrorHandlerApp middleware
128
    # setup_logging() #end
314.1.9 by Paul Hummer
Whitespace fix
129
217.1.4 by Guillermo Gonzalez
* new apps module: "error" and ErrorHandlerApp middleware
130
    app = TransLogger(app, logger=logger)
232.1.1 by Paul Hummer
Added profile flag for profiling loggerhead
131
    if options.profile:
232.1.7 by Robert Collins
Allow lsprofile data on requests to be gathered.
132
        from loggerhead.middleware.profile import LSProfMiddleware
133
        app = LSProfMiddleware(app)
314.1.6 by Paul Hummer
Added update method for memory profiling middleware.
134
    if options.memory_profile:
135
        from loggerhead.middleware.profile import MemoryProfileMiddleware
136
        app = MemoryProfileMiddleware(app)
217.1.4 by Guillermo Gonzalez
* new apps module: "error" and ErrorHandlerApp middleware
137
215.1.2 by Martin Albisetti
Add --prefix option for hosts
138
    if not options.user_prefix:
139
        prefix = '/'
140
    else:
141
        prefix = options.user_prefix
277 by Michael Hudson
* make example Apache stanza more correct with how PasteDeploy works
142
        if not prefix.startswith('/'):
143
            prefix = '/' + prefix
215.1.2 by Martin Albisetti
Add --prefix option for hosts
144
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
145
    try:
146
        from paste.deploy.config import PrefixMiddleware
147
    except ImportError:
264 by Michael Hudson
error if you run serve-branches behind proxy when paste.deploy is not available
148
        cant_proxy_correctly_message = (
149
            'Unsupported configuration: PasteDeploy not available, but '
150
            'loggerhead appears to be behind a proxy.')
151
        def check_not_proxied(app):
152
            def wrapped(environ, start_response):
153
                if 'HTTP_X_FORWARDED_SERVER' in environ:
154
                    exc = HTTPInternalServerError()
155
                    exc.explanation = cant_proxy_correctly_message
156
                    raise exc
157
                return app(environ, start_response)
158
            return wrapped
159
        app = check_not_proxied(app)
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
160
    else:
215.1.2 by Martin Albisetti
Add --prefix option for hosts
161
        app = PrefixMiddleware(app, prefix=prefix)
217.2.1 by Michael Hudson
whitespace, style, typos
162
266.2.13 by Michael Hudson
raise a 404 when passed an invalid revid
163
    app = HTTPExceptionHandler(app)
264 by Michael Hudson
error if you run serve-branches behind proxy when paste.deploy is not available
164
    app = ErrorHandlerApp(app)
165
215.1.1 by Martin Albisetti
* Allow specifying a custom port
166
    if not options.user_port:
167
        port = '8080'
168
    else:
169
        port = options.user_port
170
171
    if not options.user_host:
172
        host = '0.0.0.0'
173
    else:
174
        host = options.user_host
175
270.1.1 by Michael Hudson
defer loading of plugins until after we've set up the logging
176
    load_plugins()
177
215.1.1 by Martin Albisetti
* Allow specifying a custom port
178
    httpserver.serve(app, host=host, port=port)
189.1.2 by Tim Penhey
Extend serve-branches to serve user dirs.
179
180
181
if __name__ == "__main__":
182
    main(sys.argv)