Home | History | Annotate | Download | only in google
      1 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """Platform-specific utility methods shared by several scripts."""
      6 
      7 import os
      8 import subprocess
      9 
     10 import google.path_utils
     11 
     12 
     13 class PlatformUtility(object):
     14   def __init__(self, base_dir):
     15     """Args:
     16          base_dir: the base dir for running tests.
     17     """
     18     self._base_dir = base_dir
     19     self._httpd_cmd_string = None  # used for starting/stopping httpd
     20     self._bash = "/bin/bash"
     21 
     22   def _UnixRoot(self):
     23     """Returns the path to root."""
     24     return "/"
     25 
     26   def GetFilesystemRoot(self):
     27     """Returns the root directory of the file system."""
     28     return self._UnixRoot()
     29 
     30   def GetTempDirectory(self):
     31     """Returns the file system temp directory
     32 
     33     Note that this does not use a random subdirectory, so it's not
     34     intrinsically secure.  If you need a secure subdir, use the tempfile
     35     package.
     36     """
     37     return os.getenv("TMPDIR", "/tmp")
     38 
     39   def FilenameToUri(self, path, use_http=False, use_ssl=False, port=8000):
     40     """Convert a filesystem path to a URI.
     41 
     42     Args:
     43       path: For an http URI, the path relative to the httpd server's
     44           DocumentRoot; for a file URI, the full path to the file.
     45       use_http: if True, returns a URI of the form http://127.0.0.1:8000/.
     46           If False, returns a file:/// URI.
     47       use_ssl: if True, returns HTTPS URL (https://127.0.0.1:8000/).
     48           This parameter is ignored if use_http=False.
     49       port: The port number to append when returning an HTTP URI
     50     """
     51     if use_http:
     52       protocol = 'http'
     53       if use_ssl:
     54         protocol = 'https'
     55       return "%s://127.0.0.1:%d/%s" % (protocol, port, path)
     56     return "file://" + path
     57 
     58   def GetStartHttpdCommand(self, output_dir,
     59                            httpd_conf_path, mime_types_path,
     60                            document_root=None, apache2=False):
     61     """Prepares the config file and output directory to start an httpd server.
     62     Returns a list of strings containing the server's command line+args.
     63 
     64     Args:
     65       output_dir: the path to the server's output directory, for log files.
     66           It will be created if necessary.
     67       httpd_conf_path: full path to the httpd.conf file to be used.
     68       mime_types_path: full path to the mime.types file to be used.
     69       document_root: full path to the DocumentRoot.  If None, the DocumentRoot
     70           from the httpd.conf file will be used.  Note that the httpd.conf
     71           file alongside this script does not specify any DocumentRoot, so if
     72           you're using that one, be sure to specify a document_root here.
     73       apache2: boolean if true will cause this function to return start
     74                command for Apache 2.x as opposed to Apache 1.3.x. This flag
     75                is ignored on Linux (but preserved here for compatibility in
     76                function signature with win), where apache2 is used always
     77     """
     78 
     79     exe_name = "apache2"
     80     cert_file = google.path_utils.FindUpward(self._base_dir, 'tools',
     81                                              'python', 'google',
     82                                              'httpd_config', 'httpd2.pem')
     83     ssl_enabled = os.path.exists('/etc/apache2/mods-enabled/ssl.conf')
     84 
     85     httpd_vars = {
     86       "httpd_executable_path":
     87           os.path.join(self._UnixRoot(), "usr", "sbin", exe_name),
     88       "httpd_conf_path": httpd_conf_path,
     89       "ssl_certificate_file": cert_file,
     90       "document_root" : document_root,
     91       "server_root": os.path.join(self._UnixRoot(), "usr"),
     92       "mime_types_path": mime_types_path,
     93       "output_dir": output_dir,
     94       "ssl_mutex": "file:"+os.path.join(output_dir, "ssl_mutex"),
     95       "ssl_session_cache":
     96           "shmcb:" + os.path.join(output_dir, "ssl_scache") + "(512000)",
     97       "user": os.environ.get("USER", "#%d" % os.geteuid()),
     98       "lock_file": os.path.join(output_dir, "accept.lock"),
     99     }
    100 
    101     google.path_utils.MaybeMakeDirectory(output_dir)
    102 
    103     # We have to wrap the command in bash
    104     # -C: process directive before reading config files
    105     # -c: process directive after reading config files
    106     # Apache wouldn't run CGIs with permissions==700 unless we add
    107     # -c User "<username>"
    108     httpd_cmd_string = (
    109       '%(httpd_executable_path)s'
    110       ' -f %(httpd_conf_path)s'
    111       ' -c \'TypesConfig "%(mime_types_path)s"\''
    112       ' -c \'CustomLog "%(output_dir)s/access_log.txt" common\''
    113       ' -c \'ErrorLog "%(output_dir)s/error_log.txt"\''
    114       ' -c \'PidFile "%(output_dir)s/httpd.pid"\''
    115       ' -C \'User "%(user)s"\''
    116       ' -C \'ServerRoot "%(server_root)s"\''
    117       ' -c \'LockFile "%(lock_file)s"\''
    118     )
    119 
    120     if document_root:
    121       httpd_cmd_string += ' -C \'DocumentRoot "%(document_root)s"\''
    122 
    123     if ssl_enabled:
    124       httpd_cmd_string += (
    125         ' -c \'SSLCertificateFile "%(ssl_certificate_file)s"\''
    126         ' -c \'SSLMutex "%(ssl_mutex)s"\''
    127         ' -c \'SSLSessionCache "%(ssl_session_cache)s"\''
    128       )
    129 
    130     # Save a copy of httpd_cmd_string to use for stopping httpd
    131     self._httpd_cmd_string = httpd_cmd_string % httpd_vars
    132 
    133     httpd_cmd = [self._bash, "-c", self._httpd_cmd_string]
    134     return httpd_cmd
    135 
    136   def GetStopHttpdCommand(self):
    137     """Returns a list of strings that contains the command line+args needed to
    138     stop the http server used in the http tests.
    139 
    140     This tries to fetch the pid of httpd (if available) and returns the
    141     command to kill it. If pid is not available, kill all httpd processes
    142     """
    143 
    144     if not self._httpd_cmd_string:
    145       return ["true"]   # Haven't been asked for the start cmd yet. Just pass.
    146     # Add a sleep after the shutdown because sometimes it takes some time for
    147     # the port to be available again.
    148     return [self._bash, "-c", self._httpd_cmd_string + ' -k stop && sleep 5']
    149