You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

230 lines
7.4 KiB

# Copyright 2020 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""cvd_runtime_config class."""
import json
import os
import re
from acloud import errors
_CFG_KEY_CROSVM_BINARY = "crosvm_binary"
_CFG_KEY_X_RES = "x_res"
_CFG_KEY_Y_RES = "y_res"
_CFG_KEY_DPI = "dpi"
_CFG_KEY_VIRTUAL_DISK_PATHS = "virtual_disk_paths"
_CFG_KEY_INSTANCES = "instances"
_CFG_KEY_ADB_IP_PORT = "adb_ip_and_port"
_CFG_KEY_INSTANCE_DIR = "instance_dir"
_CFG_KEY_VNC_PORT = "vnc_server_port"
_CFG_KEY_ADB_PORT = "host_port"
_CFG_KEY_ENABLE_WEBRTC = "enable_webrtc"
# TODO(148648620): Check instance_home_[id] for backward compatible.
_RE_LOCAL_INSTANCE_ID = re.compile(r".+(?:local-instance-|instance_home_)"
r"(?P<ins_id>\d+).+")
def _GetIdFromInstanceDirStr(instance_dir):
"""Look for instance id from the path of instance dir.
Args:
instance_dir: String, path of instance_dir.
Returns:
String of instance id.
"""
match = _RE_LOCAL_INSTANCE_ID.match(instance_dir)
if match:
return match.group("ins_id")
# To support the device which is not created by acloud.
if os.path.expanduser("~") in instance_dir:
return "1"
return None
class CvdRuntimeConfig(object):
"""The class that hold the information from cuttlefish_config.json.
The example of cuttlefish_config.json
{
"memory_mb" : 4096,
"cpus" : 2,
"dpi" : 320,
"virtual_disk_paths" :
[
"/path-to-image"
],
"adb_ip_and_port" : "0.0.0.0:6520",
"instance_dir" : "/path-to-instance-dir",
}
If we launched multiple local instances, the config will be as below:
{
"memory_mb" : 4096,
"cpus" : 2,
"dpi" : 320,
"instances" :
{
"1" :
{
"adb_ip_and_port" : "0.0.0.0:6520",
"instance_dir" : "/path-to-instance-dir",
"virtual_disk_paths" :
[
"/path-to-image"
],
}
}
}
If the avd enable the webrtc, the config will be as below:
{
"enable_webrtc" : true,
"vnc_server_binary" : "/home/vsoc-01/bin/vnc_server",
"webrtc_assets_dir" : "/home/vsoc-01/usr/share/webrtc/assets",
"webrtc_binary" : "/home/vsoc-01/bin/webRTC",
"webrtc_certs_dir" : "/home/vsoc-01/usr/share/webrtc/certs",
"webrtc_enable_adb_websocket" : false,
"webrtc_public_ip" : "0.0.0.0",
}
"""
def __init__(self, config_path=None, raw_data=None):
self._config_path = config_path
self._instance_id = "1" if raw_data else _GetIdFromInstanceDirStr(
config_path)
self._config_dict = self._GetCuttlefishRuntimeConfig(config_path,
raw_data)
self._x_res = self._config_dict.get(_CFG_KEY_X_RES)
self._y_res = self._config_dict.get(_CFG_KEY_Y_RES)
self._dpi = self._config_dict.get(_CFG_KEY_DPI)
crosvm_bin = self._config_dict.get(_CFG_KEY_CROSVM_BINARY)
self._cvd_tools_path = (os.path.dirname(crosvm_bin)
if crosvm_bin else None)
# Below properties will be collected inside of instance id node if there
# are more than one instance.
self._instance_dir = self._config_dict.get(_CFG_KEY_INSTANCE_DIR)
self._vnc_port = self._config_dict.get(_CFG_KEY_VNC_PORT)
self._adb_port = self._config_dict.get(_CFG_KEY_ADB_PORT)
self._adb_ip_port = self._config_dict.get(_CFG_KEY_ADB_IP_PORT)
self._virtual_disk_paths = self._config_dict.get(
_CFG_KEY_VIRTUAL_DISK_PATHS)
self._enable_webrtc = self._config_dict.get(_CFG_KEY_ENABLE_WEBRTC)
if not self._instance_dir:
ins_cfg = self._config_dict.get(_CFG_KEY_INSTANCES)
ins_dict = ins_cfg.get(self._instance_id)
if not ins_dict:
raise errors.ConfigError("instances[%s] property does not exist"
" in: %s" %
(self._instance_id, config_path))
self._instance_dir = ins_dict.get(_CFG_KEY_INSTANCE_DIR)
self._vnc_port = ins_dict.get(_CFG_KEY_VNC_PORT)
self._adb_port = ins_dict.get(_CFG_KEY_ADB_PORT)
self._adb_ip_port = ins_dict.get(_CFG_KEY_ADB_IP_PORT)
self._virtual_disk_paths = ins_dict.get(_CFG_KEY_VIRTUAL_DISK_PATHS)
@staticmethod
def _GetCuttlefishRuntimeConfig(runtime_cf_config_path, raw_data=None):
"""Get and parse cuttlefish_config.json.
Args:
runtime_cf_config_path: String, path of the cvd runtime config.
raw_data: String, data of the cvd runtime config.
Returns:
A dictionary that parsed from cuttlefish runtime config.
Raises:
errors.ConfigError: if file not found or config load failed.
"""
if raw_data:
# if remote instance couldn't fetch the config will return message such as
# 'cat: .../cuttlefish_config.json: No such file or directory'.
# Add this condition to prevent from JSONDecodeError.
try:
return json.loads(raw_data)
except ValueError as e:
raise errors.ConfigError(
"An exception happened when loading the raw_data of the "
"cvd runtime config:\n%s" % str(e))
if not os.path.exists(runtime_cf_config_path):
raise errors.ConfigError(
"file does not exist: %s" % runtime_cf_config_path)
with open(runtime_cf_config_path, "r") as cf_config:
return json.load(cf_config)
@property
def cvd_tools_path(self):
"""Return string of the path to the cvd tools."""
return self._cvd_tools_path
@property
def x_res(self):
"""Return x_res."""
return self._x_res
@property
def y_res(self):
"""Return y_res."""
return self._y_res
@property
def dpi(self):
"""Return dpi."""
return self._dpi
@property
def adb_ip_port(self):
"""Return adb_ip_port."""
return self._adb_ip_port
@property
def instance_dir(self):
"""Return instance_dir."""
return self._instance_dir
@property
def vnc_port(self):
"""Return vnc_port."""
return self._vnc_port
@property
def adb_port(self):
"""Return adb_port."""
return self._adb_port
@property
def config_path(self):
"""Return config_path."""
return self._config_path
@property
def virtual_disk_paths(self):
"""Return virtual_disk_paths"""
return self._virtual_disk_paths
@property
def instance_id(self):
"""Return _instance_id"""
return self._instance_id
@property
def enable_webrtc(self):
"""Return _enable_webrtc"""
return self._enable_webrtc