def DeleteAndroidVirtualDevices(cfg, instance_names): """Deletes android devices. Args: cfg: An AcloudConfig instance. instance_names: A list of names of the instances to delete. Returns: A Report instance. """ r = report.Report(command="delete") credentials = auth.CreateCredentials(cfg, ALL_SCOPES) compute_client = android_compute_client.AndroidComputeClient(cfg, credentials) try: deleted, failed, error_msgs = compute_client.DeleteInstances( instance_names, cfg.zone) _AddDeletionResultToReport( r, deleted, failed, error_msgs, resource_name="instance") if r.status == report.Status.UNKNOWN: r.SetStatus(report.Status.SUCCESS) except errors.DriverError as e: r.AddError(str(e)) r.SetStatus(report.Status.FAIL) return r
def setUp(self): """Set up the test.""" super(AndroidComputeClientTest, self).setUp() self.Patch(android_compute_client.AndroidComputeClient, "InitResourceHandle") self.android_compute_client = android_compute_client.AndroidComputeClient( self._GetFakeConfig(), mock.MagicMock())
def __init__(self, cfg, devices=None): self._devices = devices or [] self._cfg = cfg credentials = auth.CreateCredentials(cfg) self._build_client = android_build_client.AndroidBuildClient( credentials) self._storage_client = gstorage_client.StorageClient(credentials) self._compute_client = android_compute_client.AndroidComputeClient( cfg, credentials)
def __init__(self, cfg, instance_name): """Initialize. Args: cfg: AcloudConfig object, used to create credentials. instance_name: string, instance name. """ credentials = auth.CreateCredentials(cfg, ALL_SCOPES) self._compute_client = android_compute_client.AndroidComputeClient( cfg, credentials) # Name of the Cloud Android instance. self._instance_name = instance_name # IP of the Cloud Android instance. self._target_ip = self._compute_client.GetInstanceIP(instance_name)
def AddPublicSshRsaToInstance(cfg, user, instance_name): """Add the public rsa key to the instance's metadata. When the public key doesn't exist in the metadata, it will add it. Args: cfg: An AcloudConfig instance. user: String, the ssh username to access instance. instance_name: String, instance name. """ credentials = auth.CreateCredentials(cfg) compute_client = android_compute_client.AndroidComputeClient( cfg, credentials) compute_client.AddSshRsaInstanceMetadata(user, cfg.ssh_public_key_path, instance_name)
def CheckAccess(cfg): """Check if user has access. Args: cfg: An AcloudConfig instance. """ credentials = auth.CreateCredentials(cfg) compute_client = android_compute_client.AndroidComputeClient( cfg, credentials) logger.info("Checking if user has access to project %s", cfg.project) if not compute_client.CheckAccess(): logger.error("User does not have access to project %s", cfg.project) # Print here so that command line user can see it. print("Looks like you do not have access to %s. " % cfg.project) if cfg.project in cfg.no_project_access_msg_map: print(cfg.no_project_access_msg_map[cfg.project])
def DeleteAndroidVirtualDevices(cfg, instance_names, default_report=None): """Deletes android devices. Args: cfg: An AcloudConfig instance. instance_names: A list of names of the instances to delete. default_report: A initialized Report instance. Returns: A Report instance. """ # delete, failed, error_msgs are used to record result. deleted = [] failed = [] error_msgs = [] r = default_report if default_report else report.Report(command="delete") credentials = auth.CreateCredentials(cfg) compute_client = android_compute_client.AndroidComputeClient( cfg, credentials) zone_instances = compute_client.GetZonesByInstances(instance_names) try: for zone, instances in zone_instances.items(): deleted_ins, failed_ins, error_ins = compute_client.DeleteInstances( instances, zone) deleted.extend(deleted_ins) failed.extend(failed_ins) error_msgs.extend(error_ins) AddDeletionResultToReport(r, deleted, failed, error_msgs, resource_name="instance") if r.status == report.Status.UNKNOWN: r.SetStatus(report.Status.SUCCESS) except errors.DriverError as e: r.AddError(str(e)) r.SetStatus(report.Status.FAIL) return r
def AddSshRsa(cfg, user, ssh_rsa_path): """Add public ssh rsa key to the project. Args: cfg: An AcloudConfig instance. user: the name of the user which the key belongs to. ssh_rsa_path: The absolute path to public rsa key. Returns: A Report instance. """ r = report.Report(command="sshkey") try: credentials = auth.CreateCredentials(cfg, ALL_SCOPES) compute_client = android_compute_client.AndroidComputeClient( cfg, credentials) compute_client.AddSshRsa(user, ssh_rsa_path) r.SetStatus(report.Status.SUCCESS) except errors.DriverError as e: r.AddError(str(e)) r.SetStatus(report.Status.FAIL) return r
def CreateGCETypeAVD(cfg, build_target=None, build_id=None, num=1, gce_image=None, local_disk_image=None, cleanup=True, serial_log_file=None, autoconnect=False, report_internal_ip=False, avd_spec=None): """Creates one or multiple gce android devices. Args: cfg: An AcloudConfig instance. build_target: Target name, e.g. "aosp_cf_x86_phone-userdebug" build_id: Build id, a string, e.g. "2263051", "P2804227" num: Number of devices to create. gce_image: string, if given, will use this gce image instead of creating a new one. implies cleanup=False. local_disk_image: string, path to a local disk image, e.g. /tmp/avd-system.tar.gz cleanup: boolean, if True clean up compute engine image and disk image in storage after creating the instance. serial_log_file: A path to a file where serial output should be saved to. autoconnect: Create ssh tunnel(s) and adb connect after device creation. report_internal_ip: Boolean to report the internal ip instead of external ip. avd_spec: AVDSpec object for pass hw_property. Returns: A Report instance. """ r = report.Report(command="create") credentials = auth.CreateCredentials(cfg) compute_client = android_compute_client.AndroidComputeClient( cfg, credentials) try: common_operations.CreateSshKeyPairIfNecessary(cfg) device_pool = AndroidVirtualDevicePool(cfg) device_pool.CreateDevices( num, build_target, build_id, gce_image, local_disk_image, cleanup, extra_data_disk_size_gb=cfg.extra_data_disk_size_gb, precreated_data_image=cfg.precreated_data_image_map.get( cfg.extra_data_disk_size_gb), avd_spec=avd_spec, extra_scopes=cfg.extra_scopes) failures = device_pool.WaitForBoot() # Write result to report. for device in device_pool.devices: ip = (device.ip.internal if report_internal_ip else device.ip.external) device_dict = {"ip": ip, "instance_name": device.instance_name} if autoconnect: forwarded_ports = utils.AutoConnect( ip_addr=ip, rsa_key_file=cfg.ssh_private_key_path, target_vnc_port=constants.GCE_VNC_PORT, target_adb_port=constants.GCE_ADB_PORT, ssh_user=_SSH_USER, client_adb_port=avd_spec.client_adb_port, extra_args_ssh_tunnel=cfg.extra_args_ssh_tunnel) device_dict[constants.VNC_PORT] = forwarded_ports.vnc_port device_dict[constants.ADB_PORT] = forwarded_ports.adb_port if avd_spec.unlock_screen: AdbTools(forwarded_ports.adb_port).AutoUnlockScreen() if device.instance_name in failures: r.AddData(key="devices_failing_boot", value=device_dict) r.AddError(str(failures[device.instance_name])) else: r.AddData(key="devices", value=device_dict) if failures: r.SetStatus(report.Status.BOOT_FAIL) else: r.SetStatus(report.Status.SUCCESS) # Dump serial logs. if serial_log_file: _FetchSerialLogsFromDevices( compute_client, instance_names=[d.instance_name for d in device_pool.devices], port=constants.DEFAULT_SERIAL_PORT, output_file=serial_log_file) except errors.DriverError as e: r.AddError(str(e)) r.SetStatus(report.Status.FAIL) return r
def Cleanup(cfg, expiration_mins): """Cleans up stale gce images, gce instances, and disk images in storage. Args: cfg: An AcloudConfig instance. expiration_mins: Integer, resources older than |expiration_mins| will be cleaned up. Returns: A Report instance. """ r = report.Report(command="cleanup") try: cut_time = (datetime.datetime.now(dateutil.tz.tzlocal()) - datetime.timedelta(minutes=expiration_mins)) logger.info( "Cleaning up any gce images/instances and cached build artifacts." "in google storage that are older than %s", cut_time) credentials = auth.CreateCredentials(cfg, ALL_SCOPES) compute_client = android_compute_client.AndroidComputeClient( cfg, credentials) storage_client = gstorage_client.StorageClient(credentials) # Cleanup expired instances items = compute_client.ListInstances(zone=cfg.zone) cleanup_list = [ item["name"] for item in _FindOldItems(items, cut_time, "creationTimestamp") ] logger.info("Found expired instances: %s", cleanup_list) for i in range(0, len(cleanup_list), MAX_BATCH_CLEANUP_COUNT): result = compute_client.DeleteInstances( instances=cleanup_list[i:i + MAX_BATCH_CLEANUP_COUNT], zone=cfg.zone) _AddDeletionResultToReport(r, *result, resource_name="instance") # Cleanup expired images items = compute_client.ListImages() skip_list = cfg.precreated_data_image_map.viewvalues() cleanup_list = [ item["name"] for item in _FindOldItems(items, cut_time, "creationTimestamp") if item["name"] not in skip_list ] logger.info("Found expired images: %s", cleanup_list) for i in range(0, len(cleanup_list), MAX_BATCH_CLEANUP_COUNT): result = compute_client.DeleteImages( image_names=cleanup_list[i:i + MAX_BATCH_CLEANUP_COUNT]) _AddDeletionResultToReport(r, *result, resource_name="image") # Cleanup expired disks # Disks should have been attached to instances with autoDelete=True. # However, sometimes disks may not be auto deleted successfully. items = compute_client.ListDisks(zone=cfg.zone) cleanup_list = [ item["name"] for item in _FindOldItems(items, cut_time, "creationTimestamp") if not item.get("users") ] logger.info("Found expired disks: %s", cleanup_list) for i in range(0, len(cleanup_list), MAX_BATCH_CLEANUP_COUNT): result = compute_client.DeleteDisks( disk_names=cleanup_list[i:i + MAX_BATCH_CLEANUP_COUNT], zone=cfg.zone) _AddDeletionResultToReport(r, *result, resource_name="disk") # Cleanup expired google storage items = storage_client.List(bucket_name=cfg.storage_bucket_name) cleanup_list = [ item["name"] for item in _FindOldItems(items, cut_time, "timeCreated") ] logger.info("Found expired cached artifacts: %s", cleanup_list) for i in range(0, len(cleanup_list), MAX_BATCH_CLEANUP_COUNT): result = storage_client.DeleteFiles( bucket_name=cfg.storage_bucket_name, object_names=cleanup_list[i:i + MAX_BATCH_CLEANUP_COUNT]) _AddDeletionResultToReport( r, *result, resource_name="cached_build_artifact") # Everything succeeded, write status to report. if r.status == report.Status.UNKNOWN: r.SetStatus(report.Status.SUCCESS) except errors.DriverError as e: r.AddError(str(e)) r.SetStatus(report.Status.FAIL) return r
def CreateAndroidVirtualDevices(cfg, build_target=None, build_id=None, num=1, gce_image=None, local_disk_image=None, cleanup=True, serial_log_file=None, logcat_file=None): """Creates one or multiple android devices. Args: cfg: An AcloudConfig instance. build_target: Target name, e.g. "gce_x86-userdebug" build_id: Build id, a string, e.g. "2263051", "P2804227" num: Number of devices to create. gce_image: string, if given, will use this gce image instead of creating a new one. implies cleanup=False. local_disk_image: string, path to a local disk image, e.g. /tmp/avd-system.tar.gz cleanup: boolean, if True clean up compute engine image and disk image in storage after creating the instance. serial_log_file: A path to a file where serial output should be saved to. logcat_file: A path to a file where logcat logs should be saved. Returns: A Report instance. """ r = report.Report(command="create") credentials = auth.CreateCredentials(cfg, ALL_SCOPES) compute_client = android_compute_client.AndroidComputeClient(cfg, credentials) try: _CreateSshKeyPairIfNecessary(cfg) device_pool = AndroidVirtualDevicePool(cfg) device_pool.CreateDevices( num, build_target, build_id, gce_image, local_disk_image, cleanup, extra_data_disk_size_gb=cfg.extra_data_disk_size_gb, precreated_data_image=cfg.precreated_data_image_map.get( cfg.extra_data_disk_size_gb)) failures = device_pool.WaitForBoot() # Write result to report. for device in device_pool.devices: device_dict = {"ip": device.ip, "instance_name": device.instance_name} if device.instance_name in failures: r.AddData(key="devices_failing_boot", value=device_dict) r.AddError(str(failures[device.instance_name])) else: r.AddData(key="devices", value=device_dict) if failures: r.SetStatus(report.Status.BOOT_FAIL) else: r.SetStatus(report.Status.SUCCESS) # Dump serial and logcat logs. if serial_log_file: _FetchSerialLogsFromDevices( compute_client, instance_names=[d.instance_name for d in device_pool.devices], port=constants.DEFAULT_SERIAL_PORT, output_file=serial_log_file) if logcat_file: _FetchSerialLogsFromDevices( compute_client, instance_names=[d.instance_name for d in device_pool.devices], port=constants.LOGCAT_SERIAL_PORT, output_file=logcat_file) except errors.DriverError as e: r.AddError(str(e)) r.SetStatus(report.Status.FAIL) return r