blob: 0b9c24b68cb84635ec52b31083c522a0c506d32c [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A small wrapper script, iterates through
the known hosts and tries to call get_labels()
to discover host functionality, and adds these
detected labels to host.
Limitations:
- Does not keep a count of how many labels were
actually added.
- If a label is added by this script because it
is detected as supported by get_labels, but later becomes
unsupported, this script has no way to know that it
should be removed, so it will remain attached to the host.
See crosbug.com/38569
"""
import logging
import socket
import argparse
import sys
import common
from autotest_lib.server.hosts import ssh_host
from autotest_lib.server import frontend
from autotest_lib.client.common_lib import error
def add_missing_labels(hostname, afe):
"""
Queries the detectable labels supported by the given host,
and adds those labels to the host.
@param hostname: The host to query and update.
@param afe: A frontend.AFE() instance.
@return: True on success.
False on failure to fetch labels or to add any individual label.
"""
try:
ssh_obj = ssh_host.SSHHost(hostname)
labels = ssh_obj.get_labels()
except socket.gaierror:
logging.warning('Unable to establish ssh connection to hostname '
'%s. Skipping.', hostname)
return False
except error.AutoservRunError:
logging.warning('Unable to query labels on hostname %s. Skipping.',
hostname)
return False
success = True
for label_name in labels:
label_matches = afe.get_labels(name=label_name)
if not label_matches:
success = False
logging.warning('Unable to add label %s to host %s. '
'Skipping unknown label.', label_name,
hostname)
continue
label_matches[0].add_hosts(hosts=[hostname])
return success
def main():
""""
Entry point for add_detected_host_labels script.
"""
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--silent', dest='silent', action='store_true',
help='Suppress logging messages below.')
parser.add_argument('-i', '--info', dest='info_only', action='store_true',
help='Suppress logging messages below INFO priority.')
options = parser.parse_args()
if options.silent and options.info_only:
print 'The -i and -s flags cannot be used together.'
parser.print_help()
return 0
if options.silent:
logging.disable(logging.CRITICAL)
if options.info_only:
logging.disable(logging.DEBUG)
afe = frontend.AFE()
labels = afe.get_labels()
hostnames = afe.get_hostnames()
failures = 0
attempts = 0
for hostname in hostnames:
if not add_missing_labels(hostname, afe):
failures += 1
attempts = len(hostnames)
logging.info('Label updating finished. Failed update on %d out of %d '
'hosts.', failures, attempts)
return 0
if __name__ == '__main__':
sys.exit(main())