• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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