blob: 22b5c145eb6b22000539fa24fab3e320a0f7d8de [file] [log] [blame]
# 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()