Merge "Add file name and no prompt args for acloud pull." am: ec0bd30aa8 am: 9e82ee9a2a
am: 3c80a5fb3b

Change-Id: I6d936e101d3924c5530ffc549c84bb570fbe4c24
diff --git a/internal/lib/cvd_compute_client_multi_stage.py b/internal/lib/cvd_compute_client_multi_stage.py
index a4c2826..44c0e90 100644
--- a/internal/lib/cvd_compute_client_multi_stage.py
+++ b/internal/lib/cvd_compute_client_multi_stage.py
@@ -297,7 +297,7 @@
         """Launch CVD.
 
         Launch AVD with launch_cvd. If the process is failed, acloud would show
-        error messages and atuo download log files from remote instance.
+        error messages and auto download log files from remote instance.
 
         Args:
             instance: String, instance name.
diff --git a/pull/pull.py b/pull/pull.py
index 60c2074..1f99c5c 100644
--- a/pull/pull.py
+++ b/pull/pull.py
@@ -41,7 +41,7 @@
 _IMG_FILE_EXTENSION = ".img"
 
 
-def PullFileFromInstance(cfg, instance):
+def PullFileFromInstance(cfg, instance, file_name=None, no_prompts=False):
     """Pull file from remote CF instance.
 
     1. Download log files to temp folder.
@@ -51,6 +51,8 @@
     Args:
         cfg: AcloudConfig object.
         instance: list.Instance() object.
+        file_name: String of file name.
+        no_prompts: Boolean, True to skip the prompt about file streaming.
 
     Returns:
         A Report instance.
@@ -59,11 +61,11 @@
               gce_user=constants.GCE_USER,
               ssh_private_key_path=cfg.ssh_private_key_path,
               extra_args_ssh_tunnel=cfg.extra_args_ssh_tunnel)
-    log_files = SelectLogFileToPull(ssh)
+    log_files = SelectLogFileToPull(ssh, file_name)
     download_folder = GetDownloadLogFolder(instance.name)
     PullLogs(ssh, log_files, download_folder)
     if len(log_files) == 1:
-        DisplayLog(ssh, log_files[0])
+        DisplayLog(ssh, log_files[0], no_prompts)
     return report.Report(command="pull")
 
 
@@ -81,17 +83,18 @@
     _DisplayPullResult(download_folder)
 
 
-def DisplayLog(ssh, log_file):
+def DisplayLog(ssh, log_file, no_prompts=False):
     """Display the content of log file in the screen.
 
     Args:
         ssh: Ssh object.
         log_file: String of the log file path.
+        no_prompts: Boolean, True to skip all prompts.
     """
     warning_msg = ("It will stream log to show on screen. If you want to stop "
                    "streaming, please press CTRL-C to exit.\nPress 'y' to show "
                    "log or read log by myself[y/N]:")
-    if utils.GetUserAnswerYes(warning_msg):
+    if no_prompts or utils.GetUserAnswerYes(warning_msg):
         ssh.Run("tail -f -n +1 %s" % log_file, show_output=True)
 
 
@@ -122,22 +125,29 @@
     return log_folder
 
 
-def SelectLogFileToPull(ssh):
+def SelectLogFileToPull(ssh, file_name=None):
     """Select one log file or all log files to downalod.
 
     1. Get all log file paths as selection list
-    2. Get user selected file path
+    2. Get user selected file path or user provided file name.
 
     Args:
         ssh: Ssh object.
-
-    Raises:
-        errors.CheckPathError: Can't find log files.
+        file_name: String of file name.
 
     Returns:
         List of selected file paths.
+
+    Raises:
+        errors.CheckPathError: Can't find log files.
     """
     log_files = GetAllLogFilePaths(ssh)
+    if file_name:
+        file_path = os.path.join(_REMOTE_LOG_FOLDER, file_name)
+        if file_path in log_files:
+            return [file_path]
+        raise errors.CheckPathError("Can't find this log file(%s) from remote "
+                                    "instance." % file_path)
 
     if len(log_files) == 1:
         return log_files
@@ -147,7 +157,7 @@
         return utils.GetAnswerFromList(log_files, enable_choose_all=True)
 
     raise errors.CheckPathError("Can't find any log file in folder(%s) from "
-                                "remote instance" % _REMOTE_LOG_FOLDER)
+                                "remote instance." % _REMOTE_LOG_FOLDER)
 
 
 def GetAllLogFilePaths(ssh):
@@ -207,5 +217,8 @@
     if args.instance_name:
         instance = list_instances.GetInstancesFromInstanceNames(
             cfg, [args.instance_name])
-        return PullFileFromInstance(cfg, instance[0])
-    return PullFileFromInstance(cfg, list_instances.ChooseOneRemoteInstance(cfg))
+        return PullFileFromInstance(cfg, instance[0], args.file_name, args.no_prompt)
+    return PullFileFromInstance(cfg,
+                                list_instances.ChooseOneRemoteInstance(cfg),
+                                args.file_name,
+                                args.no_prompt)
diff --git a/pull/pull_args.py b/pull/pull_args.py
index 62a28d4..7ab6172 100644
--- a/pull/pull_args.py
+++ b/pull/pull_args.py
@@ -39,5 +39,19 @@
         type=str,
         required=False,
         help="The name of the remote instance that need to pull log files.")
+    pull_parser.add_argument(
+        "--file-name",
+        dest="file_name",
+        type=str,
+        required=False,
+        help="The log file name to pull from the remote instance, "
+             "e.g. launcher.log, kernel.log.")
+    pull_parser.add_argument(
+        "--yes", "-y",
+        action="store_true",
+        dest="no_prompt",
+        required=False,
+        help="Assume 'yes' as an answer to the prompt when asking users about "
+             "file streaming.")
 
     return pull_parser
diff --git a/pull/pull_test.py b/pull/pull_test.py
index 458bb87..c82f12f 100644
--- a/pull/pull_test.py
+++ b/pull/pull_test.py
@@ -48,6 +48,22 @@
         expected_result = ["file2.log"]
         self.assertEqual(pull.SelectLogFileToPull(ssh), expected_result)
 
+        # Test user provided file name exist.
+        log_files = ["/home/vsoc-01/cuttlefish_runtime/file1.log",
+                     "/home/vsoc-01/cuttlefish_runtime/file2.log"]
+        input_file = "file1.log"
+        self.Patch(pull, "GetAllLogFilePaths", return_value=log_files)
+        expected_result = ["/home/vsoc-01/cuttlefish_runtime/file1.log"]
+        self.assertEqual(pull.SelectLogFileToPull(ssh, input_file), expected_result)
+
+        # Test user provided file name not exist.
+        log_files = ["/home/vsoc-01/cuttlefish_runtime/file1.log",
+                     "/home/vsoc-01/cuttlefish_runtime/file2.log"]
+        input_file = "not_exist.log"
+        self.Patch(pull, "GetAllLogFilePaths", return_value=log_files)
+        with self.assertRaises(errors.CheckPathError):
+            pull.SelectLogFileToPull(ssh, input_file)
+
     def testFilterLogfiles(self):
         """test filer log file from black list."""
         # Filter out file name is "kernel".