1*800a58d9SAndroid Build Coastguard Worker#!/usr/bin/env python 2*800a58d9SAndroid Build Coastguard Worker# 3*800a58d9SAndroid Build Coastguard Worker# Copyright 2018 - The Android Open Source Project 4*800a58d9SAndroid Build Coastguard Worker# 5*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*800a58d9SAndroid Build Coastguard Worker# 9*800a58d9SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*800a58d9SAndroid Build Coastguard Worker# 11*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*800a58d9SAndroid Build Coastguard Worker# limitations under the License. 16*800a58d9SAndroid Build Coastguard Workerr"""host setup runner 17*800a58d9SAndroid Build Coastguard Worker 18*800a58d9SAndroid Build Coastguard WorkerA setup sub task runner to support setting up the local host for AVD local 19*800a58d9SAndroid Build Coastguard Workerinstance. 20*800a58d9SAndroid Build Coastguard Worker""" 21*800a58d9SAndroid Build Coastguard Worker 22*800a58d9SAndroid Build Coastguard Workerfrom __future__ import print_function 23*800a58d9SAndroid Build Coastguard Worker 24*800a58d9SAndroid Build Coastguard Workerimport getpass 25*800a58d9SAndroid Build Coastguard Workerimport logging 26*800a58d9SAndroid Build Coastguard Workerimport os 27*800a58d9SAndroid Build Coastguard Workerimport shutil 28*800a58d9SAndroid Build Coastguard Workerimport sys 29*800a58d9SAndroid Build Coastguard Workerimport tempfile 30*800a58d9SAndroid Build Coastguard Worker 31*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal import constants 32*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import utils 33*800a58d9SAndroid Build Coastguard Workerfrom acloud.setup import base_task_runner 34*800a58d9SAndroid Build Coastguard Workerfrom acloud.setup import setup_common 35*800a58d9SAndroid Build Coastguard Workerfrom acloud.setup import mkcert 36*800a58d9SAndroid Build Coastguard Worker 37*800a58d9SAndroid Build Coastguard Worker 38*800a58d9SAndroid Build Coastguard Workerlogger = logging.getLogger(__name__) 39*800a58d9SAndroid Build Coastguard Worker 40*800a58d9SAndroid Build Coastguard Worker_CF_COMMOM_FOLDER = "cf-common" 41*800a58d9SAndroid Build Coastguard Worker 42*800a58d9SAndroid Build Coastguard Worker_INTEL = "intel" 43*800a58d9SAndroid Build Coastguard Worker_AMD = "amd" 44*800a58d9SAndroid Build Coastguard Worker_KVM_INTEL = "kvm_intel" 45*800a58d9SAndroid Build Coastguard Worker_KVM_AMD = "kvm_amd" 46*800a58d9SAndroid Build Coastguard Worker_LIST_OF_INTEL_MODULES = [_KVM_INTEL, "kvm"] 47*800a58d9SAndroid Build Coastguard Worker_LIST_OF_AMD_MODULES = [_KVM_AMD, "kvm"] 48*800a58d9SAndroid Build Coastguard Worker_DICT_MODULES = {_INTEL: _LIST_OF_INTEL_MODULES, _AMD: _LIST_OF_AMD_MODULES} 49*800a58d9SAndroid Build Coastguard Worker_INTEL_COMMANDS = [ 50*800a58d9SAndroid Build Coastguard Worker "sudo rmmod kvm_intel || true", "sudo rmmod kvm || true", 51*800a58d9SAndroid Build Coastguard Worker "sudo modprobe kvm", "sudo modprobe kvm_intel"] 52*800a58d9SAndroid Build Coastguard Worker_AMD_COMMANDS = [ 53*800a58d9SAndroid Build Coastguard Worker "sudo rmmod kvm_amd || true", "sudo rmmod kvm|| true", "sudo modprobe kvm", 54*800a58d9SAndroid Build Coastguard Worker "sudo modprobe kvm_amd"] 55*800a58d9SAndroid Build Coastguard Worker_DICT_SETUP_CMDS = {_INTEL: _INTEL_COMMANDS, _AMD: _AMD_COMMANDS} 56*800a58d9SAndroid Build Coastguard Worker_UPDATE_APT_GET_CMD = "sudo apt-get update" 57*800a58d9SAndroid Build Coastguard Worker_INSTALL_CUTTLEFISH_COMMOM_CMD = [ 58*800a58d9SAndroid Build Coastguard Worker "git clone https://github.com/google/android-cuttlefish.git {git_folder}", 59*800a58d9SAndroid Build Coastguard Worker "cd {git_folder}/base", 60*800a58d9SAndroid Build Coastguard Worker "debuild -i -us -uc -b", 61*800a58d9SAndroid Build Coastguard Worker "cd ../frontend", 62*800a58d9SAndroid Build Coastguard Worker "debuild -i -us -uc -b", 63*800a58d9SAndroid Build Coastguard Worker "sudo dpkg -i ../cuttlefish-base_*_*64.deb || sudo apt-get install -f", 64*800a58d9SAndroid Build Coastguard Worker "sudo dpkg -i ../cuttlefish-user_*_*64.deb || sudo apt-get install -f", 65*800a58d9SAndroid Build Coastguard Worker "sudo dpkg -i ../cuttlefish-common_*_*64.deb || sudo apt-get install -f"] 66*800a58d9SAndroid Build Coastguard Worker_INSTALL_CUTTLEFISH_COMMOM_MSG = ("\nStart to install cuttlefish-common :\n%s" 67*800a58d9SAndroid Build Coastguard Worker "\nEnter 'y' to continue, otherwise N or " 68*800a58d9SAndroid Build Coastguard Worker "enter to exit: ") 69*800a58d9SAndroid Build Coastguard Worker 70*800a58d9SAndroid Build Coastguard Worker 71*800a58d9SAndroid Build Coastguard Workerclass BasePkgInstaller(base_task_runner.BaseTaskRunner): 72*800a58d9SAndroid Build Coastguard Worker """Subtask base runner class for installing packages.""" 73*800a58d9SAndroid Build Coastguard Worker 74*800a58d9SAndroid Build Coastguard Worker # List of packages for child classes to override. 75*800a58d9SAndroid Build Coastguard Worker PACKAGES = [] 76*800a58d9SAndroid Build Coastguard Worker 77*800a58d9SAndroid Build Coastguard Worker def ShouldRun(self): 78*800a58d9SAndroid Build Coastguard Worker """Check if required packages are all installed. 79*800a58d9SAndroid Build Coastguard Worker 80*800a58d9SAndroid Build Coastguard Worker Returns: 81*800a58d9SAndroid Build Coastguard Worker Boolean, True if required packages are not installed. 82*800a58d9SAndroid Build Coastguard Worker """ 83*800a58d9SAndroid Build Coastguard Worker if not utils.IsSupportedPlatform(): 84*800a58d9SAndroid Build Coastguard Worker return False 85*800a58d9SAndroid Build Coastguard Worker 86*800a58d9SAndroid Build Coastguard Worker # Any required package is not installed or not up-to-date will need to 87*800a58d9SAndroid Build Coastguard Worker # run installation task. 88*800a58d9SAndroid Build Coastguard Worker for pkg_name in self.PACKAGES: 89*800a58d9SAndroid Build Coastguard Worker if not setup_common.PackageInstalled(pkg_name): 90*800a58d9SAndroid Build Coastguard Worker return True 91*800a58d9SAndroid Build Coastguard Worker 92*800a58d9SAndroid Build Coastguard Worker return False 93*800a58d9SAndroid Build Coastguard Worker 94*800a58d9SAndroid Build Coastguard Worker def _Run(self): 95*800a58d9SAndroid Build Coastguard Worker """Install specified packages.""" 96*800a58d9SAndroid Build Coastguard Worker cmd = "\n".join( 97*800a58d9SAndroid Build Coastguard Worker [setup_common.PKG_INSTALL_CMD % pkg 98*800a58d9SAndroid Build Coastguard Worker for pkg in self.PACKAGES 99*800a58d9SAndroid Build Coastguard Worker if not setup_common.PackageInstalled(pkg)]) 100*800a58d9SAndroid Build Coastguard Worker 101*800a58d9SAndroid Build Coastguard Worker if not utils.GetUserAnswerYes("\nStart to install package(s):\n%s" 102*800a58d9SAndroid Build Coastguard Worker "\nEnter 'y' to continue, otherwise N or " 103*800a58d9SAndroid Build Coastguard Worker "enter to exit: " % cmd): 104*800a58d9SAndroid Build Coastguard Worker sys.exit(constants.EXIT_BY_USER) 105*800a58d9SAndroid Build Coastguard Worker 106*800a58d9SAndroid Build Coastguard Worker setup_common.CheckCmdOutput(_UPDATE_APT_GET_CMD, shell=True) 107*800a58d9SAndroid Build Coastguard Worker for pkg in self.PACKAGES: 108*800a58d9SAndroid Build Coastguard Worker setup_common.InstallPackage(pkg) 109*800a58d9SAndroid Build Coastguard Worker 110*800a58d9SAndroid Build Coastguard Worker logger.info("All package(s) installed now.") 111*800a58d9SAndroid Build Coastguard Worker 112*800a58d9SAndroid Build Coastguard Worker 113*800a58d9SAndroid Build Coastguard Workerclass AvdPkgInstaller(BasePkgInstaller): 114*800a58d9SAndroid Build Coastguard Worker """Subtask runner class for installing packages for local instances.""" 115*800a58d9SAndroid Build Coastguard Worker 116*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE_TITLE = ("Install required packages for host setup for " 117*800a58d9SAndroid Build Coastguard Worker "local instances") 118*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE = ("This step will walk you through the required packages " 119*800a58d9SAndroid Build Coastguard Worker "installation for running Android cuttlefish devices " 120*800a58d9SAndroid Build Coastguard Worker "on your host.") 121*800a58d9SAndroid Build Coastguard Worker PACKAGES = constants.AVD_REQUIRED_PKGS 122*800a58d9SAndroid Build Coastguard Worker 123*800a58d9SAndroid Build Coastguard Worker 124*800a58d9SAndroid Build Coastguard Workerclass HostBasePkgInstaller(BasePkgInstaller): 125*800a58d9SAndroid Build Coastguard Worker """Subtask runner class for installing base host packages.""" 126*800a58d9SAndroid Build Coastguard Worker 127*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE_TITLE = "Install base packages on the host" 128*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE = ("This step will walk you through the base packages " 129*800a58d9SAndroid Build Coastguard Worker "installation for your host.") 130*800a58d9SAndroid Build Coastguard Worker PACKAGES = constants.BASE_REQUIRED_PKGS 131*800a58d9SAndroid Build Coastguard Worker 132*800a58d9SAndroid Build Coastguard Worker 133*800a58d9SAndroid Build Coastguard Workerclass CuttlefishCommonPkgInstaller(base_task_runner.BaseTaskRunner): 134*800a58d9SAndroid Build Coastguard Worker """Subtask base runner class for installing cuttlefish-common.""" 135*800a58d9SAndroid Build Coastguard Worker 136*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE_TITLE = "Install cuttlefish-common packages on the host" 137*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE = ("This step will walk you through the cuttlefish-common " 138*800a58d9SAndroid Build Coastguard Worker "packages installation for your host.") 139*800a58d9SAndroid Build Coastguard Worker 140*800a58d9SAndroid Build Coastguard Worker def ShouldRun(self): 141*800a58d9SAndroid Build Coastguard Worker """Check if cuttlefish-common package is installed. 142*800a58d9SAndroid Build Coastguard Worker 143*800a58d9SAndroid Build Coastguard Worker Returns: 144*800a58d9SAndroid Build Coastguard Worker Boolean, True if cuttlefish-common is not installed. 145*800a58d9SAndroid Build Coastguard Worker """ 146*800a58d9SAndroid Build Coastguard Worker if not utils.IsSupportedPlatform(): 147*800a58d9SAndroid Build Coastguard Worker return False 148*800a58d9SAndroid Build Coastguard Worker 149*800a58d9SAndroid Build Coastguard Worker # Any required package is not installed or not up-to-date will need to 150*800a58d9SAndroid Build Coastguard Worker # run installation task. 151*800a58d9SAndroid Build Coastguard Worker if not setup_common.PackageInstalled(constants.CUTTLEFISH_COMMOM_PKG): 152*800a58d9SAndroid Build Coastguard Worker return True 153*800a58d9SAndroid Build Coastguard Worker return False 154*800a58d9SAndroid Build Coastguard Worker 155*800a58d9SAndroid Build Coastguard Worker def _Run(self): 156*800a58d9SAndroid Build Coastguard Worker """Install cuttlefilsh-common packages.""" 157*800a58d9SAndroid Build Coastguard Worker if setup_common.IsPackageInAptList(constants.CUTTLEFISH_COMMOM_PKG): 158*800a58d9SAndroid Build Coastguard Worker cmd = setup_common.PKG_INSTALL_CMD % constants.CUTTLEFISH_COMMOM_PKG 159*800a58d9SAndroid Build Coastguard Worker if not utils.GetUserAnswerYes(_INSTALL_CUTTLEFISH_COMMOM_MSG % cmd): 160*800a58d9SAndroid Build Coastguard Worker sys.exit(constants.EXIT_BY_USER) 161*800a58d9SAndroid Build Coastguard Worker setup_common.InstallPackage(constants.CUTTLEFISH_COMMOM_PKG) 162*800a58d9SAndroid Build Coastguard Worker return 163*800a58d9SAndroid Build Coastguard Worker 164*800a58d9SAndroid Build Coastguard Worker # Install cuttlefish-common from github. 165*800a58d9SAndroid Build Coastguard Worker cf_common_path = os.path.join(tempfile.mkdtemp(), _CF_COMMOM_FOLDER) 166*800a58d9SAndroid Build Coastguard Worker logger.debug("cuttlefish-common path: %s", cf_common_path) 167*800a58d9SAndroid Build Coastguard Worker cmd = "\n".join(sub_cmd.format(git_folder=cf_common_path) 168*800a58d9SAndroid Build Coastguard Worker for sub_cmd in _INSTALL_CUTTLEFISH_COMMOM_CMD) 169*800a58d9SAndroid Build Coastguard Worker try: 170*800a58d9SAndroid Build Coastguard Worker if not utils.GetUserAnswerYes(_INSTALL_CUTTLEFISH_COMMOM_MSG % cmd): 171*800a58d9SAndroid Build Coastguard Worker sys.exit(constants.EXIT_BY_USER) 172*800a58d9SAndroid Build Coastguard Worker setup_common.CheckCmdOutput(cmd, shell=True) 173*800a58d9SAndroid Build Coastguard Worker finally: 174*800a58d9SAndroid Build Coastguard Worker shutil.rmtree(os.path.dirname(cf_common_path)) 175*800a58d9SAndroid Build Coastguard Worker 176*800a58d9SAndroid Build Coastguard Worker 177*800a58d9SAndroid Build Coastguard Workerclass LocalCAHostSetup(base_task_runner.BaseTaskRunner): 178*800a58d9SAndroid Build Coastguard Worker """Subtask class that setup host for setup local CA.""" 179*800a58d9SAndroid Build Coastguard Worker 180*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE_TITLE = "Local CA Host Environment Setup" 181*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE = ("This step will walk you through the local CA setup " 182*800a58d9SAndroid Build Coastguard Worker "to your host for assuring a secure localhost url " 183*800a58d9SAndroid Build Coastguard Worker "connection when launching an AVD over webrtc.") 184*800a58d9SAndroid Build Coastguard Worker 185*800a58d9SAndroid Build Coastguard Worker def ShouldRun(self): 186*800a58d9SAndroid Build Coastguard Worker """Check if the local CA is setup or not. 187*800a58d9SAndroid Build Coastguard Worker 188*800a58d9SAndroid Build Coastguard Worker Returns: 189*800a58d9SAndroid Build Coastguard Worker Boolean, True if local CA is ready. 190*800a58d9SAndroid Build Coastguard Worker """ 191*800a58d9SAndroid Build Coastguard Worker if not utils.IsSupportedPlatform(): 192*800a58d9SAndroid Build Coastguard Worker return False 193*800a58d9SAndroid Build Coastguard Worker 194*800a58d9SAndroid Build Coastguard Worker return not mkcert.IsRootCAReady() 195*800a58d9SAndroid Build Coastguard Worker 196*800a58d9SAndroid Build Coastguard Worker def _Run(self): 197*800a58d9SAndroid Build Coastguard Worker """Setup host environment for the local CA.""" 198*800a58d9SAndroid Build Coastguard Worker if not utils.GetUserAnswerYes("\nStart to setup the local CA:\n" 199*800a58d9SAndroid Build Coastguard Worker "\nEnter 'y' to continue, otherwise N or " 200*800a58d9SAndroid Build Coastguard Worker "enter to exit: "): 201*800a58d9SAndroid Build Coastguard Worker sys.exit(constants.EXIT_BY_USER) 202*800a58d9SAndroid Build Coastguard Worker 203*800a58d9SAndroid Build Coastguard Worker mkcert.Install() 204*800a58d9SAndroid Build Coastguard Worker logger.info("The local CA '%s.pem' is installed now.", 205*800a58d9SAndroid Build Coastguard Worker constants.SSL_CA_NAME) 206*800a58d9SAndroid Build Coastguard Worker 207*800a58d9SAndroid Build Coastguard Worker 208*800a58d9SAndroid Build Coastguard Workerclass CuttlefishHostSetup(base_task_runner.BaseTaskRunner): 209*800a58d9SAndroid Build Coastguard Worker """Subtask class that setup host for cuttlefish.""" 210*800a58d9SAndroid Build Coastguard Worker 211*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE_TITLE = "Host Environment Setup" 212*800a58d9SAndroid Build Coastguard Worker WELCOME_MESSAGE = ( 213*800a58d9SAndroid Build Coastguard Worker "This step will help you to setup environment for running Android " 214*800a58d9SAndroid Build Coastguard Worker "cuttlefish devices on your host. That includes adding user to kvm " 215*800a58d9SAndroid Build Coastguard Worker "related groups and checking required linux modules." 216*800a58d9SAndroid Build Coastguard Worker ) 217*800a58d9SAndroid Build Coastguard Worker 218*800a58d9SAndroid Build Coastguard Worker def ShouldRun(self): 219*800a58d9SAndroid Build Coastguard Worker """Check host user groups and modules. 220*800a58d9SAndroid Build Coastguard Worker 221*800a58d9SAndroid Build Coastguard Worker Returns: 222*800a58d9SAndroid Build Coastguard Worker Boolean: False if user is in all required groups and all modules 223*800a58d9SAndroid Build Coastguard Worker are reloaded. 224*800a58d9SAndroid Build Coastguard Worker """ 225*800a58d9SAndroid Build Coastguard Worker if not utils.IsSupportedPlatform(): 226*800a58d9SAndroid Build Coastguard Worker return False 227*800a58d9SAndroid Build Coastguard Worker 228*800a58d9SAndroid Build Coastguard Worker return not (utils.CheckUserInGroups(constants.LIST_CF_USER_GROUPS) 229*800a58d9SAndroid Build Coastguard Worker and self._CheckLoadedModules( 230*800a58d9SAndroid Build Coastguard Worker _DICT_MODULES.get(self._GetProcessorType()))) 231*800a58d9SAndroid Build Coastguard Worker 232*800a58d9SAndroid Build Coastguard Worker @staticmethod 233*800a58d9SAndroid Build Coastguard Worker def _GetProcessorType(): 234*800a58d9SAndroid Build Coastguard Worker """Get the processor type. 235*800a58d9SAndroid Build Coastguard Worker 236*800a58d9SAndroid Build Coastguard Worker Returns: 237*800a58d9SAndroid Build Coastguard Worker The processor type of the host. e.g. amd, intel. 238*800a58d9SAndroid Build Coastguard Worker """ 239*800a58d9SAndroid Build Coastguard Worker lsmod_output = setup_common.CheckCmdOutput("lsmod", print_cmd=False) 240*800a58d9SAndroid Build Coastguard Worker current_modules = [r.split()[0] for r in lsmod_output.splitlines()] 241*800a58d9SAndroid Build Coastguard Worker if _KVM_AMD in current_modules: 242*800a58d9SAndroid Build Coastguard Worker return _AMD 243*800a58d9SAndroid Build Coastguard Worker return _INTEL 244*800a58d9SAndroid Build Coastguard Worker 245*800a58d9SAndroid Build Coastguard Worker @staticmethod 246*800a58d9SAndroid Build Coastguard Worker def _CheckLoadedModules(module_list): 247*800a58d9SAndroid Build Coastguard Worker """Check if the modules are all in use. 248*800a58d9SAndroid Build Coastguard Worker 249*800a58d9SAndroid Build Coastguard Worker Args: 250*800a58d9SAndroid Build Coastguard Worker module_list: The list of module name. 251*800a58d9SAndroid Build Coastguard Worker 252*800a58d9SAndroid Build Coastguard Worker Returns: 253*800a58d9SAndroid Build Coastguard Worker True if all modules are in use. 254*800a58d9SAndroid Build Coastguard Worker """ 255*800a58d9SAndroid Build Coastguard Worker logger.info("Checking if modules are loaded: %s", module_list) 256*800a58d9SAndroid Build Coastguard Worker lsmod_output = setup_common.CheckCmdOutput("lsmod", print_cmd=False) 257*800a58d9SAndroid Build Coastguard Worker current_modules = [r.split()[0] for r in lsmod_output.splitlines()] 258*800a58d9SAndroid Build Coastguard Worker all_modules_present = True 259*800a58d9SAndroid Build Coastguard Worker for module in module_list: 260*800a58d9SAndroid Build Coastguard Worker if module not in current_modules: 261*800a58d9SAndroid Build Coastguard Worker logger.info("missing module: %s", module) 262*800a58d9SAndroid Build Coastguard Worker all_modules_present = False 263*800a58d9SAndroid Build Coastguard Worker return all_modules_present 264*800a58d9SAndroid Build Coastguard Worker 265*800a58d9SAndroid Build Coastguard Worker def _Run(self): 266*800a58d9SAndroid Build Coastguard Worker """Setup host environment for local cuttlefish instance support.""" 267*800a58d9SAndroid Build Coastguard Worker # TODO: provide --uid args to let user use prefered username 268*800a58d9SAndroid Build Coastguard Worker username = getpass.getuser() 269*800a58d9SAndroid Build Coastguard Worker setup_cmds = _DICT_SETUP_CMDS.get(self._GetProcessorType()) 270*800a58d9SAndroid Build Coastguard Worker for group in constants.LIST_CF_USER_GROUPS: 271*800a58d9SAndroid Build Coastguard Worker setup_cmds.append("sudo usermod -aG %s % s" % (group, username)) 272*800a58d9SAndroid Build Coastguard Worker 273*800a58d9SAndroid Build Coastguard Worker print("Below commands will be run:") 274*800a58d9SAndroid Build Coastguard Worker for setup_cmd in setup_cmds: 275*800a58d9SAndroid Build Coastguard Worker print(setup_cmd) 276*800a58d9SAndroid Build Coastguard Worker 277*800a58d9SAndroid Build Coastguard Worker if self._ConfirmContinue(): 278*800a58d9SAndroid Build Coastguard Worker for setup_cmd in setup_cmds: 279*800a58d9SAndroid Build Coastguard Worker setup_common.CheckCmdOutput(setup_cmd, shell=True) 280*800a58d9SAndroid Build Coastguard Worker print("Host environment setup has done!") 281*800a58d9SAndroid Build Coastguard Worker 282*800a58d9SAndroid Build Coastguard Worker @staticmethod 283*800a58d9SAndroid Build Coastguard Worker def _ConfirmContinue(): 284*800a58d9SAndroid Build Coastguard Worker """Ask user if they want to continue. 285*800a58d9SAndroid Build Coastguard Worker 286*800a58d9SAndroid Build Coastguard Worker Returns: 287*800a58d9SAndroid Build Coastguard Worker True if user answer yes. 288*800a58d9SAndroid Build Coastguard Worker """ 289*800a58d9SAndroid Build Coastguard Worker answer_client = utils.InteractWithQuestion( 290*800a58d9SAndroid Build Coastguard Worker "\nEnter 'y' to continue, otherwise N or enter to exit: ", 291*800a58d9SAndroid Build Coastguard Worker utils.TextColors.WARNING) 292*800a58d9SAndroid Build Coastguard Worker return answer_client in constants.USER_ANSWER_YES 293