xref: /aosp_15_r20/tools/acloud/setup/host_setup_runner.py (revision 800a58d989c669b8eb8a71d8df53b1ba3d411444)
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