Skip to content

Commit 52584f3

Browse files
committed
Overhaul cvd help reset output
Bug: b/524685675 Assisted-by: Gemini
1 parent 69134e4 commit 52584f3

3 files changed

Lines changed: 77 additions & 66 deletions

File tree

base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,15 @@ cf_cc_library(
315315
"//cuttlefish/common/libs/utils:files",
316316
"//cuttlefish/flag_parser",
317317
"//cuttlefish/host/commands/cvd/cli:command_request",
318+
"//cuttlefish/host/commands/cvd/cli:help_format",
318319
"//cuttlefish/host/commands/cvd/cli:types",
319320
"//cuttlefish/host/commands/cvd/cli/commands:command_handler",
320321
"//cuttlefish/host/commands/cvd/instances",
321322
"//cuttlefish/host/commands/cvd/instances:instance_manager",
322323
"//cuttlefish/host/commands/cvd/utils",
323324
"//cuttlefish/result",
324325
"//libbase",
326+
"@fmt",
325327
],
326328
)
327329

base/cvd/cuttlefish/host/commands/cvd/cli/commands/reset.cpp

Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "cuttlefish/host/commands/cvd/cli/commands/reset.h"
1818

1919
#include <ctype.h>
20+
#include <fmt/format.h>
2021

2122
#include <algorithm>
2223
#include <iostream>
@@ -28,8 +29,10 @@
2829
#include "cuttlefish/flag_parser/gflags_compat.h"
2930
#include "cuttlefish/host/commands/cvd/cli/command_request.h"
3031
#include "cuttlefish/host/commands/cvd/cli/commands/command_handler.h"
32+
#include "cuttlefish/host/commands/cvd/cli/help_format.h"
3133
#include "cuttlefish/host/commands/cvd/cli/types.h"
3234
#include "cuttlefish/host/commands/cvd/instances/instance_manager.h"
35+
#include "cuttlefish/host/commands/cvd/utils/common.h"
3336
#include "cuttlefish/result/result.h"
3437

