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 25 import sys 26 import os 27 import subprocess 28 import logging 29 import optparse 30 import time 31 32 def main(run_cmd, options): 33 # Setup logging class 34 logging.basicConfig(level=logging.INFO, format='%(message)s') 35 36 if not run_cmd in ("start", "stop", "restart"): 37 logging.info("illegal argument: " + run_cmd) 38 logging.info("Usage: python run_apache2.py start|stop|restart") 39 return False 40 41 # Create /tmp/WebKit if it doesn't exist. This is needed for various files used by apache2 42 tmp_WebKit = os.path.join("/tmp", "WebKit") 43 if not os.path.exists(tmp_WebKit): 44 os.mkdir(tmp_WebKit) 45 46 # Get the path to android tree root based on the script location. 47 # Basically we go 5 levels up 48 parent = os.pardir 49 script_location = os.path.abspath(os.path.dirname(sys.argv[0])) 50 android_tree_root = os.path.join(script_location, parent, parent, parent, parent, parent) 51 android_tree_root = os.path.normpath(android_tree_root) 52 53 # If any of these is relative, then it's relative to ServerRoot (in our case android_tree_root) 54 webkit_path = os.path.join("external", "webkit") 55 if (options.tests_root_directory != None): 56 # if options.tests_root_directory is absolute, os.getcwd() is discarded! 57 layout_tests_path = os.path.normpath(os.path.join(os.getcwd(), options.tests_root_directory)) 58 else: 59 layout_tests_path = os.path.join(webkit_path, "LayoutTests") 60 http_conf_path = os.path.join(layout_tests_path, "http", "conf") 61 62 # Prepare the command to set ${APACHE_RUN_USER} and ${APACHE_RUN_GROUP} 63 envvars_path = os.path.join("/etc", "apache2", "envvars") 64 export_envvars_cmd = "source " + envvars_path 65 66 error_log_path = os.path.join(tmp_WebKit, "apache2-error.log") 67 custom_log_path = os.path.join(tmp_WebKit, "apache2-access.log") 68 69 # Prepare the command to (re)start/stop the server with specified settings 70 apache2_restart_template = "apache2 -k %s" 71 directives = " -c \"ServerRoot " + android_tree_root + "\"" 72 73 # The default config in apache2-debian-httpd.conf listens on ports 8080 and 74 # 8443. We also need to listen on port 8000 for HTTP tests. 75 directives += " -c \"Listen 8000\"" 76 77 # We use http/tests as the document root as the HTTP tests use hardcoded 78 # resources at the server root. We then use aliases to make available the 79 # complete set of tests and the required scripts. 80 directives += " -c \"DocumentRoot " + os.path.join(layout_tests_path, "http", "tests/") + "\"" 81 directives += " -c \"Alias /LayoutTests " + layout_tests_path + "\"" 82 directives += " -c \"Alias /Tools/DumpRenderTree/android " + \ 83 os.path.join(webkit_path, "Tools", "DumpRenderTree", "android") + "\"" 84 directives += " -c \"Alias /ThirdPartyProject.prop " + \ 85 os.path.join(webkit_path, "ThirdPartyProject.prop") + "\"" 86 87 # This directive is commented out in apache2-debian-httpd.conf for some reason 88 # However, it is useful to browse through tests in the browser, so it's added here. 89 # One thing to note is that because of problems with mod_dir and port numbers, mod_dir 90 # is turned off. That means that there _must_ be a trailing slash at the end of URL 91 # for auto indexes to work correctly. 92 directives += " -c \"LoadModule autoindex_module /usr/lib/apache2/modules/mod_autoindex.so\"" 93 94 directives += " -c \"ErrorLog " + error_log_path +"\"" 95 directives += " -c \"CustomLog " + custom_log_path + " combined\"" 96 directives += " -c \"SSLCertificateFile " + os.path.join(http_conf_path, "webkit-httpd.pem") + \ 97 "\"" 98 directives += " -c \"User ${APACHE_RUN_USER}\"" 99 directives += " -c \"Group ${APACHE_RUN_GROUP}\"" 100 directives += " -C \"TypesConfig " + \ 101 os.path.join(android_tree_root, http_conf_path, "mime.types") + "\"" 102 conf_file_cmd = " -f " + \ 103 os.path.join(android_tree_root, http_conf_path, "apache2-debian-httpd.conf") 104 105 # Try to execute the commands 106 logging.info("Will " + run_cmd + " apache2 server.") 107 108 # It is worth noting here that if the configuration file with which we restart the server points 109 # to a different PidFile it will not work and will result in a second apache2 instance. 110 if (run_cmd == 'restart'): 111 logging.info("First will stop...") 112 if execute_cmd(envvars_path, error_log_path, 113 export_envvars_cmd + " && " + (apache2_restart_template % ('stop')) + directives + conf_file_cmd) == False: 114 logging.info("Failed to stop Apache2") 115 return False 116 logging.info("Stopped. Will start now...") 117 # We need to sleep breifly to avoid errors with apache being stopped and started too quickly 118 time.sleep(0.5) 119 120 if execute_cmd(envvars_path, error_log_path, 121 export_envvars_cmd + " && " + 122 (apache2_restart_template % (run_cmd)) + directives + 123 conf_file_cmd) == False: 124 logging.info("Failed to start Apache2") 125 return False 126 127 logging.info("Successfully started") 128 return True 129 130 def execute_cmd(envvars_path, error_log_path, cmd): 131 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 132 (out, err) = p.communicate() 133 134 # Output the stdout from the command to console 135 logging.info(out) 136 137 # Report any errors 138 if p.returncode != 0: 139 logging.info("!! ERRORS:") 140 141 if err.find(envvars_path) != -1: 142 logging.info(err) 143 elif err.find('command not found') != -1: 144 logging.info("apache2 is probably not installed") 145 else: 146 logging.info(err) 147 logging.info("Try looking in " + error_log_path + " for details") 148 return False 149 150 return True 151 152 if __name__ == "__main__": 153 option_parser = optparse.OptionParser(usage="Usage: %prog [options] start|stop|restart") 154 option_parser.add_option("", "--tests-root-directory", 155 help="The directory from which to take the tests, default is external/webkit/LayoutTests in this checkout of the Android tree") 156 options, args = option_parser.parse_args(); 157 158 if len(args) < 1: 159 run_cmd = "" 160 else: 161 run_cmd = args[0] 162 163 main(run_cmd, options) 164