1*800a58d9SAndroid Build Coastguard Worker# Copyright 2020 - The Android Open Source Project 2*800a58d9SAndroid Build Coastguard Worker# 3*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*800a58d9SAndroid Build Coastguard Worker# 7*800a58d9SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*800a58d9SAndroid Build Coastguard Worker# 9*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*800a58d9SAndroid Build Coastguard Worker# limitations under the License. 14*800a58d9SAndroid Build Coastguard Worker"""cvd_runtime_config class.""" 15*800a58d9SAndroid Build Coastguard Worker 16*800a58d9SAndroid Build Coastguard Workerimport json 17*800a58d9SAndroid Build Coastguard Workerimport os 18*800a58d9SAndroid Build Coastguard Workerimport re 19*800a58d9SAndroid Build Coastguard Worker 20*800a58d9SAndroid Build Coastguard Workerfrom acloud import errors 21*800a58d9SAndroid Build Coastguard Worker 22*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_CROSVM_BINARY = "crosvm_binary" 23*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_DISPLAY_CONFIGS = "display_configs" 24*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_VIRTUAL_DISK_PATHS = "virtual_disk_paths" 25*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_INSTANCES = "instances" 26*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_ADB_IP_PORT = "adb_ip_and_port" 27*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_INSTANCE_DIR = "instance_dir" 28*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_ROOT_DIR = "root_dir" 29*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_VNC_PORT = "vnc_server_port" 30*800a58d9SAndroid Build Coastguard Worker# The adb port field name changes from "host_port" to "adb_host_port". 31*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_ADB_PORT = "host_port" 32*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_ADB_HOST_PORT = "adb_host_port" 33*800a58d9SAndroid Build Coastguard Worker_CFG_KEY_ENABLE_WEBRTC = "enable_webrtc" 34*800a58d9SAndroid Build Coastguard Worker# TODO(148648620): Check instance_home_[id] for backward compatible. 35*800a58d9SAndroid Build Coastguard Worker_RE_LOCAL_INSTANCE_ID = re.compile(r".+(?:local-instance-|instance_home_)" 36*800a58d9SAndroid Build Coastguard Worker r"(?P<ins_id>\d+).+") 37*800a58d9SAndroid Build Coastguard Worker 38*800a58d9SAndroid Build Coastguard Worker 39*800a58d9SAndroid Build Coastguard Workerdef _GetIdFromInstanceDirStr(instance_dir, config_dict): 40*800a58d9SAndroid Build Coastguard Worker """Look for instance id from the path of instance dir. 41*800a58d9SAndroid Build Coastguard Worker 42*800a58d9SAndroid Build Coastguard Worker Args: 43*800a58d9SAndroid Build Coastguard Worker instance_dir: String, path of instance_dir. 44*800a58d9SAndroid Build Coastguard Worker 45*800a58d9SAndroid Build Coastguard Worker Returns: 46*800a58d9SAndroid Build Coastguard Worker String of instance id. 47*800a58d9SAndroid Build Coastguard Worker """ 48*800a58d9SAndroid Build Coastguard Worker match = _RE_LOCAL_INSTANCE_ID.match(instance_dir) 49*800a58d9SAndroid Build Coastguard Worker if match: 50*800a58d9SAndroid Build Coastguard Worker return match.group("ins_id") 51*800a58d9SAndroid Build Coastguard Worker 52*800a58d9SAndroid Build Coastguard Worker # To support the device which is not created by acloud. 53*800a58d9SAndroid Build Coastguard Worker if os.path.expanduser("~") in instance_dir: 54*800a58d9SAndroid Build Coastguard Worker if config_dict: 55*800a58d9SAndroid Build Coastguard Worker instances = config_dict.get(_CFG_KEY_INSTANCES) 56*800a58d9SAndroid Build Coastguard Worker if instances: 57*800a58d9SAndroid Build Coastguard Worker return min(instances.keys()) 58*800a58d9SAndroid Build Coastguard Worker else: 59*800a58d9SAndroid Build Coastguard Worker # Old runtime config doesn't have "instances" information. 60*800a58d9SAndroid Build Coastguard Worker return "1" 61*800a58d9SAndroid Build Coastguard Worker else: 62*800a58d9SAndroid Build Coastguard Worker return "1" 63*800a58d9SAndroid Build Coastguard Worker 64*800a58d9SAndroid Build Coastguard Worker return None 65*800a58d9SAndroid Build Coastguard Worker 66*800a58d9SAndroid Build Coastguard Worker 67*800a58d9SAndroid Build Coastguard Workerclass CvdRuntimeConfig(): 68*800a58d9SAndroid Build Coastguard Worker """The class that hold the information from cuttlefish_config.json. 69*800a58d9SAndroid Build Coastguard Worker 70*800a58d9SAndroid Build Coastguard Worker The example of cuttlefish_config.json 71*800a58d9SAndroid Build Coastguard Worker { 72*800a58d9SAndroid Build Coastguard Worker "memory_mb" : 4096, 73*800a58d9SAndroid Build Coastguard Worker "cpus" : 2, 74*800a58d9SAndroid Build Coastguard Worker "display_configs" : 75*800a58d9SAndroid Build Coastguard Worker [ 76*800a58d9SAndroid Build Coastguard Worker { 77*800a58d9SAndroid Build Coastguard Worker "dpi" : 160, 78*800a58d9SAndroid Build Coastguard Worker "x_res" : 1280, 79*800a58d9SAndroid Build Coastguard Worker "y_res" : 700 80*800a58d9SAndroid Build Coastguard Worker } 81*800a58d9SAndroid Build Coastguard Worker ], 82*800a58d9SAndroid Build Coastguard Worker "dpi" : 320, 83*800a58d9SAndroid Build Coastguard Worker "virtual_disk_paths" : 84*800a58d9SAndroid Build Coastguard Worker [ 85*800a58d9SAndroid Build Coastguard Worker "/path-to-image" 86*800a58d9SAndroid Build Coastguard Worker ], 87*800a58d9SAndroid Build Coastguard Worker "adb_ip_and_port" : "0.0.0.0:6520", 88*800a58d9SAndroid Build Coastguard Worker "instance_dir" : "/path-to-instance-dir", 89*800a58d9SAndroid Build Coastguard Worker } 90*800a58d9SAndroid Build Coastguard Worker 91*800a58d9SAndroid Build Coastguard Worker If we launched multiple local instances, the config will be as below: 92*800a58d9SAndroid Build Coastguard Worker { 93*800a58d9SAndroid Build Coastguard Worker "memory_mb" : 4096, 94*800a58d9SAndroid Build Coastguard Worker "cpus" : 2, 95*800a58d9SAndroid Build Coastguard Worker "dpi" : 320, 96*800a58d9SAndroid Build Coastguard Worker "instances" : 97*800a58d9SAndroid Build Coastguard Worker { 98*800a58d9SAndroid Build Coastguard Worker "1" : 99*800a58d9SAndroid Build Coastguard Worker { 100*800a58d9SAndroid Build Coastguard Worker "adb_ip_and_port" : "0.0.0.0:6520", 101*800a58d9SAndroid Build Coastguard Worker "instance_dir" : "/path-to-instance-dir", 102*800a58d9SAndroid Build Coastguard Worker "webrtc_device_id" : "cvd-1", 103*800a58d9SAndroid Build Coastguard Worker "virtual_disk_paths" : 104*800a58d9SAndroid Build Coastguard Worker [ 105*800a58d9SAndroid Build Coastguard Worker "/path-to-image" 106*800a58d9SAndroid Build Coastguard Worker ], 107*800a58d9SAndroid Build Coastguard Worker } 108*800a58d9SAndroid Build Coastguard Worker } 109*800a58d9SAndroid Build Coastguard Worker } 110*800a58d9SAndroid Build Coastguard Worker 111*800a58d9SAndroid Build Coastguard Worker If the avd enable the webrtc, the config will be as below: 112*800a58d9SAndroid Build Coastguard Worker { 113*800a58d9SAndroid Build Coastguard Worker "enable_webrtc" : true, 114*800a58d9SAndroid Build Coastguard Worker "vnc_server_binary" : "/home/vsoc-01/bin/vnc_server", 115*800a58d9SAndroid Build Coastguard Worker "webrtc_assets_dir" : "/home/vsoc-01/usr/share/webrtc/assets", 116*800a58d9SAndroid Build Coastguard Worker "webrtc_binary" : "/home/vsoc-01/bin/webRTC", 117*800a58d9SAndroid Build Coastguard Worker "webrtc_certs_dir" : "/home/vsoc-01/usr/share/webrtc/certs", 118*800a58d9SAndroid Build Coastguard Worker "webrtc_public_ip" : "0.0.0.0", 119*800a58d9SAndroid Build Coastguard Worker } 120*800a58d9SAndroid Build Coastguard Worker 121*800a58d9SAndroid Build Coastguard Worker """ 122*800a58d9SAndroid Build Coastguard Worker 123*800a58d9SAndroid Build Coastguard Worker def __init__(self, config_path=None, raw_data=None): 124*800a58d9SAndroid Build Coastguard Worker if not config_path and not raw_data: 125*800a58d9SAndroid Build Coastguard Worker raise errors.ConfigError("No cuttlefish config found!") 126*800a58d9SAndroid Build Coastguard Worker self._config_path = config_path 127*800a58d9SAndroid Build Coastguard Worker self._config_dict = self._GetCuttlefishRuntimeConfig(config_path, 128*800a58d9SAndroid Build Coastguard Worker raw_data) 129*800a58d9SAndroid Build Coastguard Worker self._instance_id = "1" if raw_data else _GetIdFromInstanceDirStr( 130*800a58d9SAndroid Build Coastguard Worker config_path, self._config_dict) 131*800a58d9SAndroid Build Coastguard Worker self._instances = self._config_dict.get(_CFG_KEY_INSTANCES) 132*800a58d9SAndroid Build Coastguard Worker # Old runtime config doesn't have "instances" information. 133*800a58d9SAndroid Build Coastguard Worker self._instance_ids = list(self._instances.keys()) if self._instances else ["1"] 134*800a58d9SAndroid Build Coastguard Worker self._display_configs = self._config_dict.get(_CFG_KEY_DISPLAY_CONFIGS, {}) 135*800a58d9SAndroid Build Coastguard Worker self._root_dir = self._config_dict.get(_CFG_KEY_ROOT_DIR) 136*800a58d9SAndroid Build Coastguard Worker crosvm_bin = self._config_dict.get(_CFG_KEY_CROSVM_BINARY) 137*800a58d9SAndroid Build Coastguard Worker self._cvd_tools_path = (os.path.dirname(crosvm_bin) 138*800a58d9SAndroid Build Coastguard Worker if crosvm_bin else None) 139*800a58d9SAndroid Build Coastguard Worker 140*800a58d9SAndroid Build Coastguard Worker # Below properties will be collected inside of instance id node if there 141*800a58d9SAndroid Build Coastguard Worker # are more than one instance. 142*800a58d9SAndroid Build Coastguard Worker self._instance_dir = self._config_dict.get(_CFG_KEY_INSTANCE_DIR) 143*800a58d9SAndroid Build Coastguard Worker self._vnc_port = self._config_dict.get(_CFG_KEY_VNC_PORT) 144*800a58d9SAndroid Build Coastguard Worker self._adb_port = (self._config_dict.get(_CFG_KEY_ADB_PORT) or 145*800a58d9SAndroid Build Coastguard Worker self._config_dict.get(_CFG_KEY_ADB_HOST_PORT)) 146*800a58d9SAndroid Build Coastguard Worker self._adb_ip_port = self._config_dict.get(_CFG_KEY_ADB_IP_PORT) 147*800a58d9SAndroid Build Coastguard Worker self._virtual_disk_paths = self._config_dict.get( 148*800a58d9SAndroid Build Coastguard Worker _CFG_KEY_VIRTUAL_DISK_PATHS) 149*800a58d9SAndroid Build Coastguard Worker self._enable_webrtc = self._config_dict.get(_CFG_KEY_ENABLE_WEBRTC) 150*800a58d9SAndroid Build Coastguard Worker if not self._instance_dir: 151*800a58d9SAndroid Build Coastguard Worker ins_dict = self._instances.get(self._instance_id) 152*800a58d9SAndroid Build Coastguard Worker if not ins_dict: 153*800a58d9SAndroid Build Coastguard Worker raise errors.ConfigError("instances[%s] property does not exist" 154*800a58d9SAndroid Build Coastguard Worker " in: %s" % 155*800a58d9SAndroid Build Coastguard Worker (self._instance_id, config_path)) 156*800a58d9SAndroid Build Coastguard Worker self._instance_dir = ins_dict.get(_CFG_KEY_INSTANCE_DIR) 157*800a58d9SAndroid Build Coastguard Worker self._vnc_port = ins_dict.get(_CFG_KEY_VNC_PORT) 158*800a58d9SAndroid Build Coastguard Worker self._adb_port = (ins_dict.get(_CFG_KEY_ADB_PORT) or 159*800a58d9SAndroid Build Coastguard Worker ins_dict.get(_CFG_KEY_ADB_HOST_PORT)) 160*800a58d9SAndroid Build Coastguard Worker self._adb_ip_port = ins_dict.get(_CFG_KEY_ADB_IP_PORT) 161*800a58d9SAndroid Build Coastguard Worker self._virtual_disk_paths = ins_dict.get(_CFG_KEY_VIRTUAL_DISK_PATHS) 162*800a58d9SAndroid Build Coastguard Worker if not self._cvd_tools_path: 163*800a58d9SAndroid Build Coastguard Worker self._cvd_tools_path = os.path.dirname( 164*800a58d9SAndroid Build Coastguard Worker ins_dict.get(_CFG_KEY_CROSVM_BINARY)) 165*800a58d9SAndroid Build Coastguard Worker 166*800a58d9SAndroid Build Coastguard Worker @staticmethod 167*800a58d9SAndroid Build Coastguard Worker def _GetCuttlefishRuntimeConfig(runtime_cf_config_path, raw_data=None): 168*800a58d9SAndroid Build Coastguard Worker """Get and parse cuttlefish_config.json. 169*800a58d9SAndroid Build Coastguard Worker 170*800a58d9SAndroid Build Coastguard Worker Args: 171*800a58d9SAndroid Build Coastguard Worker runtime_cf_config_path: String, path of the cvd runtime config. 172*800a58d9SAndroid Build Coastguard Worker raw_data: String, data of the cvd runtime config. 173*800a58d9SAndroid Build Coastguard Worker 174*800a58d9SAndroid Build Coastguard Worker Returns: 175*800a58d9SAndroid Build Coastguard Worker A dictionary that parsed from cuttlefish runtime config. 176*800a58d9SAndroid Build Coastguard Worker 177*800a58d9SAndroid Build Coastguard Worker Raises: 178*800a58d9SAndroid Build Coastguard Worker errors.ConfigError: if file not found or config load failed. 179*800a58d9SAndroid Build Coastguard Worker """ 180*800a58d9SAndroid Build Coastguard Worker if raw_data: 181*800a58d9SAndroid Build Coastguard Worker # if remote instance couldn't fetch the config will return message such as 182*800a58d9SAndroid Build Coastguard Worker # 'cat: .../cuttlefish_config.json: No such file or directory'. 183*800a58d9SAndroid Build Coastguard Worker # Add this condition to prevent from JSONDecodeError. 184*800a58d9SAndroid Build Coastguard Worker try: 185*800a58d9SAndroid Build Coastguard Worker return json.loads(raw_data) 186*800a58d9SAndroid Build Coastguard Worker except ValueError as e: 187*800a58d9SAndroid Build Coastguard Worker raise errors.ConfigError( 188*800a58d9SAndroid Build Coastguard Worker "An exception happened when loading the raw_data of the " 189*800a58d9SAndroid Build Coastguard Worker "cvd runtime config:\n%s" % str(e)) 190*800a58d9SAndroid Build Coastguard Worker if not os.path.exists(runtime_cf_config_path): 191*800a58d9SAndroid Build Coastguard Worker raise errors.ConfigError( 192*800a58d9SAndroid Build Coastguard Worker "file does not exist: %s" % runtime_cf_config_path) 193*800a58d9SAndroid Build Coastguard Worker with open(runtime_cf_config_path, "r") as cf_config: 194*800a58d9SAndroid Build Coastguard Worker return json.load(cf_config) 195*800a58d9SAndroid Build Coastguard Worker 196*800a58d9SAndroid Build Coastguard Worker @property 197*800a58d9SAndroid Build Coastguard Worker def cvd_tools_path(self): 198*800a58d9SAndroid Build Coastguard Worker """Return string of the path to the cvd tools.""" 199*800a58d9SAndroid Build Coastguard Worker return self._cvd_tools_path 200*800a58d9SAndroid Build Coastguard Worker 201*800a58d9SAndroid Build Coastguard Worker @property 202*800a58d9SAndroid Build Coastguard Worker def display_configs(self): 203*800a58d9SAndroid Build Coastguard Worker """Return display_configs.""" 204*800a58d9SAndroid Build Coastguard Worker return self._display_configs 205*800a58d9SAndroid Build Coastguard Worker 206*800a58d9SAndroid Build Coastguard Worker @property 207*800a58d9SAndroid Build Coastguard Worker def adb_ip_port(self): 208*800a58d9SAndroid Build Coastguard Worker """Return adb_ip_port.""" 209*800a58d9SAndroid Build Coastguard Worker return self._adb_ip_port 210*800a58d9SAndroid Build Coastguard Worker 211*800a58d9SAndroid Build Coastguard Worker @property 212*800a58d9SAndroid Build Coastguard Worker def instance_dir(self): 213*800a58d9SAndroid Build Coastguard Worker """Return instance_dir.""" 214*800a58d9SAndroid Build Coastguard Worker return self._instance_dir 215*800a58d9SAndroid Build Coastguard Worker 216*800a58d9SAndroid Build Coastguard Worker @property 217*800a58d9SAndroid Build Coastguard Worker def root_dir(self): 218*800a58d9SAndroid Build Coastguard Worker """Return root_dir.""" 219*800a58d9SAndroid Build Coastguard Worker return self._root_dir 220*800a58d9SAndroid Build Coastguard Worker 221*800a58d9SAndroid Build Coastguard Worker @property 222*800a58d9SAndroid Build Coastguard Worker def vnc_port(self): 223*800a58d9SAndroid Build Coastguard Worker """Return vnc_port.""" 224*800a58d9SAndroid Build Coastguard Worker return self._vnc_port 225*800a58d9SAndroid Build Coastguard Worker 226*800a58d9SAndroid Build Coastguard Worker @property 227*800a58d9SAndroid Build Coastguard Worker def adb_port(self): 228*800a58d9SAndroid Build Coastguard Worker """Return adb_port.""" 229*800a58d9SAndroid Build Coastguard Worker return self._adb_port 230*800a58d9SAndroid Build Coastguard Worker 231*800a58d9SAndroid Build Coastguard Worker @property 232*800a58d9SAndroid Build Coastguard Worker def config_path(self): 233*800a58d9SAndroid Build Coastguard Worker """Return config_path.""" 234*800a58d9SAndroid Build Coastguard Worker return self._config_path 235*800a58d9SAndroid Build Coastguard Worker 236*800a58d9SAndroid Build Coastguard Worker @property 237*800a58d9SAndroid Build Coastguard Worker def virtual_disk_paths(self): 238*800a58d9SAndroid Build Coastguard Worker """Return virtual_disk_paths""" 239*800a58d9SAndroid Build Coastguard Worker return self._virtual_disk_paths 240*800a58d9SAndroid Build Coastguard Worker 241*800a58d9SAndroid Build Coastguard Worker @property 242*800a58d9SAndroid Build Coastguard Worker def instance_id(self): 243*800a58d9SAndroid Build Coastguard Worker """Return _instance_id""" 244*800a58d9SAndroid Build Coastguard Worker return self._instance_id 245*800a58d9SAndroid Build Coastguard Worker 246*800a58d9SAndroid Build Coastguard Worker @property 247*800a58d9SAndroid Build Coastguard Worker def instance_ids(self): 248*800a58d9SAndroid Build Coastguard Worker """Return _instance_ids""" 249*800a58d9SAndroid Build Coastguard Worker return self._instance_ids 250*800a58d9SAndroid Build Coastguard Worker 251*800a58d9SAndroid Build Coastguard Worker @property 252*800a58d9SAndroid Build Coastguard Worker def instances(self): 253*800a58d9SAndroid Build Coastguard Worker """Return _instances""" 254*800a58d9SAndroid Build Coastguard Worker return self._instances 255*800a58d9SAndroid Build Coastguard Worker 256*800a58d9SAndroid Build Coastguard Worker @property 257*800a58d9SAndroid Build Coastguard Worker def enable_webrtc(self): 258*800a58d9SAndroid Build Coastguard Worker """Return _enable_webrtc""" 259*800a58d9SAndroid Build Coastguard Worker return self._enable_webrtc 260