Home | History | Annotate | Download | only in assets
      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