[Acloud] Support per-instance sshkey
Cherry-pick cl/147878124
BUG: 35273911
TEST: Manually tested
Change-Id: Id008ce97df35e63ce59951a26fd29f729e8363ed
diff --git a/internal/lib/android_compute_client.py b/internal/lib/android_compute_client.py
index a3167fd..f6a29a3 100755
--- a/internal/lib/android_compute_client.py
+++ b/internal/lib/android_compute_client.py
@@ -37,6 +37,7 @@
with this module, update callers of gce_manager.py to use this module.
"""
+import getpass
import logging
import os
import uuid
@@ -77,6 +78,7 @@
self._orientation = acloud_config.orientation
self._resolution = acloud_config.resolution
self._metadata = acloud_config.metadata_variable.copy()
+ self._ssh_public_key_path = acloud_config.ssh_public_key_path
@classmethod
def _FormalizeName(cls, name):
@@ -221,6 +223,31 @@
"deviceName": extra_disk_name,
}]
+ @staticmethod
+ def _LoadSshPublicKey(ssh_public_key_path):
+ """Load the content of ssh public key from a file.
+
+ Args:
+ ssh_public_key_path: String, path to the public key file.
+ E.g. ~/.ssh/acloud_rsa.pub
+ Returns:
+ String, content of the file.
+
+ Raises:
+ errors.DriverError if the public key file does not exist
+ or the content is not valid.
+ """
+ key_path = os.path.expanduser(ssh_public_key_path)
+ if not os.path.exists(key_path):
+ raise errors.DriverError(
+ "SSH public key file %s does not exist." % key_path)
+
+ with open(key_path) as f:
+ rsa = f.read()
+ rsa = rsa.strip() if rsa else rsa
+ utils.VerifyRsaPubKey(rsa)
+ return rsa
+
def CreateInstance(self, instance, image_name, extra_disk_name=None):
"""Create a gce instance given an gce image.
@@ -235,6 +262,19 @@
metadata = self._metadata.copy()
metadata["cfg_sta_display_resolution"] = self._resolution
metadata["t_force_orientation"] = self._orientation
+
+ # Add per-instance ssh key
+ if self._ssh_public_key_path:
+ rsa = self._LoadSshPublicKey(self._ssh_public_key_path)
+ logger.info("ssh_public_key_path is specified in config: %s, "
+ "will add the key to the instance.",
+ self._ssh_public_key_path)
+ metadata["sshKeys"] = "%s:%s" % (getpass.getuser(), rsa)
+ else:
+ logger.warning(
+ "ssh_public_key_path is not specified in config, "
+ "only project-wide key will be effective.")
+
super(AndroidComputeClient, self).CreateInstance(
instance, image_name, self._machine_type, metadata, self._network,
self._zone, disk_args)
@@ -254,7 +294,7 @@
instance=instance, port=1)
except errors.HttpError as e:
if e.code == 400:
- logging.debug("CheckBoot: Instance is not ready yet %s",
+ logger.debug("CheckBoot: Instance is not ready yet %s",
str(e))
return False
raise