Snap for 8479413 from a4d4b1dba6318efaf89091ce80da91c5c1823e0f to tm-release

Change-Id: Id05139d5e0f3e22d3c3bae916f1a270234b1959f
diff --git a/delete/delete.py b/delete/delete.py
index e8aaaaf..98ee79e 100644
--- a/delete/delete.py
+++ b/delete/delete.py
@@ -25,12 +25,12 @@
 
 from acloud import errors
 from acloud.internal import constants
-from acloud.internal.lib import auth
 from acloud.internal.lib import cvd_compute_client_multi_stage
+from acloud.internal.lib import cvd_utils
 from acloud.internal.lib import emulator_console
 from acloud.internal.lib import goldfish_remote_host_client
 from acloud.internal.lib import oxygen_client
-from acloud.internal.lib import ssh as ssh_object
+from acloud.internal.lib import ssh
 from acloud.internal.lib import utils
 from acloud.list import list as list_instances
 from acloud.public import config
@@ -279,17 +279,13 @@
     Returns:
         delete_report.
     """
-    credentials = auth.CreateCredentials(cfg)
-    compute_client = cvd_compute_client_multi_stage.CvdComputeClient(
-        acloud_config=cfg,
-        oauth2_credentials=credentials)
-    ssh = ssh_object.Ssh(
-        ip=ssh_object.IP(ip=remote_host),
+    ssh_obj = ssh.Ssh(
+        ip=ssh.IP(ip=remote_host),
         user=host_user,
         ssh_private_key_path=(
             host_ssh_private_key_path or cfg.ssh_private_key_path))
     try:
-        compute_client.InitRemoteHost(ssh, remote_host, host_user)
+        cvd_utils.CleanUpRemoteCvd(ssh_obj, raise_error=True)
         delete_report.SetStatus(report.Status.SUCCESS)
         device_driver.AddDeletionResultToReport(
             delete_report, [remote_host], failed=[],
diff --git a/delete/delete_test.py b/delete/delete_test.py
index d216669..6baa8b9 100644
--- a/delete/delete_test.py
+++ b/delete/delete_test.py
@@ -208,17 +208,14 @@
         self.assertEqual(delete_report.status, "FAIL")
         self.assertEqual(len(delete_report.errors), 1)
 
-    @mock.patch.object(delete, "auth")
-    @mock.patch.object(delete, "cvd_compute_client_multi_stage")
-    @mock.patch.object(delete, "ssh_object")
-    def testCleanUpRemoteHost(self, mock_ssh, mock_client, mock_auth):
+    @mock.patch.object(delete, "ssh")
+    @mock.patch.object(delete, "cvd_utils")
+    def testCleanUpRemoteHost(self, mock_cvd_utils, mock_ssh):
         """Test CleanUpRemoteHost."""
         mock_ssh_ip = mock.Mock()
         mock_ssh.IP.return_value = mock_ssh_ip
         mock_ssh_obj = mock.Mock()
         mock_ssh.Ssh.return_value = mock_ssh_obj
-        mock_client_obj = mock.Mock()
-        mock_client.CvdComputeClient.return_value = mock_client_obj
         cfg_attrs = {"ssh_private_key_path": "cfg_key_path"}
         mock_cfg = mock.Mock(spec_set=list(cfg_attrs.keys()), **cfg_attrs)
         delete_report = report.Report(command="delete")
@@ -230,8 +227,8 @@
             ip=mock_ssh_ip,
             user="vsoc-01",
             ssh_private_key_path="cfg_key_path")
-        mock_client_obj.InitRemoteHost.assert_called_with(
-            mock_ssh_obj, "192.0.2.1", "vsoc-01")
+        mock_cvd_utils.CleanUpRemoteCvd.assert_called_with(mock_ssh_obj,
+                                                           raise_error=True)
         self.assertEqual(delete_report.status, "SUCCESS")
         self.assertEqual(delete_report.data, {
             "deleted": [
@@ -244,8 +241,8 @@
 
         mock_ssh_ip.reset_mock()
         mock_ssh_obj.reset_mock()
-        mock_client_obj.InitRemoteHost.reset_mock()
-        mock_client_obj.InitRemoteHost.side_effect = (
+        mock_cvd_utils.reset_mock()
+        mock_cvd_utils.CleanUpRemoteCvd.side_effect = (
             subprocess.CalledProcessError(cmd="test", returncode=1))
         delete_report = report.Report(command="delete")
 
@@ -256,8 +253,8 @@
             ip=mock_ssh_ip,
             user="user",
             ssh_private_key_path="key_path")
-        mock_client_obj.InitRemoteHost.assert_called_with(
-            mock_ssh_obj, "192.0.2.2", "user")
+        mock_cvd_utils.CleanUpRemoteCvd.assert_called_with(mock_ssh_obj,
+                                                           raise_error=True)
         self.assertEqual(delete_report.status, "FAIL")
         self.assertEqual(len(delete_report.errors), 1)
 
diff --git a/internal/lib/cvd_compute_client.py b/internal/lib/cvd_compute_client.py
index cdedbe2..e4245e7 100644
--- a/internal/lib/cvd_compute_client.py
+++ b/internal/lib/cvd_compute_client.py
@@ -56,7 +56,7 @@
                       "cvd_01_fetch_kernel_bid",
                       "cvd_01_fetch_kernel_build_target"]
 
-
+# TODO(228405515): Delete CvdComputeClient class.
 class CvdComputeClient(android_compute_client.AndroidComputeClient):
     """Client that manages Anadroid Virtual Device."""
 
diff --git a/internal/lib/cvd_compute_client_multi_stage.py b/internal/lib/cvd_compute_client_multi_stage.py
index 817f716..5464dee 100644
--- a/internal/lib/cvd_compute_client_multi_stage.py
+++ b/internal/lib/cvd_compute_client_multi_stage.py
@@ -46,6 +46,7 @@
 from acloud.internal import constants
 from acloud.internal.lib import android_build_client
 from acloud.internal.lib import android_compute_client
+from acloud.internal.lib import cvd_utils
 from acloud.internal.lib import gcompute_client
 from acloud.internal.lib import utils
 from acloud.internal.lib.ssh import Ssh
@@ -185,8 +186,7 @@
         self._ip = ip
         self._user = user
         self._ssh.WaitForSsh(timeout=self._ins_timeout_secs)
-        self.StopCvd()
-        self.CleanUp()
+        cvd_utils.CleanUpRemoteCvd(self._ssh, raise_error=False)
 
     # TODO(171376263): Refactor CreateInstance() args with avd_spec.
     # pylint: disable=arguments-differ,too-many-locals,broad-except
@@ -259,8 +259,7 @@
             self._ssh.WaitForSsh(timeout=self._ins_timeout_secs)
             if avd_spec:
                 if avd_spec.instance_name_to_reuse:
-                    self.StopCvd()
-                    self.CleanUp()
+                    cvd_utils.CleanUpRemoteCvd(self._ssh, raise_error=False)
                 return instance
 
             # TODO: Remove following code after create_cf deprecated.
@@ -374,33 +373,6 @@
         launch_cvd_args.append(_AGREEMENT_PROMPT_ARG)
         return launch_cvd_args
 
-    # pylint: disable=broad-except
-    def StopCvd(self):
-        """Stop CVD.
-
-        If stop_cvd fails, assume that it's because there was no previously
-        running device.
-        """
-        ssh_command = "./bin/stop_cvd"
-        try:
-            self._ssh.Run(ssh_command)
-        except Exception as e:
-            logger.debug("Failed to stop_cvd (possibly no running device): %s", e)
-
-    def CleanUp(self):
-        """Clean up the files/folders on the existing instance.
-
-        If previous AVD have these files/folders, reusing the instance may have
-        side effects if not cleaned. The path in the instance is /home/vsoc-01/*
-        if the GCE user is vsoc-01.
-        """
-
-        ssh_command = "'/bin/rm -rf /home/%s/*'" % self._user
-        try:
-            self._ssh.Run(ssh_command)
-        except subprocess.CalledProcessError as e:
-            logger.debug("Failed to clean up the files/folders: %s", e)
-
     @utils.TimeExecute(function_description="Launching AVD(s) and waiting for boot up",
                        result_evaluator=utils.BootEvaluator)
     def LaunchCvd(self, instance, avd_spec=None,
diff --git a/internal/lib/cvd_utils.py b/internal/lib/cvd_utils.py
index 20534ef..5194806 100644
--- a/internal/lib/cvd_utils.py
+++ b/internal/lib/cvd_utils.py
@@ -18,6 +18,7 @@
 import logging
 import os
 import posixpath as remote_path
+import subprocess
 
 from acloud import errors
 from acloud.create import create_common
@@ -252,6 +253,32 @@
     return []
 
 
+def CleanUpRemoteCvd(ssh_obj, raise_error):
+    """Call stop_cvd and delete the files on a remote host or a GCE instance.
+
+    Args:
+        ssh_obj: An Ssh object.
+        raise_error: Whether to raise an error if the remote instance is not
+                     running.
+
+    Raises:
+        subprocess.CalledProcessError if any command fails.
+    """
+    stop_cvd_cmd = "./bin/stop_cvd"
+    if raise_error:
+        ssh_obj.Run(stop_cvd_cmd)
+    else:
+        try:
+            ssh_obj.Run(stop_cvd_cmd, retry=0)
+        except subprocess.CalledProcessError as e:
+            logger.debug(
+                "Failed to stop_cvd (possibly no running device): %s", e)
+
+    # This command deletes all files except hidden files under HOME.
+    # It does not raise an error if no files can be deleted.
+    ssh_obj.Run("'rm -rf ./*'")
+
+
 def ConvertRemoteLogs(log_paths):
     """Convert paths on a remote host or a GCE instance to log objects.
 
diff --git a/internal/lib/cvd_utils_test.py b/internal/lib/cvd_utils_test.py
index ab0e82a..28dc441 100644
--- a/internal/lib/cvd_utils_test.py
+++ b/internal/lib/cvd_utils_test.py
@@ -15,6 +15,7 @@
 """Tests for cvd_utils."""
 
 import os
+import subprocess
 import tempfile
 import unittest
 from unittest import mock
@@ -126,6 +127,28 @@
             mock_ssh.Run.assert_called_once()
             self.assertEqual(2, mock_ssh.ScpPushFile.call_count)
 
+
+    def testCleanUpRemoteCvd(self):
+        """Test CleanUpRemoteCvd."""
+        mock_ssh = mock.Mock()
+        cvd_utils.CleanUpRemoteCvd(mock_ssh, raise_error=True)
+        mock_ssh.Run.assert_any_call("./bin/stop_cvd")
+        mock_ssh.Run.assert_any_call("'rm -rf ./*'")
+
+        mock_ssh.reset_mock()
+        mock_ssh.Run.side_effect = [
+            subprocess.CalledProcessError(cmd="should raise", returncode=1)]
+        with self.assertRaises(subprocess.CalledProcessError):
+            cvd_utils.CleanUpRemoteCvd(mock_ssh, raise_error=True)
+
+        mock_ssh.reset_mock()
+        mock_ssh.Run.side_effect = [
+            subprocess.CalledProcessError(cmd="should ignore", returncode=1),
+            None]
+        cvd_utils.CleanUpRemoteCvd(mock_ssh, raise_error=False)
+        mock_ssh.Run.assert_any_call("./bin/stop_cvd", retry=0)
+        mock_ssh.Run.assert_any_call("'rm -rf ./*'")
+
     def testConvertRemoteLogs(self):
         """Test ConvertRemoteLogs."""
         logs = cvd_utils.ConvertRemoteLogs(
diff --git a/public/acloud_main.py b/public/acloud_main.py
index 12cf258..96648d6 100644
--- a/public/acloud_main.py
+++ b/public/acloud_main.py
@@ -70,9 +70,7 @@
 from __future__ import print_function
 import argparse
 import logging
-import os
 import sys
-import sysconfig
 import traceback
 
 if sys.version_info.major == 2:
@@ -106,7 +104,6 @@
 from acloud.delete import delete
 from acloud.delete import delete_args
 from acloud.internal import constants
-from acloud.internal.lib import utils
 from acloud.reconnect import reconnect
 from acloud.reconnect import reconnect_args
 from acloud.list import list as list_instances
@@ -117,7 +114,6 @@
 from acloud.public import acloud_common
 from acloud.public import config
 from acloud.public import report
-from acloud.public.actions import create_cuttlefish_action
 from acloud.public.actions import create_goldfish_action
 from acloud.pull import pull
 from acloud.pull import pull_args
@@ -136,12 +132,10 @@
 PROG = "acloud"
 
 # Commands
-CMD_CREATE_CUTTLEFISH = "create_cf"
 CMD_CREATE_GOLDFISH = "create_gf"
 
 # Config requires fields.
 _CREATE_REQUIRE_FIELDS = ["project", "zone", "machine_type"]
-_CREATE_CF_REQUIRE_FIELDS = ["resolution"]
 # show contact info to user.
 _CONTACT_INFO = ("If you have any question or need acloud team support, "
                  "please feel free to contact us by email at "
@@ -179,13 +173,6 @@
     subparsers = parser.add_subparsers(metavar="{" + usage + "}")
     subparser_list = []
 
-    # Command "create_cf", create cuttlefish instances
-    create_cf_parser = subparsers.add_parser(CMD_CREATE_CUTTLEFISH)
-    create_cf_parser.required = False
-    create_cf_parser.set_defaults(which=CMD_CREATE_CUTTLEFISH)
-    create_args.AddCommonCreateArgs(create_cf_parser)
-    subparser_list.append(create_cf_parser)
-
     # Command "create_gf", create goldfish instances
     # In order to create a goldfish device we need the following parameters:
     # 1. The emulator build we wish to use, this is the binary that emulates
@@ -282,10 +269,6 @@
         create_args.VerifyArgs(parsed_args)
     if parsed_args.which == setup_args.CMD_SETUP:
         setup_args.VerifyArgs(parsed_args)
-    if parsed_args.which == CMD_CREATE_CUTTLEFISH:
-        if not parsed_args.build_id and not parsed_args.branch:
-            raise errors.CommandArgError(
-                "Must specify --build_id or --branch")
     if parsed_args.which == CMD_CREATE_GOLDFISH:
         if not parsed_args.emulator_build_id and not parsed_args.build_id and (
                 not parsed_args.emulator_branch and not parsed_args.branch):
@@ -301,9 +284,7 @@
                 "--system-* args are not supported for AVD type: %s"
                 % constants.TYPE_GF)
 
-    if parsed_args.which in [
-            create_args.CMD_CREATE, CMD_CREATE_CUTTLEFISH, CMD_CREATE_GOLDFISH
-    ]:
+    if parsed_args.which in [create_args.CMD_CREATE, CMD_CREATE_GOLDFISH]:
         if (parsed_args.serial_log_file
                 and not parsed_args.serial_log_file.endswith(".tar.gz")):
             raise errors.CommandArgError(
@@ -323,8 +304,6 @@
     missing_fields = []
     if args.which == create_args.CMD_CREATE and args.local_instance is None:
         missing_fields = cfg.GetMissingFields(_CREATE_REQUIRE_FIELDS)
-    if args.which == CMD_CREATE_CUTTLEFISH:
-        missing_fields.extend(cfg.GetMissingFields(_CREATE_CF_REQUIRE_FIELDS))
     if missing_fields:
         return (
             "Config file (%s) missing required fields: %s, please add these "
@@ -422,31 +401,6 @@
             constants.ACLOUD_UNKNOWN_ARGS_ERROR)
     elif args.which == create_args.CMD_CREATE:
         reporter = create.Run(args)
-    elif args.which == CMD_CREATE_CUTTLEFISH:
-        # Set ports offset when base_instance_num is specified
-        utils.SetCvdPorts(args.base_instance_num)
-
-        reporter = create_cuttlefish_action.CreateDevices(
-            cfg=cfg,
-            build_target=args.build_target,
-            build_id=args.build_id,
-            branch=args.branch,
-            kernel_build_id=args.kernel_build_id,
-            kernel_branch=args.kernel_branch,
-            kernel_build_target=args.kernel_build_target,
-            system_branch=args.system_branch,
-            system_build_id=args.system_build_id,
-            system_build_target=args.system_build_target,
-            bootloader_branch=args.bootloader_branch,
-            bootloader_build_id=args.bootloader_build_id,
-            bootloader_build_target=args.bootloader_build_target,
-            gpu=args.gpu,
-            num=args.num,
-            serial_log_file=args.serial_log_file,
-            autoconnect=args.autoconnect,
-            report_internal_ip=args.report_internal_ip,
-            boot_timeout_secs=args.boot_timeout_secs,
-            ins_timeout_secs=args.ins_timeout_secs)
     elif args.which == CMD_CREATE_GOLDFISH:
         reporter = create_goldfish_action.CreateDevices(
             cfg=cfg,