| # Copyright 2021 - The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| r"""host cleanup runner |
| |
| A host cleanup sub task runner will cleanup host to a pristine state. |
| """ |
| |
| from __future__ import print_function |
| |
| import logging |
| import os |
| import subprocess |
| import textwrap |
| |
| from acloud.internal import constants |
| from acloud.internal.lib import utils |
| from acloud.setup import base_task_runner |
| from acloud.setup import setup_common |
| |
| logger = logging.getLogger(__name__) |
| |
| _PARAGRAPH_BREAK = "=" |
| _PURGE_PACKAGE_CMD = "sudo apt-get purge --assume-yes %s" |
| _UNINSTALL_SUCCESS_MSG = "Package(s) [%s] have uninstalled." |
| |
| |
| class BasePurger(base_task_runner.BaseTaskRunner): |
| """Subtask base runner class for hostcleanup.""" |
| |
| PURGE_MESSAGE_TITLE = "" |
| PURGE_MESSAGE = "" |
| |
| cmds = [] |
| purge_packages = [] |
| |
| def ShouldRun(self): |
| """Check if required packages are all uninstalled. |
| |
| Returns: |
| Boolean, True if command list not null. |
| """ |
| if not utils.IsSupportedPlatform(): |
| return False |
| |
| if self.cmds: |
| return True |
| |
| utils.PrintColorString( |
| "[%s]: don't have to process." % self.PURGE_MESSAGE_TITLE, |
| utils.TextColors.WARNING) |
| return False |
| |
| def _Run(self): |
| """Run purge commands.""" |
| utils.PrintColorString("Below commands will be run: \n%s" % |
| "\n".join(self.cmds)) |
| |
| answer_client = utils.InteractWithQuestion( |
| "\nPress 'y' to continue or anything else to do it myself[y/N]: ", |
| utils.TextColors.WARNING) |
| if answer_client not in constants.USER_ANSWER_YES: |
| return |
| |
| for cmd in self.cmds: |
| try: |
| setup_common.CheckCmdOutput(cmd, |
| shell=True, |
| stderr=subprocess.STDOUT) |
| except subprocess.CalledProcessError as cpe: |
| logger.error("Run command [%s] failed: %s", |
| cmd, cpe.output) |
| |
| utils.PrintColorString((_UNINSTALL_SUCCESS_MSG % |
| ",".join(self.purge_packages)), |
| utils.TextColors.OKGREEN) |
| |
| def PrintPurgeMessage(self): |
| """Print purge message""" |
| # define the layout of message. |
| console_width = int(os.popen('stty size', 'r').read().split()[1]) |
| break_width = int(console_width / 2) |
| |
| # start to print purge message. |
| print("\n" + _PARAGRAPH_BREAK * break_width) |
| print(" [%s] " % self.PURGE_MESSAGE_TITLE) |
| print(textwrap.fill( |
| self.PURGE_MESSAGE, |
| break_width - 2, |
| initial_indent=" ", |
| subsequent_indent=" ")) |
| print(_PARAGRAPH_BREAK * break_width + "\n") |
| |
| |
| class PackagesUninstaller(BasePurger): |
| """Subtask base runner class for uninstalling packages.""" |
| |
| PURGE_MESSAGE_TITLE = "Uninstalling packages" |
| PURGE_MESSAGE = ("This will uninstall packages installed previously " |
| "through \"acloud setup --host-setup\"") |
| |
| def __init__(self): |
| """Initialize.""" |
| packages = [] |
| packages.extend(constants.AVD_REQUIRED_PKGS) |
| packages.extend(constants.BASE_REQUIRED_PKGS) |
| packages.append(constants.CUTTLEFISH_COMMOM_PKG) |
| |
| self.purge_packages = [pkg for pkg in packages |
| if setup_common.PackageInstalled(pkg)] |
| |
| self.cmds = [ |
| _PURGE_PACKAGE_CMD % pkg for pkg in self.purge_packages] |
| |
| self.PrintPurgeMessage() |