| # 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 |
| GSUTIL_USER = 'moblab' |
| GSUTIL_INTERNAL_BUCKETS = ['gs://chromeos-image-archive'] |
| 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.sudo_run(cmd, user=GSUTIL_USER) |
| 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 |
| |
| if gs_url in GSUTIL_INTERNAL_BUCKETS: |
| self.bucket = gs_url |
| return 1 |
| |
| return 0 |
| |
| def Diagnose(self, errcode): |
| if 1 == errcode: |
| return ('Using an internal Google Storage bucket %s' % self.bucket, []) |
| |
| elif -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, []) |