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. 16"""Common code used by acloud create methods/classes.""" 17 18import logging 19import os 20 21from acloud import errors 22from acloud.internal import constants 23from acloud.internal.lib import android_build_client 24from acloud.internal.lib import auth 25from acloud.internal.lib import utils 26 27 28logger = logging.getLogger(__name__) 29 30 31def ParseHWPropertyArgs(dict_str, item_separator=",", key_value_separator=":"): 32 """Helper function to initialize a dict object from string. 33 34 e.g. 35 cpu:2,dpi:240,resolution:1280x800 36 -> {"cpu":"2", "dpi":"240", "resolution":"1280x800"} 37 38 Args: 39 dict_str: A String to be converted to dict object. 40 item_separator: String character to separate items. 41 key_value_separator: String character to separate key and value. 42 43 Returns: 44 Dict created from key:val pairs in dict_str. 45 46 Raises: 47 error.MalformedDictStringError: If dict_str is malformed. 48 """ 49 hw_dict = {} 50 if not dict_str: 51 return hw_dict 52 53 for item in dict_str.split(item_separator): 54 if key_value_separator not in item: 55 raise errors.MalformedDictStringError( 56 "Expecting ':' in '%s' to make a key-val pair" % item) 57 key, value = item.split(key_value_separator) 58 if not value or not key: 59 raise errors.MalformedDictStringError( 60 "Missing key or value in %s, expecting form of 'a:b'" % item) 61 hw_dict[key.strip()] = value.strip() 62 63 return hw_dict 64 65 66def GetCvdHostPackage(): 67 """Get cvd host package path. 68 69 Look for the host package in $ANDROID_HOST_OUT and dist dir then verify 70 existence and get cvd host package path. 71 72 Return: 73 A string, the path to the host package. 74 75 Raises: 76 errors.GetCvdLocalHostPackageError: Can't find cvd host package. 77 """ 78 dirs_to_check = list(filter(None, [os.environ.get(constants.ENV_ANDROID_HOST_OUT)])) 79 dist_dir = utils.GetDistDir() 80 if dist_dir: 81 dirs_to_check.append(dist_dir) 82 83 for path in dirs_to_check: 84 cvd_host_package = os.path.join(path, constants.CVD_HOST_PACKAGE) 85 if os.path.exists(cvd_host_package): 86 logger.debug("cvd host package: %s", cvd_host_package) 87 return cvd_host_package 88 raise errors.GetCvdLocalHostPackageError( 89 "Can't find the cvd host package (Try lunching a cuttlefish target" 90 " like aosp_cf_x86_phone-userdebug and running 'm'): \n%s" % 91 '\n'.join(dirs_to_check)) 92 93 94def DownloadRemoteArtifact(cfg, build_target, build_id, artifact, extract_path, 95 decompress=False): 96 """Download remote artifact. 97 98 Args: 99 cfg: An AcloudConfig instance. 100 build_target: String, the build target, e.g. cf_x86_phone-userdebug. 101 build_id: String, Build id, e.g. "2263051", "P2804227" 102 artifact: String, zip image or cvd host package artifact. 103 extract_path: String, a path include extracted files. 104 decompress: Boolean, if true decompress the artifact. 105 """ 106 build_client = android_build_client.AndroidBuildClient( 107 auth.CreateCredentials(cfg)) 108 temp_file = os.path.join(extract_path, artifact) 109 build_client.DownloadArtifact( 110 build_target, 111 build_id, 112 artifact, 113 temp_file) 114 if decompress: 115 utils.Decompress(temp_file, extract_path) 116 try: 117 os.remove(temp_file) 118 logger.debug("Deleted temporary file %s", temp_file) 119 except OSError as e: 120 logger.error("Failed to delete temporary file: %s", str(e)) 121