blob: 13c1a35aac817ca6a8166eee4b35e2c40ab8a56d [file] [log] [blame]
Aviv Keshet53bd44e2013-01-31 13:08:41 -08001#!/usr/bin/python
2
3# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6"""A small wrapper script, iterates through
7the known hosts and tries to call get_labels()
8to discover host functionality, and adds these
9detected labels to host.
10
11Limitations:
12 - Does not keep a count of how many labels were
13 actually added.
14 - If a label is added by this script because it
15 is detected as supported by get_labels, but later becomes
16 unsupported, this script has no way to know that it
17 should be removed, so it will remain attached to the host.
18 See crosbug.com/38569
19"""
20
21
Alex Miller6f84a792014-02-06 16:07:56 -080022from multiprocessing import pool
Aviv Keshet53bd44e2013-01-31 13:08:41 -080023import logging
24import socket
25import argparse
26import sys
27
28import common
29
J. Richard Barnetteecdbd192013-10-02 17:44:08 -070030from autotest_lib.server import hosts
Aviv Keshet53bd44e2013-01-31 13:08:41 -080031from autotest_lib.server import frontend
32from autotest_lib.client.common_lib import error
33
34
Alex Miller6f84a792014-02-06 16:07:56 -080035def add_missing_labels(afe, hostname):
Aviv Keshet53bd44e2013-01-31 13:08:41 -080036 """
37 Queries the detectable labels supported by the given host,
38 and adds those labels to the host.
39
Aviv Keshet53bd44e2013-01-31 13:08:41 -080040 @param afe: A frontend.AFE() instance.
Alex Miller6f84a792014-02-06 16:07:56 -080041 @param hostname: The host to query and update.
Aviv Keshet53bd44e2013-01-31 13:08:41 -080042
43 @return: True on success.
44 False on failure to fetch labels or to add any individual label.
45 """
46
47 try:
J. Richard Barnetteecdbd192013-10-02 17:44:08 -070048 host = hosts.create_host(hostname)
49 labels = host.get_labels()
Aviv Keshet53bd44e2013-01-31 13:08:41 -080050 except socket.gaierror:
51 logging.warning('Unable to establish ssh connection to hostname '
52 '%s. Skipping.', hostname)
53 return False
J. Richard Barnetteecdbd192013-10-02 17:44:08 -070054 except error.AutoservError:
Aviv Keshet53bd44e2013-01-31 13:08:41 -080055 logging.warning('Unable to query labels on hostname %s. Skipping.',
56 hostname)
57 return False
Alex Miller6f84a792014-02-06 16:07:56 -080058 finally:
59 host.close()
Aviv Keshet53bd44e2013-01-31 13:08:41 -080060
Alex Miller6f84a792014-02-06 16:07:56 -080061 label_matches = afe.get_labels(name__in=labels)
Aviv Keshet53bd44e2013-01-31 13:08:41 -080062
Alex Miller6f84a792014-02-06 16:07:56 -080063 for label in label_matches:
64 label.add_hosts(hosts=[hostname])
Aviv Keshet53bd44e2013-01-31 13:08:41 -080065
Alex Miller6f84a792014-02-06 16:07:56 -080066 missing_labels = set(labels) - set([l.name for l in label_matches])
Aviv Keshet53bd44e2013-01-31 13:08:41 -080067
Alex Miller6f84a792014-02-06 16:07:56 -080068 if missing_labels:
69 for label in missing_labels:
Aviv Keshet53bd44e2013-01-31 13:08:41 -080070 logging.warning('Unable to add label %s to host %s. '
Alex Miller6f84a792014-02-06 16:07:56 -080071 'Skipping unknown label.', label, hostname)
72 return False
Aviv Keshet53bd44e2013-01-31 13:08:41 -080073
Alex Miller6f84a792014-02-06 16:07:56 -080074 return True
Aviv Keshet53bd44e2013-01-31 13:08:41 -080075
76
77def main():
78 """"
79 Entry point for add_detected_host_labels script.
80 """
81
82 parser = argparse.ArgumentParser()
83 parser.add_argument('-s', '--silent', dest='silent', action='store_true',
Alex Miller6f84a792014-02-06 16:07:56 -080084 help='Suppress all but critical logging messages.')
Aviv Keshet53bd44e2013-01-31 13:08:41 -080085 parser.add_argument('-i', '--info', dest='info_only', action='store_true',
Alex Miller6f84a792014-02-06 16:07:56 -080086 help='Suppress logging messages below INFO priority.')
87 parser.add_argument('-m', '--machines', dest='machines',
88 help='Comma separated list of machines to check.')
Aviv Keshet53bd44e2013-01-31 13:08:41 -080089 options = parser.parse_args()
90
91 if options.silent and options.info_only:
92 print 'The -i and -s flags cannot be used together.'
93 parser.print_help()
94 return 0
95
96
97 if options.silent:
98 logging.disable(logging.CRITICAL)
99
100 if options.info_only:
101 logging.disable(logging.DEBUG)
102
Alex Miller6f84a792014-02-06 16:07:56 -0800103 threadpool = pool.ThreadPool()
Aviv Keshet53bd44e2013-01-31 13:08:41 -0800104 afe = frontend.AFE()
Aviv Keshet53bd44e2013-01-31 13:08:41 -0800105
Alex Miller6f84a792014-02-06 16:07:56 -0800106 if options.machines:
107 hostnames = [m.strip() for m in options.machines.split(',')]
108 else:
109 hostnames = afe.get_hostnames()
Aviv Keshet53bd44e2013-01-31 13:08:41 -0800110
Alex Miller6f84a792014-02-06 16:07:56 -0800111 successes = sum(threadpool.imap_unordered(
112 lambda x: add_missing_labels(afe, x),
113 hostnames))
Aviv Keshet53bd44e2013-01-31 13:08:41 -0800114 attempts = len(hostnames)
115
116 logging.info('Label updating finished. Failed update on %d out of %d '
Alex Miller6f84a792014-02-06 16:07:56 -0800117 'hosts.', attempts-successes, attempts)
Aviv Keshet53bd44e2013-01-31 13:08:41 -0800118
119 return 0
120
121
122if __name__ == '__main__':
J. Richard Barnetteecdbd192013-10-02 17:44:08 -0700123 sys.exit(main())