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 5import collections 6import json 7 8from 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. 13ProtocolHandler = collections.namedtuple('ProtocolHandler', 14 ['name', 'port', 'use_tls']) 15 16def 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 37class 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