factory.py revision e48bcfb879c943df72a866e3db8b2df8e930b2c1
1635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanskifrom autotest_lib.client.common_lib import utils, error
2635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanskifrom autotest_lib.server import utils as server_utils
3ca7da37fd4346d8944ca2e94c5b629d00c0cd102jadmanskifrom autotest_lib.server.hosts import site_factory, abstract_ssh
4e48bcfb879c943df72a866e3db8b2df8e930b2c1mblighfrom autotest_lib.server.hosts import ssh_host, serial, netconsole
5e48bcfb879c943df72a866e3db8b2df8e930b2c1mblighfrom autotest_lib.server.hosts import logfile_monitor
6e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh
7e48bcfb879c943df72a866e3db8b2df8e930b2c1mblighDEFAULT_FOLLOW_PATH = '/var/log/kern.log'
8e48bcfb879c943df72a866e3db8b2df8e930b2c1mblighDEFAULT_PATTERNS_PATH = 'console_patterns'
9635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski
10635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski
11d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski# for tracking which hostnames have already had job_start called
12d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski_started_hostnames = set()
13d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski
14e48bcfb879c943df72a866e3db8b2df8e930b2c1mblighdef create_host(
15e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh    hostname, auto_monitor=True, follow_paths=None, pattern_paths=None, **args):
16635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski    # by default assume we're using SSH support
17635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski    classes = [ssh_host.SSHHost]
18635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski
1954f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski    if auto_monitor:
2054f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski        # use serial console support if it's available
2154f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski        conmux_args = {}
2254f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski        for key in ("conmux_server", "conmux_attach"):
2354f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski            if key in args:
2454f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                conmux_args[key] = args[key]
2554f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski        if serial.SerialHost.host_is_supported(hostname, **conmux_args):
2654f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski            classes.append(serial.SerialHost)
27635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski        else:
2854f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski            # no serial host available, try netconsole logging if available
2954f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski            def run_func(cmd):
30ca7da37fd4346d8944ca2e94c5b629d00c0cd102jadmanski                base_cmd = abstract_ssh.make_ssh_command(connect_timeout=3)
3154f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                full_cmd = '%s %s "%s"' % (base_cmd, hostname,
3254f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                                           server_utils.sh_escape(cmd))
3354f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                try:
3454f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                    utils.run(full_cmd)
3554f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                except error.CmdError:
3654f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                    pass
3754f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski
3854f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski            if netconsole.NetconsoleHost.host_is_supported(run_func):
3954f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                classes.append(netconsole.NetconsoleHost)
4054f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski            else:
4154f90af69daac8a781678f0ccd42d6728d5d81d1jadmanski                # nothing available, fall back to direct dmesg logging
42e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                if follow_paths is None:
43e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                    follow_paths = [DEFAULT_FOLLOW_PATH]
44e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                else:
45e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                    follow_paths = list(follow_paths) + [DEFAULT_FOLLOW_PATH]
46e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh
47e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                if pattern_paths is None:
48e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                    pattern_paths = [DEFAULT_PATTERNS_PATH]
49e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                else:
50e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                    pattern_paths = (
51e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                        list(pattern_paths) + [DEFAULT_PATTERNS_PATH])
52e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh
53e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                logfile_monitor_class = logfile_monitor.NewLogfileMonitorMixin(
54e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                    follow_paths, pattern_paths)
55e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh                classes.append(logfile_monitor_class)
56e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh
57e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh    elif follow_paths:
58e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh        logfile_monitor_class = logfile_monitor.NewLogfileMonitorMixin(
59e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh            follow_paths, pattern_paths)
60e48bcfb879c943df72a866e3db8b2df8e930b2c1mbligh        classes.append(logfile_monitor_class)
61635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski
62635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski    # do any site-specific processing of the classes list
63d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski    site_factory.postprocess_classes(classes, hostname,
64ea90226c42c24de00839d2c68a04909b233e9a4fjadmanski                                     auto_monitor=auto_monitor, **args)
65635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski
66635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski    # create a custom host class for this machine and return an instance of it
67635b06f6c016fd5e4e14e98c471e92b1f435ac46jadmanski    host_class = type("%s_host" % hostname, tuple(classes), {})
68d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski    host_instance = host_class(hostname, **args)
69d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski
70d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski    # call job_start if this is the first time this host is being used
71d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski    if hostname not in _started_hostnames:
72d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski        host_instance.job_start()
73d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski        _started_hostnames.add(hostname)
74d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski
75d60321a8b012aa6101bcb237341fab5bd2d25a04jadmanski    return host_instance
76