3538
namespace cuttlefish {
@@ -38,64 +41,7 @@ namespace {
3841
constexpr char kResetSubcmd[] = "reset";
3942

4043
constexpr char kSummaryHelpText[] =
41-
"Used to stop devices, optionally clean up instance files, and shut down "
42-
"the deprecated cvd server process";
43-
44-
constexpr char kDetailedHelpText[] = R"(usage: cvd reset <args>
45-
46-
* Warning: Cvd reset is an experimental implementation. When you are in panic,
47-
cvd reset is the last resort.
48-
49-
args:
50-
--help Prints this message.
51-
help
52-
53-
--device-by-cvd-only Terminates devices that a cvd server started
54-
This excludes the devices launched by "launch_cvd"
55-
or "cvd_internal_start" directly (default: false)
56-
57-
--clean-runtime-dir Cleans up the runtime directory for the devices
58-
Yet to be implemented. For now, if true, only if
59-
stop_cvd supports --clear_instance_dirs and the
60-
device could be stopped by stop_cvd, the flag takes
61-
effects. (default: true)
62-
63-
--yes Resets without asking the user confirmation.
64-
-y
65-
66-
description:
67-
68-
1. Gracefully stops all devices that the cvd client can reach.
69-
2. Forcefully stops all run_cvd processes and their subprocesses.
70-
3. Kill the cvd server itself if unresponsive.
71-
4. Reset the states of the involved instance lock files
72-
-- If cvd reset stops a device, it resets the corresponding lock file.
73-
5. Optionally, cleans up the runtime files of the stopped devices.)";
74-
75-
struct ParsedFlags {
76-
bool clean_runtime_dir = true;
77-
bool is_confirmed_by_flag = false;
78-
};
79-
80-
static Result<ParsedFlags> ParseResetFlags(cvd_common::Args subcmd_args) {
81-
if (subcmd_args.size() > 2 && subcmd_args.at(2) == "help") {
82-
// Turn `cvd reset help` into `cvd reset --help`
83-
subcmd_args[2] = "--help";
84-
}
85-
86-
ParsedFlags parsed_flags;
87-
88-
Flag y_flag =
89-
GflagsCompatFlag("yes", parsed_flags.is_confirmed_by_flag).Alias("y");
90-
std::vector<Flag> flags{
91-
y_flag,
92-
GflagsCompatFlag("clean-runtime-dir", parsed_flags.clean_runtime_dir),
93-
};
94-
CF_EXPECT(
95-
ConsumeFlags(flags, subcmd_args, {.fail_on_unexpected_argument = true}));
96-
97-
return parsed_flags;
98-
}
44+
"Remove all instance groups and kills orphaned cuttlefish processes";
9945

10046
static bool GetUserConfirm() {
10147
std::cout << "Are you sure to reset all the devices, runtime files, "
@@ -114,15 +60,17 @@ CvdResetCommandHandler::CvdResetCommandHandler(
11460

11561
Result<void> CvdResetCommandHandler::Handle(const CommandRequest& request) {
11662
std::vector<std::string> subcmd_args = request.SubcommandArguments();
117-
auto options = CF_EXPECT(ParseResetFlags(subcmd_args));
63+
std::vector<Flag> flags = CF_EXPECT(Flags(request));
64+
CF_EXPECT(
65+
ConsumeFlags(flags, subcmd_args, {.fail_on_unexpected_argument = true}));
11866

11967
// cvd reset. Give one more opportunity
120-
if (!options.is_confirmed_by_flag && !GetUserConfirm()) {
121-
std::cout << "For more details: " << " cvd reset --help" << std::endl;
68+
if (!flags_.is_confirmed_by_flag && !GetUserConfirm()) {
69+
std::cout << "For more details: " << " cvd help reset" << std::endl;
12270
return {};
12371
}
12472

125-
if (options.clean_runtime_dir) {
73+
if (flags_.clean_runtime_dir) {
12674
CF_EXPECT(instance_manager_.ResetAndClearInstanceDirs());
12775
} else {
12876
CF_EXPECT(instance_manager_.Reset());
@@ -138,9 +86,63 @@ std::string CvdResetCommandHandler::SummaryHelp() const {
13886
return kSummaryHelpText;
13987
}
14088

141-
Result<std::string> CvdResetCommandHandler::DetailedHelp(
142-
const CommandRequest& /*request*/) {
143-
return kDetailedHelpText;
89+
std::vector<HelpParagraph> CvdResetCommandHandler::Description() const {
90+
return {
91+
HelpParagraph::Raw(
92+
"Usage:\n cvd reset [--yes] [--noclean-runtime-dir]"),
93+
HelpParagraph("Warning: `cvd reset` is an experimental command and "
94+
"should only be used as a last resort. Prefer `cvd remove` "
95+
"and/or `cvd clear` instead."),
96+
HelpParagraph(
97+
"Attempts to remove any trace of running Cuttlefish devices *owned "
98+
"by the current user*. This includes Cuttlefish devices not tracked "
99+
"by CVD, such as those started by the legacy launch_cvd invocations. "
100+
"It's particularly useful for file-in-use errors and when ADB "
101+
"remains connected to untracked devices."),
102+
HelpParagraph(
103+
"This is a destructive operation that cannot be undone, so the "
104+
"command always asks for confirmation from the user and exits if it "
105+
"can't get it. Confirmation can be provided on the command line with "
106+
"the --yes flag which allows the command to be used in scripts and "
107+
"other non-interactive use cases."),
108+
HelpParagraph(
109+
"By default, all instance directories and files are deleted as part "
110+
"of the reset. It is possible to skip this step for untracked "
111+
"instances (those not members of any known instance group) by "
112+
"passing the --noclean-runtime-dir flag. This allows examining the "
113+
"runtime files of any untracked instances after the reset. Tracked "
114+
"instances can be managed using other commands (like stop) to "
115+
"preserve their files, so this option doesn't apply to them and "
116+
"their runtime files are always deleted during reset."),
117+
HelpParagraph("`cvd reset` executes the following steps:"),
118+
HelpParagraph(" 1. Stop and remove all known instance groups."),
119+
HelpParagraph(" 2. Gracefully stop all remaining devices that CVD can "
120+
"reach and optionally clean their runtime directories."),
121+
HelpParagraph(
122+
" 3. Kill all remaining run_cvd processes and their subprocesses."),
123+
HelpParagraph(" 4. Release host resources previously used by any "
124+
"untracked devices."),
125+
HelpParagraph(
126+
fmt::format("These steps are a best-effort attempt at resetting CVD "
127+
"to a clean state, but it may sometimes not be enough. "
128+
"In those cases the best course of action might be to "
129+
"reboot the system and then delete the '{}' directory.",
130+
CvdDir())),
131+
};
132+
}
133+
134+
Result<std::vector<Flag>> CvdResetCommandHandler::Flags(const CommandRequest&) {
135+
Flag y_flag = GflagsCompatFlag("yes", flags_.is_confirmed_by_flag)
136+
.Alias("y")
137+
.Help(
138+
"Provide user confirmation in advance so the command "
139+
"doesn't ask for it interactively.");
140+
Flag clean_runtime_dir_flag =
141+
GflagsCompatFlag("clean-runtime-dir", flags_.clean_runtime_dir)
142+
.Help(
143+
"Clean up the runtime directory for untracked devices (not "
144+
"members of any known instance group)");
145+
return std::vector<Flag>{y_flag, clean_runtime_dir_flag};
144146
}
145147

146148
std::unique_ptr<CvdCommandHandler> NewCvdResetCommandHandler(

base/cvd/cuttlefish/host/commands/cvd/cli/commands/reset.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "cuttlefish/host/commands/cvd/cli/command_request.h"
2323
#include "cuttlefish/host/commands/cvd/cli/commands/command_handler.h"
24+
#include "cuttlefish/host/commands/cvd/cli/help_format.h"
2425
#include "cuttlefish/host/commands/cvd/cli/types.h"
2526
#include "cuttlefish/host/commands/cvd/instances/instance_manager.h"
2627
#include "cuttlefish/result/result.h"
@@ -35,10 +36,16 @@ class CvdResetCommandHandler : public CvdCommandHandler {
3536
cvd_common::Args CmdList() const override;
3637

3738
std::string SummaryHelp() const override;
38-
Result<std::string> DetailedHelp(const CommandRequest& request) override;
39+
std::vector<HelpParagraph> Description() const override;
40+
Result<std::vector<Flag>> Flags(const CommandRequest&) override;
3941

4042
private:
43+
struct ResetFlags {
44+
bool clean_runtime_dir = true;
45+
bool is_confirmed_by_flag = false;
46+
};
4147
InstanceManager& instance_manager_;
48+
ResetFlags flags_;
4249
};
4350

4451
std::unique_ptr<CvdCommandHandler> NewCvdResetCommandHandler(

0 commit comments

Comments
 (0)