1#!/usr/bin/env python 2# 3# Copyright 2018 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16r"""RemoteImageRemoteInstance class. 17 18Create class that is responsible for creating a remote instance AVD with a 19remote image. 20""" 21 22import logging 23import time 24 25from acloud.create import base_avd_create 26from acloud.internal import constants 27from acloud.internal.lib import engprod_client 28from acloud.internal.lib import utils 29from acloud.public.actions import common_operations 30from acloud.public.actions import remote_instance_cf_device_factory 31from acloud.public import report 32 33 34logger = logging.getLogger(__name__) 35_DEVICE = "device" 36_DEVICE_KEY_MAPPING = {"serverUrl": "ip", "sessionId": "instance_name"} 37_LAUNCH_CVD_TIME = "launch_cvd_time" 38 39 40class RemoteImageRemoteInstance(base_avd_create.BaseAVDCreate): 41 """Create class for a remote image remote instance AVD.""" 42 43 @utils.TimeExecute(function_description="Total time: ", 44 print_before_call=False, print_status=False) 45 def _CreateAVD(self, avd_spec, no_prompts): 46 """Create the AVD. 47 48 Args: 49 avd_spec: AVDSpec object that tells us what we're going to create. 50 no_prompts: Boolean, True to skip all prompts. 51 52 Returns: 53 A Report instance. 54 """ 55 if avd_spec.oxygen: 56 return self._LeaseOxygenAVD(avd_spec) 57 device_factory = remote_instance_cf_device_factory.RemoteInstanceDeviceFactory( 58 avd_spec) 59 create_report = common_operations.CreateDevices( 60 "create_cf", avd_spec.cfg, device_factory, avd_spec.num, 61 report_internal_ip=avd_spec.report_internal_ip, 62 autoconnect=avd_spec.autoconnect, 63 avd_type=constants.TYPE_CF, 64 boot_timeout_secs=avd_spec.boot_timeout_secs, 65 unlock_screen=avd_spec.unlock_screen, 66 wait_for_boot=False, 67 connect_webrtc=avd_spec.connect_webrtc, 68 client_adb_port=avd_spec.client_adb_port) 69 # Launch vnc client if we're auto-connecting. 70 if avd_spec.connect_vnc: 71 utils.LaunchVNCFromReport(create_report, avd_spec, no_prompts) 72 if avd_spec.connect_webrtc: 73 utils.LaunchBrowserFromReport(create_report) 74 75 return create_report 76 77 def _LeaseOxygenAVD(self, avd_spec): 78 """Lease the AVD from the AVD pool. 79 80 Args: 81 avd_spec: AVDSpec object that tells us what we're going to create. 82 83 Returns: 84 A Report instance. 85 """ 86 timestart = time.time() 87 response = engprod_client.EngProdClient.LeaseDevice( 88 avd_spec.remote_image[constants.BUILD_TARGET], 89 avd_spec.remote_image[constants.BUILD_ID], 90 avd_spec.cfg.api_key, 91 avd_spec.cfg.api_url) 92 execution_time = round(time.time() - timestart, 2) 93 reporter = report.Report(command="create_cf") 94 if _DEVICE in response: 95 reporter.SetStatus(report.Status.SUCCESS) 96 device_data = response[_DEVICE] 97 device_data[_LAUNCH_CVD_TIME] = execution_time 98 self._ReplaceDeviceDataKeys(device_data) 99 reporter.UpdateData(response) 100 else: 101 reporter.SetStatus(report.Status.FAIL) 102 reporter.AddError(response.get("errorMessage")) 103 104 return reporter 105 106 @staticmethod 107 def _ReplaceDeviceDataKeys(device_data): 108 """Replace keys of device data from oxygen response. 109 110 To keep the device data using the same keys in Acloud report. Before 111 writing data to report, it needs to update the keys. 112 113 Values: 114 device_data: Dict of device data. e.g. {'sessionId': 'b01ead68', 115 'serverUrl': '10.1.1.1'} 116 """ 117 for key, val in _DEVICE_KEY_MAPPING.items(): 118 if key in device_data: 119 device_data[val] = device_data[key] 120 del device_data[key] 121 else: 122 logger.debug("There is no '%s' data in response.", key) 123