run_apache2.py revision 183c3c9ca20f55703f31e3610bca72682f6355db
174b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski#!/usr/bin/python
2073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski#
3073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# Copyright (C) 2010 The Android Open Source Project
4073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski#
5073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# Licensed under the Apache License, Version 2.0 (the "License");
6073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# you may not use this file except in compliance with the License.
7073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# You may obtain a copy of the License at
8073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski#
9073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski#      http://www.apache.org/licenses/LICENSE-2.0
10073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski#
11073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# Unless required by applicable law or agreed to in writing, software
12073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# distributed under the License is distributed on an "AS IS" BASIS,
13073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# See the License for the specific language governing permissions and
15073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski# limitations under the License.
16073d2c9aa96f6265bacb5c6abc609ca265f60488Maksymilian Osowski#
1774b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski"""Start, stop, or restart apache2 server.
1874b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
1974b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  Apache2 must be installed with mod_php!
2074b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
2174b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  Usage:
220e4d86fddf2c9664f2fd44247e5688f077b95d5eSteve Block    run_apache2.py start|stop|restart
2374b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski"""
2474b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
2574b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowskiimport sys
2674b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowskiimport os
2774b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowskiimport subprocess
2874b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowskiimport logging
2978fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowskiimport optparse
304af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowskiimport time
3174b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
32ae47ce00460538d7db688a269d8cbae5a2054b18Steve Blockdef main(run_cmd, options):
33ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Setup logging class
3474b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  logging.basicConfig(level=logging.INFO, format='%(message)s')
3574b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
3674b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  if not run_cmd in ("start", "stop", "restart"):
3774b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski    logging.info("illegal argument: " + run_cmd)
380e4d86fddf2c9664f2fd44247e5688f077b95d5eSteve Block    logging.info("Usage: python run_apache2.py start|stop|restart")
39ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block    return False
4074b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
41ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Create /tmp/WebKit if it doesn't exist. This is needed for various files used by apache2
4274b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  tmp_WebKit = os.path.join("/tmp", "WebKit")
4374b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  if not os.path.exists(tmp_WebKit):
4474b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski    os.mkdir(tmp_WebKit)
4574b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
46ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Get the path to android tree root based on the script location.
47ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Basically we go 5 levels up
4874b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  parent = os.pardir
4974b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  script_location = os.path.abspath(os.path.dirname(sys.argv[0]))
5074b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  android_tree_root = os.path.join(script_location, parent, parent, parent, parent, parent)
5174b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  android_tree_root = os.path.normpath(android_tree_root)
5274b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
5378fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski  # If any of these is relative, then it's relative to ServerRoot (in our case android_tree_root)
54ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  webkit_path = os.path.join("external", "webkit")
5578fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski  if (options.tests_root_directory != None):
5678fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski    # if options.tests_root_directory is absolute, os.getcwd() is discarded!
5778fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski    layout_tests_path = os.path.normpath(os.path.join(os.getcwd(), options.tests_root_directory))
5878fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski  else:
5978fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski    layout_tests_path = os.path.join(webkit_path, "LayoutTests")
609d660cb5f3202366ad8540d66018b33b3f8578dfSteve Block  http_conf_path = os.path.join(layout_tests_path, "http", "conf")
61ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block
62ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Prepare the command to set ${APACHE_RUN_USER} and ${APACHE_RUN_GROUP}
6374b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  envvars_path = os.path.join("/etc", "apache2", "envvars")
6474b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  export_envvars_cmd = "source " + envvars_path
6574b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
6674b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  error_log_path = os.path.join(tmp_WebKit, "apache2-error.log")
67fe33f987cb61d8a5c22f207df6d47d2346828af7Maksymilian Osowski  custom_log_path = os.path.join(tmp_WebKit, "apache2-access.log")
6874b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
69ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Prepare the command to (re)start/stop the server with specified settings
704af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski  apache2_restart_template = "apache2 -k %s"
7174b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  directives  = " -c \"ServerRoot " + android_tree_root + "\""
729d660cb5f3202366ad8540d66018b33b3f8578dfSteve Block
7376c97ee414dfc752ce26201a440bf7c451acae85Steve Block  # The default config in apache2-debian-httpd.conf listens on ports 8080 and
7476c97ee414dfc752ce26201a440bf7c451acae85Steve Block  # 8443. We also need to listen on port 8000 for HTTP tests.
7576c97ee414dfc752ce26201a440bf7c451acae85Steve Block  directives += " -c \"Listen 8000\""
7676c97ee414dfc752ce26201a440bf7c451acae85Steve Block
779d660cb5f3202366ad8540d66018b33b3f8578dfSteve Block  # We use http/tests as the document root as the HTTP tests use hardcoded
789d660cb5f3202366ad8540d66018b33b3f8578dfSteve Block  # resources at the server root. We then use aliases to make available the
799d660cb5f3202366ad8540d66018b33b3f8578dfSteve Block  # complete set of tests and the required scripts.
809d660cb5f3202366ad8540d66018b33b3f8578dfSteve Block  directives += " -c \"DocumentRoot " + os.path.join(layout_tests_path, "http", "tests/") + "\""
819d660cb5f3202366ad8540d66018b33b3f8578dfSteve Block  directives += " -c \"Alias /LayoutTests " + layout_tests_path + "\""
82183c3c9ca20f55703f31e3610bca72682f6355dbSteve Block  directives += " -c \"Alias /Tools/DumpRenderTree/android " + \
83183c3c9ca20f55703f31e3610bca72682f6355dbSteve Block    os.path.join(webkit_path, "Tools", "DumpRenderTree", "android") + "\""
840e2bae14b408d001fea84c0cbdb7348c3ec611a3Steve Block  directives += " -c \"Alias /ThirdPartyProject.prop " + \
850e2bae14b408d001fea84c0cbdb7348c3ec611a3Steve Block    os.path.join(webkit_path, "ThirdPartyProject.prop") + "\""
8674b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
87ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # This directive is commented out in apache2-debian-httpd.conf for some reason
88ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # However, it is useful to browse through tests in the browser, so it's added here.
89ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # One thing to note is that because of problems with mod_dir and port numbers, mod_dir
90ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # is turned off. That means that there _must_ be a trailing slash at the end of URL
91ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # for auto indexes to work correctly.
9274b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  directives += " -c \"LoadModule autoindex_module /usr/lib/apache2/modules/mod_autoindex.so\""
9374b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
9474b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  directives += " -c \"ErrorLog " + error_log_path +"\""
95fe33f987cb61d8a5c22f207df6d47d2346828af7Maksymilian Osowski  directives += " -c \"CustomLog " + custom_log_path + " combined\""
96ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  directives += " -c \"SSLCertificateFile " + os.path.join(http_conf_path, "webkit-httpd.pem") + \
97ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block    "\""
9874b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  directives += " -c \"User ${APACHE_RUN_USER}\""
9974b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  directives += " -c \"Group ${APACHE_RUN_GROUP}\""
1005846d4561d45c2805b3cba33995bfa08b55b980eMaksymilian Osowski  directives += " -C \"TypesConfig " + \
1015846d4561d45c2805b3cba33995bfa08b55b980eMaksymilian Osowski    os.path.join(android_tree_root, http_conf_path, "mime.types") + "\""
102ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  conf_file_cmd = " -f " + \
103ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block    os.path.join(android_tree_root, http_conf_path, "apache2-debian-httpd.conf")
10474b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
105ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Try to execute the commands
10674b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  logging.info("Will " + run_cmd + " apache2 server.")
1074af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski
1084af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski  # It is worth noting here that if the configuration file with which we restart the server points
1090e1d6876f93332eb430d31d48f627ad812abb29dSteve Block  # to a different PidFile it will not work and will result in a second apache2 instance.
1104af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski  if (run_cmd == 'restart'):
1114af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski    logging.info("First will stop...")
112ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block    if execute_cmd(envvars_path, error_log_path,
113ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block                   export_envvars_cmd + " && " + (apache2_restart_template % ('stop')) + directives + conf_file_cmd) == False:
114ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block      logging.info("Failed to stop Apache2")
115ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block      return False
1164af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski    logging.info("Stopped. Will start now...")
1174af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski    # We need to sleep breifly to avoid errors with apache being stopped and started too quickly
1184af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski    time.sleep(0.5)
1194af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski
120ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block  if execute_cmd(envvars_path, error_log_path,
121ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block                 export_envvars_cmd + " && " +
122ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block                 (apache2_restart_template % (run_cmd)) + directives +
123ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block                 conf_file_cmd) == False:
124ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block    logging.info("Failed to start Apache2")
125ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block    return False
126ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block
127ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block  logging.info("Successfully started")
128ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block  return True
1294af7705631880a8f0b1d2c34df47be4b554b7a15Maksymilian Osowski
130ae47ce00460538d7db688a269d8cbae5a2054b18Steve Blockdef execute_cmd(envvars_path, error_log_path, cmd):
13174b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
13274b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  (out, err) = p.communicate()
13374b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
134ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Output the stdout from the command to console
13574b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  logging.info(out)
13674b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
137ee273fac7f223eafb7619168ec656dd4947b1e5eSteve Block  # Report any errors
13874b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski  if p.returncode != 0:
13974b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski    logging.info("!! ERRORS:")
14074b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
14174b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski    if err.find(envvars_path) != -1:
14274b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski      logging.info(err)
14374b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski    elif err.find('command not found') != -1:
14474b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski      logging.info("apache2 is probably not installed")
14574b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski    else:
14674b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski      logging.info(err)
14774b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski      logging.info("Try looking in " + error_log_path + " for details")
148ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block    return False
149ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block
150ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block  return True
15174b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowski
15274b13aecbe4116ce33da8ed99f1b5941ecda6505Maksymilian Osowskiif __name__ == "__main__":
15378fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski  option_parser = optparse.OptionParser(usage="Usage: %prog [options] start|stop|restart")
15478fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski  option_parser.add_option("", "--tests-root-directory",
15578fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski                           help="The directory from which to take the tests, default is external/webkit/LayoutTests in this checkout of the Android tree")
15678fbc54c182cfc6b21fe745213b02b7ea18775e7Maksymilian Osowski  options, args = option_parser.parse_args();
157ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block
158ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block  if len(args) < 1:
159ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block    run_cmd = ""
160ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block  else:
161ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block    run_cmd = args[0]
162ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block
163ae47ce00460538d7db688a269d8cbae5a2054b18Steve Block  main(run_cmd, options)
164