devserver: Basic healthchecks for devserver. This CL provides some basic healthchecks for the devserver for use with the Mob* Monitor. It provides checks for: - ensuring a Boto key is present - ensuring we can access google storage BUG=chromium:522196 TEST=Deployed and tested on a moblab. Change-Id: I4543e1d47541d82cbaf0318382d89fa01f6a976c Reviewed-on: https://chromium-review.googlesource.com/298608 Commit-Ready: Matthew Sartori <msartori@chromium.org> Tested-by: Matthew Sartori <msartori@chromium.org> Reviewed-by: Matthew Sartori <msartori@chromium.org>
diff --git a/checkfiles/devserver/__init__.py b/checkfiles/devserver/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/checkfiles/devserver/__init__.py
diff --git a/checkfiles/devserver/gs_check.py b/checkfiles/devserver/gs_check.py new file mode 100644 index 0000000..3528f4d --- /dev/null +++ b/checkfiles/devserver/gs_check.py
@@ -0,0 +1,120 @@ +# Copyright 2015 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. + +"""Google Storage health checks for devserver.""" + +from __future__ import print_function + +import netifaces +import os +import ConfigParser + +from chromite.lib import cros_build_lib + + +GLOBAL_CONFIG = '/usr/local/autotest/global_config.ini' +MOBLAB_CONFIG = '/usr/local/autotest/moblab_config.ini' +SHADOW_CONFIG = '/usr/local/autotest/shadow_config.ini' + +GSUTIL_TIMEOUT_SEC = 5 +MOBLAB_SUBNET_ADDR = '192.168.231.1' + + +def GetIp(): + for iface in netifaces.interfaces(): + if 'eth' not in iface: + continue + addrs = netifaces.ifaddresses(iface).get(netifaces.AF_INET) + if not addrs: + continue + for addr in addrs: + if MOBLAB_SUBNET_ADDR != addr.get('addr'): + return addr['addr'] + + return 'localhost' + + +class GsBucket(object): + """Verify that we have access to the correct Google Storage bucket.""" + + def __init__(self): + self.bucket = None + + def BucketReachable(self, gs_url): + """Check if we can reach the image server. + + Args: + gs_url: The url of the Google Storage image server. + + Returns: + True if |gs_url| can be reached. + False otherwise. + """ + # If our boto key is non-existent or is not configured correctly + # for access to the right bucket, this check may take ~45 seconds. + # This really ruins the monitor's performance as we do not yet + # intelligently handle long running checks. + # + # Additionally, we cannot use chromite's timeout_util as it is + # based on Python's signal module, which cannot be used outside + # of the main thread. These checks are executed in a separate + # thread handled by the monitor. + # + # To handle this, we rely on the linux utility 'timeout' and + # forcefully kill our gsutil invocation if it is taking too long. + + cmd = ['timeout', '-s', '9', str(GSUTIL_TIMEOUT_SEC), + 'gsutil', 'ls', '-b', gs_url] + try: + cros_build_lib.RunCommand(cmd) + except cros_build_lib.RunCommandError: + return False + + return True + + def Check(self): + """Verifies Google storage bucket access. + + Returns: + 0 if we can access the correct bucket for our given Boto key. + -1 if a configuration file could not be found. + -2 if the configuration files did not contain the appropriate + information. + """ + config_files = [GLOBAL_CONFIG, MOBLAB_CONFIG, SHADOW_CONFIG] + for f in config_files: + if not os.path.exists(f): + return -1 + + config = ConfigParser.ConfigParser() + config.read(config_files) + + gs_url = None + + for section in config.sections(): + for option, value in config.items(section): + if 'image_storage_server' == option: + gs_url = value + break + + if not (gs_url and self.BucketReachable(gs_url)): + self.bucket = gs_url + return -2 + + return 0 + + def Diagnose(self, errcode): + if -1 == errcode: + return ('An autotest configuration file is missing.', []) + + elif -2 == errcode: + return ('Moblab is not configured to access Google Storage.' + ' The current bucket name is set to %s. Please' + ' navigate to http://%s/moblab_setup/ and update' + ' the image_storage_server variable. For more information,' + ' please see https://www.chromium.org/chromium-os/testing/' + 'moblab/setup#TOC-Setting-up-the-boto-key-for-partners' % ( + self.bucket, GetIp()), []) + + return ('Unknown error reached with error code: %s' % errcode, [])