Home | History | Annotate | Download | only in hosts
      1 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import string
      6 import common
      7 
      8 from chromite.lib import gce
      9 
     10 from autotest_lib.client.common_lib import error
     11 from autotest_lib.client.common_lib import lsbrelease_utils
     12 from autotest_lib.client.cros import constants as client_constants
     13 from autotest_lib.server.hosts import abstract_ssh
     14 
     15 SSH_KEYS_METADATA_KEY = "sshKeys"
     16 
     17 def extract_arguments(args_dict):
     18     """Extract GCE-specific arguments from arguments dictionary.
     19 
     20     @param args_dict: dictionary of all arguments supplied to the test.
     21     """
     22 
     23     return {k: v for k, v in args_dict.items()
     24             if k in ('gce_project', 'gce_instance',
     25                      'gce_zone', 'gce_key_file')}
     26 
     27 
     28 class GceHost(abstract_ssh.AbstractSSHHost):
     29     """GCE-specific subclass of Host."""
     30 
     31     def _initialize(self, hostname, gce_args=None,
     32                     *args, **dargs):
     33         """Initializes this instance of GceHost.
     34 
     35         @param hostname: the hostnname to be passed down to AbstractSSHHost.
     36         @param gce_args: GCE-specific arguments extracted using
     37                extract_arguments().
     38         """
     39         super(GceHost, self)._initialize(hostname=hostname,
     40                                          *args, **dargs)
     41 
     42         if gce_args:
     43             self._gce_project = gce_args['gce_project']
     44             self._gce_zone = gce_args['gce_zone']
     45             self._gce_instance = gce_args['gce_instance']
     46             self._gce_key_file = gce_args['gce_key_file']
     47         else:
     48             # TODO(andreyu): determine project, zone and instance names by
     49             # querying metadata from the DUT instance
     50             raise error.AutoservError('No GCE flags provided.')
     51 
     52         self.gce = gce.GceContext.ForServiceAccountThreadSafe(
     53                 self._gce_project, self._gce_zone, self._gce_key_file)
     54 
     55 
     56     def _modify_ssh_keys(self, to_add, to_remove):
     57         """Modifies the list of ssh keys.
     58 
     59         @param username: user name to add.
     60         @param to_add: a list of new enties.
     61         @param to_remove: a list of enties to be removed.
     62         """
     63         keys = self.gce.GetCommonInstanceMetadata(
     64                 SSH_KEYS_METADATA_KEY) or ''
     65         key_set = set(string.split(keys, '\n'))
     66         new_key_set = (key_set | set(to_add)) - set(to_remove)
     67         if key_set != new_key_set:
     68             self.gce.SetCommonInstanceMetadata(
     69                     SSH_KEYS_METADATA_KEY,
     70                     string.join(list(new_key_set), '\n'))
     71 
     72     def add_ssh_key(self, username, ssh_key):
     73         """Adds a new SSH key in GCE metadata.
     74 
     75         @param username: user name to add.
     76         @param ssh_key: the key to add.
     77         """
     78         self._modify_ssh_keys(['%s:%s' % (username, ssh_key)], [])
     79 
     80 
     81     def del_ssh_key(self, username, ssh_key):
     82         """Deletes the given SSH key from GCE metadata
     83 
     84         @param username: user name to delete.
     85         @param ssh_key: the key to delete.
     86         """
     87         self._modify_ssh_keys([], ['%s:%s' % (username, ssh_key)])
     88 
     89 
     90     def get_release_version(self):
     91         """Get the value of attribute CHROMEOS_RELEASE_VERSION from lsb-release.
     92 
     93         @returns The version string in lsb-release, under attribute
     94                 CHROMEOS_RELEASE_VERSION.
     95         """
     96         lsb_release_content = self.run(
     97                     'cat "%s"' % client_constants.LSB_RELEASE).stdout.strip()
     98         return lsbrelease_utils.get_chromeos_release_version(
     99                     lsb_release_content=lsb_release_content)
    100 
    101 
    102     def set_instance_metadata(self, key, value):
    103         """Sets a single metadata value on the DUT instance.
    104 
    105         @param key: Metadata key to be set.
    106         @param value: New value, or None if the given key should be removed.
    107         """
    108         self.gce.SetInstanceMetadata(self._gce_instance, key, value)
    109 
    110     def stop(self):
    111         """Stops the DUT instance
    112         """
    113         self.gce.StopInstance(self._gce_instance)
    114 
    115     def start(self):
    116         """Starts the DUT instance
    117         """
    118         self.gce.StartInstance(self._gce_instance)
    119