blob: 6f6e2c3923d327135e968cc413bd2cc8b960b197 [file] [log] [blame]
Sam Chiu81bdc652018-06-29 18:45:08 +08001#!/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.
16r"""host setup runner
17
18A setup sub task runner to support setting up the local host for AVD local
19instance.
20"""
21
22from __future__ import print_function
23
24import getpass
Sam Chiu81bdc652018-06-29 18:45:08 +080025import logging
Sam Chiu81bdc652018-06-29 18:45:08 +080026
27from acloud.internal import constants
28from acloud.internal.lib import utils
29from acloud.setup import base_task_runner
30from acloud.setup import setup_common
31
32logger = logging.getLogger(__name__)
33
34# Install cuttlefish-common will probably not work now.
35# TODO: update this to pull from the proper repo.
Kevin Chengf756bbd2018-10-11 13:50:00 -070036_AVD_REQUIRED_PKGS = ["cuttlefish-common", "ssvnc",
37 # TODO(b/117613492): This is all qemu related, take this
38 # out once they are added back in as deps for
39 # cuttlefish-common.
40 "qemu-kvm", "qemu-system-common", "qemu-system-x86",
41 "qemu-utils", "libvirt-clients", "libvirt-daemon-system"]
Sam Chiu81bdc652018-06-29 18:45:08 +080042_LIST_OF_MODULES = ["kvm_intel", "kvm"]
Kevin Chengf756bbd2018-10-11 13:50:00 -070043_UPDATE_APT_GET_CMD = "sudo apt-get update"
Sam Chiu81bdc652018-06-29 18:45:08 +080044
45
chojoyce1b818bb2018-10-03 16:34:57 +080046class AvdPkgInstaller(base_task_runner.BaseTaskRunner):
Sam Chiu81bdc652018-06-29 18:45:08 +080047 """Subtask runner class for installing required packages."""
48
49 WELCOME_MESSAGE_TITLE = "Install required package for host setup"
50 WELCOME_MESSAGE = (
51 "This step will walk you through the required packages installation for "
chojoyce1b818bb2018-10-03 16:34:57 +080052 "running Android cuttlefish devices and vnc on your host.")
Sam Chiu81bdc652018-06-29 18:45:08 +080053
54 def ShouldRun(self):
55 """Check if required packages are all installed.
56
57 Returns:
58 Boolean, True if required packages are not installed.
59 """
Sam Chiu6c738d62018-12-04 10:29:02 +080060 if not utils.IsSupportedPlatform():
Sam Chiu81bdc652018-06-29 18:45:08 +080061 return False
62
63 # Any required package is not installed or not up-to-date will need to
64 # run installation task.
chojoyce1b818bb2018-10-03 16:34:57 +080065 for pkg_name in _AVD_REQUIRED_PKGS:
Sam Chiu81bdc652018-06-29 18:45:08 +080066 if not setup_common.PackageInstalled(pkg_name):
67 return True
68
69 return False
70
71 def _Run(self):
72 """Install Cuttlefish-common package."""
73
74 logger.info("Start to install required package: %s ",
chojoyce1b818bb2018-10-03 16:34:57 +080075 _AVD_REQUIRED_PKGS)
Sam Chiu81bdc652018-06-29 18:45:08 +080076
Kevin Chengf756bbd2018-10-11 13:50:00 -070077 setup_common.CheckCmdOutput(_UPDATE_APT_GET_CMD, shell=True)
chojoyce1b818bb2018-10-03 16:34:57 +080078 for pkg in _AVD_REQUIRED_PKGS:
Sam Chiu81bdc652018-06-29 18:45:08 +080079 setup_common.InstallPackage(pkg)
80
81 logger.info("All required package are installed now.")
82
83
84class CuttlefishHostSetup(base_task_runner.BaseTaskRunner):
85 """Subtask class that setup host for cuttlefish."""
86
87 WELCOME_MESSAGE_TITLE = "Host Enviornment Setup"
88 WELCOME_MESSAGE = (
89 "This step will help you to setup enviornment for running Android "
90 "cuttlefish devices on your host. That includes adding user to kvm "
91 "related groups and checking required linux modules."
92 )
93
94 def ShouldRun(self):
95 """Check host user groups and modules.
96
97 Returns:
98 Boolean: False if user is in all required groups and all modules
99 are reloaded.
100 """
Sam Chiu6c738d62018-12-04 10:29:02 +0800101 if not utils.IsSupportedPlatform():
Sam Chiu81bdc652018-06-29 18:45:08 +0800102 return False
103
herbertxue07293a32018-11-05 20:40:11 +0800104 return not (utils.CheckUserInGroups(constants.LIST_CF_USER_GROUPS)
Sam Chiu81bdc652018-06-29 18:45:08 +0800105 and self._CheckLoadedModules(_LIST_OF_MODULES))
106
107 @staticmethod
Sam Chiu81bdc652018-06-29 18:45:08 +0800108 def _CheckLoadedModules(module_list):
109 """Check if the modules are all in use.
110
111 Args:
112 module_list: The list of module name.
113 Returns:
114 True if all modules are in use.
115 """
116 logger.info("Checking if modules are loaded: %s", module_list)
117 lsmod_output = setup_common.CheckCmdOutput("lsmod", print_cmd=False)
118 current_modules = [r.split()[0] for r in lsmod_output.splitlines()]
119 all_modules_present = True
120 for module in module_list:
121 if module not in current_modules:
122 logger.info("missing module: %s", module)
123 all_modules_present = False
124 return all_modules_present
125
126 def _Run(self):
127 """Setup host environment for local cuttlefish instance support."""
128 # TODO: provide --uid args to let user use prefered username
129 username = getpass.getuser()
130 setup_cmds = [
131 "sudo rmmod kvm_intel",
132 "sudo rmmod kvm",
133 "sudo modprobe kvm",
134 "sudo modprobe kvm_intel"]
Sam Chiuafbc6582018-09-04 20:47:13 +0800135 for group in constants.LIST_CF_USER_GROUPS:
Sam Chiu81bdc652018-06-29 18:45:08 +0800136 setup_cmds.append("sudo usermod -aG %s % s" % (group, username))
137
138 print("Below commands will be run:")
139 for setup_cmd in setup_cmds:
140 print(setup_cmd)
141
142 if self._ConfirmContinue():
143 for setup_cmd in setup_cmds:
144 setup_common.CheckCmdOutput(setup_cmd, shell=True)
145 print("Host environment setup has done!")
146
147 @staticmethod
148 def _ConfirmContinue():
149 """Ask user if they want to continue.
150
151 Returns:
152 True if user answer yes.
153 """
154 answer_client = utils.InteractWithQuestion(
Sam Chiu705b9012019-01-19 12:11:35 +0800155 "\nPress 'y' to continue or anything else to do it myself[y/N]: ",
Sam Chiu81bdc652018-06-29 18:45:08 +0800156 utils.TextColors.WARNING)
157 return answer_client in constants.USER_ANSWER_YES