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. 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 25import logging 26 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. 36_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"] 42_LIST_OF_MODULES = ["kvm_intel", "kvm"] 43_UPDATE_APT_GET_CMD = "sudo apt-get update" 44 45 46class AvdPkgInstaller(base_task_runner.BaseTaskRunner): 47 """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 " 52 "running Android cuttlefish devices and vnc on your host.") 53 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 """ 60 if not utils.IsSupportedPlatform(): 61 return False 62 63 # Any required package is not installed or not up-to-date will need to 64 # run installation task. 65 for pkg_name in _AVD_REQUIRED_PKGS: 66 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 ", 75 _AVD_REQUIRED_PKGS) 76 77 setup_common.CheckCmdOutput(_UPDATE_APT_GET_CMD, shell=True) 78 for pkg in _AVD_REQUIRED_PKGS: 79 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 """ 101 if not utils.IsSupportedPlatform(): 102 return False 103 104 return not (utils.CheckUserInGroups(constants.LIST_CF_USER_GROUPS) 105 and self._CheckLoadedModules(_LIST_OF_MODULES)) 106 107 @staticmethod 108 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"] 135 for group in constants.LIST_CF_USER_GROUPS: 136 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( 155 "\nPress 'y' to continue or anything else to do it myself[y/N]: ", 156 utils.TextColors.WARNING) 157 return answer_client in constants.USER_ANSWER_YES 158