Home | History | Annotate | Download | only in tendo
      1 # Copyright 2015 The Chromium OS 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 import collections
      6 import json
      7 
      8 from autotest_lib.client.common_lib import utils
      9 
     10 
     11 # Represents one instance of a protocol handler that the webserver can be
     12 # configured with.
     13 ProtocolHandler = collections.namedtuple('ProtocolHandler',
     14                                          ['name', 'port', 'use_tls'])
     15 
     16 def get_n_protocol_handlers(n, port_base, use_tls=False,
     17                             handler_name_prefix='test_protocol_handler_'):
     18     """Construct ProtocolHandler objects for a number of handlers.
     19 
     20     @param n: integer number of handlers.
     21     @param port_base: integer port number.  Each handler will be given a port
     22             from the port_base, port_base + 1, port_base + 2, etc.
     23     @param use_tls: True iff the handler should use encryption.
     24     @param handler_name_prefix: string prefix to be used in the names of
     25             the N handlers.
     26 
     27     """
     28     protocol_handlers = []
     29     for i in range(n):
     30         protocol_handlers.append(
     31                 ProtocolHandler(name='%s%d' % (handler_name_prefix, i),
     32                                 port=port_base + i,
     33                                 use_tls=use_tls))
     34     return protocol_handlers
     35 
     36 
     37 class WebserverConfig(object):
     38     """Helper object that knows how to configure webservd."""
     39 
     40     def __init__(self,
     41                  verbosity_level=3,
     42                  webserv_debug=None,
     43                  extra_protocol_handlers=None,
     44                  host=None):
     45         """Construct an instance.
     46 
     47         @param verbosity_level: integer verbosity level.
     48         @param webserv_debug: True iff the webserver should log in debug mode.
     49         @param extra_protocol_handlers: list of protocol handler objects
     50                 obtained from get_n_protocol_handlers.  These replace the
     51                 default handlers.
     52         @param host: Host object if we want to control webservd on a remote
     53                 host.
     54 
     55         """
     56         self._verbosity_level = verbosity_level
     57         self._webserv_debug = webserv_debug
     58         self._extra_protocol_handlers = extra_protocol_handlers
     59         self._run = utils.run if host is None else host.run
     60 
     61 
     62     def _write_out_config_file(self, path, protocol_handlers):
     63         """Write a config file at |path| for |protocol_handlers|.
     64 
     65         @param path: file system path to write config dict to.
     66         @param protocol_handlers: list of ProtocolHandler objects.
     67 
     68         """
     69         handler_configs  = []
     70         # Each handler gets a JSON dict.
     71         for handler in self._extra_protocol_handlers:
     72             handler_configs.append({'name': handler.name,
     73                                     'port': handler.port,
     74                                     'use_tls': handler.use_tls})
     75         config = {'protocol_handlers': handler_configs}
     76         # Write out the actual file and give webservd permissions.
     77         with open(path, 'w') as f:
     78             f.write(json.dumps(config, indent=True))
     79         self._run('chown webservd:webservd %s' % path)
     80 
     81 
     82     def restart_with_config(self):
     83         """Restart the webserver with this configuration."""
     84         self._run('stop webservd', ignore_status=True)
     85         config_path = None
     86         if self._extra_protocol_handlers:
     87             config_path = '/tmp/webservd.conf'
     88             self._write_out_config_file(config_path,
     89                                         self._extra_protocol_handlers)
     90         args = ['WEBSERVD_LOG_LEVEL=%d' % self._verbosity_level]
     91         if self._webserv_debug:
     92             args.append('WEBSERVD_DEBUG=true')
     93         if config_path:
     94             args.append('WEBSERVD_CONFIG_PATH=%s' % config_path)
     95         self._run('start webservd %s' % ' '.join(args))
     96 
     97 
     98     def close(self):
     99         """Restarts the webserver with the default configuration."""
    100         self._run('stop webservd', ignore_status=True)
    101         self._run('start webservd')
    102