Skip to content

Commit b8ff44f

Browse files
committed
Better cvd help stop message
Updated to document stopping a subset of instances in the group. More details on how the stop operation works. Document selector flags too. Adds the wait_for_launcher_seconds flag alias to make the time unit more obvious.
1 parent 48fe4ea commit b8ff44f

3 files changed

Lines changed: 56 additions & 37 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ cf_cc_library(
453453
deps = [
454454
"//cuttlefish/flag_parser",
455455
"//cuttlefish/host/commands/cvd/cli:command_request",
456+
"//cuttlefish/host/commands/cvd/cli:help_format",
456457
"//cuttlefish/host/commands/cvd/cli:types",
457458
"//cuttlefish/host/commands/cvd/cli:utils",
458459
"//cuttlefish/host/commands/cvd/cli/commands:command_handler",

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

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "cuttlefish/flag_parser/gflags_compat.h"
3131
#include "cuttlefish/host/commands/cvd/cli/command_request.h"
3232
#include "cuttlefish/host/commands/cvd/cli/commands/command_handler.h"
33+
#include "cuttlefish/host/commands/cvd/cli/help_format.h"
3334
#include "cuttlefish/host/commands/cvd/cli/selector/selector.h"
3435
#include "cuttlefish/host/commands/cvd/cli/types.h"
3536
#include "cuttlefish/host/commands/cvd/cli/utils.h"
@@ -41,39 +42,12 @@
4142
namespace cuttlefish {
4243
namespace {
4344

44-
constexpr char kSummaryHelpText[] = "Stop all instances in a group";
45-
46-
constexpr char kDetailedHelpText[] =
47-
R"""(
48-
Stops all instances in an instance group
49-
50-
Usage:
51-
cvd stop [--wait_for_launcher=SECONDS] [--clear_instance_dirs]
52-
53-
Stops a running cuttlefish instance group.
54-
55-
--wait_for_launcher=SECONDS The number of seconds to wait for the launcher to
56-
respond to the stop request. If SECONDS is 0 it will wait
57-
indefinitely. Defaults to 5 seconds.
58-
59-
--clear_instance_dirs If provided the instance directories will be deleted
60-
after stopping.
61-
)""";
45+
constexpr char kSummaryHelpText[] = "Stop Cuttlefish instances";
6246

6347
struct StopFlags {
6448
size_t wait_for_launcher_secs = 5;
6549
bool clear_instance_dirs = false;
6650
};
67-
Result<StopFlags> ParseCommandFlags(cvd_common::Args& args) {
68-
StopFlags flag_values;
69-
std::vector<Flag> flags = {
70-
GflagsCompatFlag("wait_for_launcher", flag_values.wait_for_launcher_secs),
71-
GflagsCompatFlag("clear_instance_dirs", flag_values.clear_instance_dirs),
72-
};
73-
CF_EXPECT(ConsumeFlags(flags, args, {.fail_on_unexpected_argument = true}));
74-
return flag_values;
75-
}
76-
7751
} // namespace
7852

7953
CvdStopCommandHandler::CvdStopCommandHandler(InstanceManager& instance_manager)
@@ -89,10 +63,11 @@ Result<void> CvdStopCommandHandler::Handle(const CommandRequest& request) {
8963
auto group = CF_EXPECT(selector::SelectGroup(instance_manager_, request));
9064
CF_EXPECT(group.HasActiveInstances(), "Selected group is not running");
9165

92-
StopFlags flags = CF_EXPECT(ParseCommandFlags(cmd_args));
66+
CF_EXPECT(ConsumeFlags(CF_EXPECT(Flags(request)), cmd_args,
67+
{.fail_on_unexpected_argument = true}));
9368
std::optional<std::chrono::seconds> launcher_timeout;
94-
if (flags.wait_for_launcher_secs > 0) {
95-
launcher_timeout.emplace(flags.wait_for_launcher_secs);
69+
if (flags_.wait_for_launcher_secs > 0) {
70+
launcher_timeout.emplace(flags_.wait_for_launcher_secs);
9671
}
9772

9873
std::vector<unsigned> instance_nums;
@@ -109,8 +84,8 @@ Result<void> CvdStopCommandHandler::Handle(const CommandRequest& request) {
10984

11085
Result<void> stop_outcome = instance_manager_.StopInstanceGroup(
11186
group, launcher_timeout,
112-
flags.clear_instance_dirs ? InstanceDirActionOnStop::Clear
113-
: InstanceDirActionOnStop::Keep,
87+
flags_.clear_instance_dirs ? InstanceDirActionOnStop::Clear
88+
: InstanceDirActionOnStop::Keep,
11489
instance_nums);
11590

11691
GatherVmStopMetrics(group);
@@ -127,9 +102,43 @@ std::string CvdStopCommandHandler::SummaryHelp() const {
127102
return kSummaryHelpText;
128103
}
129104

130-
Result<std::string> CvdStopCommandHandler::DetailedHelp(
131-
const CommandRequest& request) {
132-
return kDetailedHelpText;
105+
std::vector<HelpParagraph> CvdStopCommandHandler::Description() const {
106+
std::vector<HelpParagraph> description;
107+
description.emplace_back(
108+
HelpParagraph::Raw("Usage:\n cvd [selectors] stop [args]"));
109+
description.emplace_back(
110+
"Stop a subset of instances from a group. A single instance, several or "
111+
"all instances in a group can be stopped at once. To stop instances from "
112+
"different groups the command must be invoked multiple times.");
113+
description.emplace_back(
114+
"Instances must be in 'Running' or 'Starting' states, otherwise the "
115+
"command will fail. Instances will be left in 'Stopped' state if the "
116+
"command succeeds and can later be started with the `cvd start` "
117+
"command.");
118+
description.emplace_back(
119+
"Instances are stopped by asking the virtual machine manager to stop, "
120+
"which typically means immediately stopping all VCPU threads. This may "
121+
"lead to data loss and/or corruption as it's roughly equivalent to "
122+
"removing the battery from a physical Android device. Logs, virtual "
123+
"disks and other files are preserved after a stop completes unless "
124+
"--clear_instance_dirs is given.");
125+
return description;
126+
}
127+
128+
Result<std::vector<Flag>> CvdStopCommandHandler::Flags(const CommandRequest&) {
129+
return std::vector<Flag>{
130+
GflagsCompatFlag("wait_for_launcher_seconds",
131+
flags_.wait_for_launcher_secs)
132+
.Alias("wait_for_launcher")
133+
.Help("Number of seconds to wait for the running instance(s) "
134+
"to report that it stopped successfully before "
135+
"forcefully stopping it."),
136+
GflagsCompatFlag("clear_instance_dirs", flags_.clear_instance_dirs)
137+
.Help("Deletes log files, temporary files, virtual disks "
138+
"overlays and other instance specific state. It does "
139+
"not delete the original disk images, but reverts any "
140+
"changes the instance may have written to disk."),
141+
};
133142
}
134143

135144
std::unique_ptr<CvdCommandHandler> NewCvdStopCommandHandler(

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@
1818

1919
#include <memory>
2020
#include <string>
21+
#include <vector>
2122

23+
#include "cuttlefish/flag_parser/flag.h"
2224
#include "cuttlefish/host/commands/cvd/cli/command_request.h"
2325
#include "cuttlefish/host/commands/cvd/cli/commands/command_handler.h"
26+
#include "cuttlefish/host/commands/cvd/cli/help_format.h"
2427
#include "cuttlefish/host/commands/cvd/cli/types.h"
2528
#include "cuttlefish/host/commands/cvd/instances/instance_manager.h"
2629
#include "cuttlefish/result/result.h"
@@ -33,12 +36,18 @@ class CvdStopCommandHandler : public CvdCommandHandler {
3336

3437
Result<void> Handle(const CommandRequest& request) override;
3538
cvd_common::Args CmdList() const override;
39+
Result<std::vector<Flag>> Flags(const CommandRequest& request) override;
3640

3741
std::string SummaryHelp() const override;
42+
std::vector<HelpParagraph> Description() const override;
3843
bool RequiresDeviceExists() const override { return true; }
39-
Result<std::string> DetailedHelp(const CommandRequest& request) override;
4044

4145
private:
46+
struct {
47+
size_t wait_for_launcher_secs = 5;
48+
bool clear_instance_dirs = false;
49+
} flags_;
50+
4251
InstanceManager& instance_manager_;
4352
};
4453

0 commit comments

Comments
 (0)