blob: f0ac3aa14df95b4ac4fced0980a6c3a2248c4a90 [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 +080026import platform
27
28from acloud.internal import constants
29from acloud.internal.lib import utils
30from acloud.setup import base_task_runner
31from acloud.setup import setup_common
32
33logger = logging.getLogger(__name__)
34
35# Install cuttlefish-common will probably not work now.
36# TODO: update this to pull from the proper repo.
Kevin Chengf756bbd2018-10-11 13:50:00 -070037_AVD_REQUIRED_PKGS = ["cuttlefish-common", "ssvnc",
38 # TODO(b/117613492): This is all qemu related, take this
39 # out once they are added back in as deps for
40 # cuttlefish-common.
41 "qemu-kvm", "qemu-system-common", "qemu-system-x86",
42 "qemu-utils", "libvirt-clients", "libvirt-daemon-system"]
Sam Chiu81bdc652018-06-29 18:45:08 +080043# dict of supported system and their distributions.
44_SUPPORTED_SYSTEMS_AND_DISTS = {"Linux": ["Ubuntu", "Debian"]}
Sam Chiu81bdc652018-06-29 18:45:08 +080045_LIST_OF_MODULES = ["kvm_intel", "kvm"]
Kevin Chengf756bbd2018-10-11 13:50:00 -070046_UPDATE_APT_GET_CMD = "sudo apt-get update"
Sam Chiu81bdc652018-06-29 18:45:08 +080047
48
49def _IsSupportedPlatform():
50 """Check if user's os is the supported platform.
51
52 Returns:
53 Boolean, True if user is using supported platform.
54 """
55 system = platform.system()
56 dist = platform.linux_distribution()[0]
57 platform_supported = (system in _SUPPORTED_SYSTEMS_AND_DISTS and
58 dist in _SUPPORTED_SYSTEMS_AND_DISTS[system])
59
60 logger.info("supported system and dists: %s",
61 _SUPPORTED_SYSTEMS_AND_DISTS)
62 logger.info("%s[%s] %s supported platform",
63 system,
64 dist,
65 "is a" if platform_supported else "is not a")
66
67 return platform_supported
68
69
chojoyce1b818bb2018-10-03 16:34:57 +080070class AvdPkgInstaller(base_task_runner.BaseTaskRunner):
Sam Chiu81bdc652018-06-29 18:45:08 +080071 """Subtask runner class for installing required packages."""
72
73 WELCOME_MESSAGE_TITLE = "Install required package for host setup"
74 WELCOME_MESSAGE = (
75 "This step will walk you through the required packages installation for "
chojoyce1b818bb2018-10-03 16:34:57 +080076 "running Android cuttlefish devices and vnc on your host.")
Sam Chiu81bdc652018-06-29 18:45:08 +080077
78 def ShouldRun(self):
79 """Check if required packages are all installed.
80
81 Returns:
82 Boolean, True if required packages are not installed.
83 """
84 if not _IsSupportedPlatform():
85 return False
86
87 # Any required package is not installed or not up-to-date will need to
88 # run installation task.
chojoyce1b818bb2018-10-03 16:34:57 +080089 for pkg_name in _AVD_REQUIRED_PKGS:
Sam Chiu81bdc652018-06-29 18:45:08 +080090 if not setup_common.PackageInstalled(pkg_name):
91 return True
92
93 return False
94
95 def _Run(self):
96 """Install Cuttlefish-common package."""
97
98 logger.info("Start to install required package: %s ",
chojoyce1b818bb2018-10-03 16:34:57 +080099 _AVD_REQUIRED_PKGS)
Sam Chiu81bdc652018-06-29 18:45:08 +0800100
Kevin Chengf756bbd2018-10-11 13:50:00 -0700101 setup_common.CheckCmdOutput(_UPDATE_APT_GET_CMD, shell=True)
chojoyce1b818bb2018-10-03 16:34:57 +0800102 for pkg in _AVD_REQUIRED_PKGS:
Sam Chiu81bdc652018-06-29 18:45:08 +0800103 setup_common.InstallPackage(pkg)
104
105 logger.info("All required package are installed now.")
106
107
108class CuttlefishHostSetup(base_task_runner.BaseTaskRunner):
109 """Subtask class that setup host for cuttlefish."""
110
111 WELCOME_MESSAGE_TITLE = "Host Enviornment Setup"
112 WELCOME_MESSAGE = (
113 "This step will help you to setup enviornment for running Android "
114 "cuttlefish devices on your host. That includes adding user to kvm "
115 "related groups and checking required linux modules."
116 )
117
118 def ShouldRun(self):
119 """Check host user groups and modules.
120
121 Returns:
122 Boolean: False if user is in all required groups and all modules
123 are reloaded.
124 """
125 if not _IsSupportedPlatform():
126 return False
127
herbertxue07293a32018-11-05 20:40:11 +0800128 return not (utils.CheckUserInGroups(constants.LIST_CF_USER_GROUPS)
Sam Chiu81bdc652018-06-29 18:45:08 +0800129 and self._CheckLoadedModules(_LIST_OF_MODULES))
130
131 @staticmethod
Sam Chiu81bdc652018-06-29 18:45:08 +0800132 def _CheckLoadedModules(module_list):
133 """Check if the modules are all in use.
134
135 Args:
136 module_list: The list of module name.
137 Returns:
138 True if all modules are in use.
139 """
140 logger.info("Checking if modules are loaded: %s", module_list)
141 lsmod_output = setup_common.CheckCmdOutput("lsmod", print_cmd=False)
142 current_modules = [r.split()[0] for r in lsmod_output.splitlines()]
143 all_modules_present = True
144 for module in module_list:
145 if module not in current_modules:
146 logger.info("missing module: %s", module)
147 all_modules_present = False
148 return all_modules_present
149
150 def _Run(self):
151 """Setup host environment for local cuttlefish instance support."""
152 # TODO: provide --uid args to let user use prefered username
153 username = getpass.getuser()
154 setup_cmds = [
155 "sudo rmmod kvm_intel",
156 "sudo rmmod kvm",
157 "sudo modprobe kvm",
158 "sudo modprobe kvm_intel"]
Sam Chiuafbc6582018-09-04 20:47:13 +0800159 for group in constants.LIST_CF_USER_GROUPS:
Sam Chiu81bdc652018-06-29 18:45:08 +0800160 setup_cmds.append("sudo usermod -aG %s % s" % (group, username))
161
162 print("Below commands will be run:")
163 for setup_cmd in setup_cmds:
164 print(setup_cmd)
165
166 if self._ConfirmContinue():
167 for setup_cmd in setup_cmds:
168 setup_common.CheckCmdOutput(setup_cmd, shell=True)
169 print("Host environment setup has done!")
170
171 @staticmethod
172 def _ConfirmContinue():
173 """Ask user if they want to continue.
174
175 Returns:
176 True if user answer yes.
177 """
178 answer_client = utils.InteractWithQuestion(
179 "\nPress 'y' to continue or anything else to do it myself:[y]",
180 utils.TextColors.WARNING)
181 return answer_client in constants.USER_ANSWER_YES