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, [])