• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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