run_apache2.py revision 4af7705631880a8f0b1d2c34df47be4b554b7a15
1#!/usr/bin/python
2#
3# Copyright (C) 2010 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""Start, stop, or restart apache2 server.
18
19  Apache2 must be installed with mod_php!
20
21  Usage:
22    run_apache2.py start|stop|restart
23"""
24
25import sys
26import os
27import subprocess
28import logging
29import optparse
30import time
31
32def main(options, args):
33  if len(args) < 1:
34    run_cmd = ""
35  else:
36    run_cmd = args[0]
37
38  # Setup logging class
39  logging.basicConfig(level=logging.INFO, format='%(message)s')
40
41  if not run_cmd in ("start", "stop", "restart"):
42    logging.info("illegal argument: " + run_cmd)
43    logging.info("Usage: python run_apache2.py start|stop|restart")
44    return
45
46  # Create /tmp/WebKit if it doesn't exist. This is needed for various files used by apache2
47  tmp_WebKit = os.path.join("/tmp", "WebKit")
48  if not os.path.exists(tmp_WebKit):
49    os.mkdir(tmp_WebKit)
50
51  # Get the path to android tree root based on the script location.
52  # Basically we go 5 levels up
53  parent = os.pardir
54  script_location = os.path.abspath(os.path.dirname(sys.argv[0]))
55  android_tree_root = os.path.join(script_location, parent, parent, parent, parent, parent)
56  android_tree_root = os.path.normpath(android_tree_root)
57
58  # If any of these is relative, then it's relative to ServerRoot (in our case android_tree_root)
59  webkit_path = os.path.join("external", "webkit")
60  if (options.tests_root_directory != None):
61    # if options.tests_root_directory is absolute, os.getcwd() is discarded!
62    layout_tests_path = os.path.normpath(os.path.join(os.getcwd(), options.tests_root_directory))
63  else:
64    layout_tests_path = os.path.join(webkit_path, "LayoutTests")
65  http_conf_path = os.path.join(layout_tests_path, "http", "conf")
66
67  # Prepare the command to set ${APACHE_RUN_USER} and ${APACHE_RUN_GROUP}
68  envvars_path = os.path.join("/etc", "apache2", "envvars")
69  export_envvars_cmd = "source " + envvars_path
70
71  error_log_path = os.path.join(tmp_WebKit, "apache2-error.log")
72  custom_log_path = os.path.join(tmp_WebKit, "apache2-access.log")
73
74  # Prepare the command to (re)start/stop the server with specified settings
75  apache2_restart_template = "apache2 -k %s"
76  directives  = " -c \"ServerRoot " + android_tree_root + "\""
77
78  # We use http/tests as the document root as the HTTP tests use hardcoded
79  # resources at the server root. We then use aliases to make available the
80  # complete set of tests and the required scripts.
81  directives += " -c \"DocumentRoot " + os.path.join(layout_tests_path, "http", "tests/") + "\""
82  directives += " -c \"Alias /LayoutTests " + layout_tests_path + "\""
83  directives += " -c \"Alias /WebKitTools/DumpRenderTree/android " + \
84    os.path.join(webkit_path, "WebKitTools", "DumpRenderTree", "android") + "\""
85  directives += " -c \"Alias /ThirdPartyProject.prop " + \
86    os.path.join(webkit_path, "ThirdPartyProject.prop") + "\""
87
88  # This directive is commented out in apache2-debian-httpd.conf for some reason
89  # However, it is useful to browse through tests in the browser, so it's added here.
90  # One thing to note is that because of problems with mod_dir and port numbers, mod_dir
91  # is turned off. That means that there _must_ be a trailing slash at the end of URL
92  # for auto indexes to work correctly.
93  directives += " -c \"LoadModule autoindex_module /usr/lib/apache2/modules/mod_autoindex.so\""
94
95  directives += " -c \"ErrorLog " + error_log_path +"\""
96  directives += " -c \"CustomLog " + custom_log_path + " combined\""
97  directives += " -c \"SSLCertificateFile " + os.path.join(http_conf_path, "webkit-httpd.pem") + \
98    "\""
99  directives += " -c \"User ${APACHE_RUN_USER}\""
100  directives += " -c \"Group ${APACHE_RUN_GROUP}\""
101  directives += " -C \"TypesConfig " + \
102    os.path.join(android_tree_root, http_conf_path, "mime.types") + "\""
103  conf_file_cmd = " -f " + \
104    os.path.join(android_tree_root, http_conf_path, "apache2-debian-httpd.conf")
105
106  # Try to execute the commands
107  logging.info("Will " + run_cmd + " apache2 server.")
108  cmd_template = export_envvars_cmd + " && " + apache2_restart_template + directives + conf_file_cmd
109
110  # It is worth noting here that if the configuration file with which we restart the server points
111  # to a different PidFile it will not work and result in second apache2 instance.
112  if (run_cmd == 'restart'):
113    logging.info("First will stop...")
114    execute_cmd(cmd_template % ('stop'))
115    logging.info("Stopped. Will start now...")
116    # We need to sleep breifly to avoid errors with apache being stopped and started too quickly
117    time.sleep(0.5)
118
119  execute_cmd(cmd_template % (run_cmd))
120
121def execute_cmd(cmd):
122  p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
123  (out, err) = p.communicate()
124
125  # Output the stdout from the command to console
126  logging.info(out)
127
128  # Report any errors
129  if p.returncode != 0:
130    logging.info("!! ERRORS:")
131
132    if err.find(envvars_path) != -1:
133      logging.info(err)
134    elif err.find('command not found') != -1:
135      logging.info("apache2 is probably not installed")
136    else:
137      logging.info(err)
138      logging.info("Try looking in " + error_log_path + " for details")
139  else:
140    logging.info("OK")
141
142if __name__ == "__main__":
143  option_parser = optparse.OptionParser(usage="Usage: %prog [options] start|stop|restart")
144  option_parser.add_option("", "--tests-root-directory",
145                           help="The directory from which to take the tests, default is external/webkit/LayoutTests in this checkout of the Android tree")
146  options, args = option_parser.parse_args();
147  main(options, args);
148