Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 151 additions & 33 deletions base/cvd/cuttlefish/host/commands/cvd/cli/commands/help.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,49 +26,86 @@

#include "absl/strings/str_join.h"

#include "cuttlefish/flag_parser/flag.h"
#include "cuttlefish/flag_parser/gflags_compat.h"
#include "cuttlefish/host/commands/cvd/cli/command_request.h"
#include "cuttlefish/host/commands/cvd/cli/commands/command_handler.h"
#include "cuttlefish/host/commands/cvd/cli/help_format.h"
#include "cuttlefish/host/commands/cvd/cli/request_context.h"
#include "cuttlefish/host/commands/cvd/cli/selector/selector_common_parser.h"
#include "cuttlefish/host/commands/cvd/cli/types.h"
#include "cuttlefish/result/result.h"

namespace cuttlefish {
namespace {

constexpr char kHelpIntroText[] = R"(Cuttlefish Virtual Device (CVD) CLI.
constexpr char kHelpExamplesText[] = R"(Typical Usage Examples:

usage: cvd <selector/driver options> <command> <args>
Create from specification (Multi-Device / Config-driven):

Driver Options:
-help Print this message
-verbosity=<LEVEL> Adjust Cvd verbosity level. LEVEL is Android log
severity. (Required: cvd >= v1.3)
1. Create a JSON configuration file (e.g., spec.json) containing:
{
"instances": [
{
"name": "phone-ins",
"disk": {
"default_build": "@ab/aosp-android-latest-release/aosp_cf_x86_64_only_phone-userdebug"
}
},
{
"name": "wearable-ins",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: a foldable is not a wearable

"disk": {
"default_build": "@ab/aosp-android-latest-release/aosp_cf_x86_64_foldable-userdebug"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This target doesn't exist: https://ci.android.com/builds/branches/aosp-android-latest-release/grid?legacy=1

At the moment there are:

  • aosp_cf_arm64_auto-userdebug
  • aosp_cf_arm64_only_phone-userdebug
  • aosp_cf_riscv64_phone-userdebug
  • aosp_cf_x86_64_auto-userdebug
  • aosp_cf_x86_64_only_auto
  • aosp_cf_x86_64_only_phone

}
}
]
}

Commands (cvd help <command> for more information):
2. Launch the group:
$ cvd create --config_file=spec.json

)";
3. View the state of the running fleet:
$ cvd fleet

constexpr char kSelectorOptionsText[] = R"(
Selector Options:
-group_name <name> Specify the name of the instance group created
or selected.
-instance_name <name> Selects the device of the given name to perform the
commands for.
-instance_name <names> Takes the names of the devices to create within an
instance group. The 'names' is comma-separated.
)";
4. View the log files:
$ cvd logs
$ cvd logs -p launcher.log

constexpr char kSummaryHelpText[] =
"Used to display help information for other commands";
5. Open the web UI at https://localhost:1443

6. Interact with the device via ADB (auto-connected on every start)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention this may not immediately work if the ADB server hasn't started yet? If you run cvd create first and then adb shell, the first adb shell will start the ADB server, see no devices, and fail. Then the autoconnector will run within some time, and then adb shell will work


7. Control the lifecycle:
$ cvd stop
$ cvd start

8. Gather all logs for troubleshooting:
$ cvd bugreport

9. Clean up and delete all resources:
$ cvd remove

Create from local source (Platform Developer / AOSP build):

1. Build Android in your terminal (ensuring ANDROID_HOST_OUT and
ANDROID_PRODUCT_OUT are set in the environment).

constexpr char kDetailedHelpText[] =
R"(cvd help - used to display help text for cvd and its commands
2. Launch the device:
$ cvd create

Example usage:
cvd help - displays summary help for available commands
3. After making changes, rebuild and restart:
$ cvd stop
$ m # Rebuild android
$ cvd start

cvd help <command> - displays more detailed help for the specific command
)";
Environment Cleanup (Last Resort):
If virtual devices become unresponsive, or if 'cvd remove' fails to fully
clean up the environment, use 'cvd reset' to forcefully terminate all
Cuttlefish-related background processes and free up host resources:
$ cvd reset)";

constexpr char kSummaryHelpText[] =
"Used to display help information for other commands";

void PrintHandler(std::stringstream& help_message,
const CvdCommandHandler& handler) {
Expand Down Expand Up @@ -104,30 +141,111 @@ std::string CvdHelpHandler::SummaryHelp() const { return kSummaryHelpText; }

bool CvdHelpHandler::RequiresHostConfiguration() const { return false; }

Result<std::string> CvdHelpHandler::DetailedHelp(
const CommandRequest& request) {
return kDetailedHelpText;
std::vector<HelpParagraph> CvdHelpHandler::Description() const {
return {
HelpParagraph("Example usage:"),
HelpParagraph::Raw(
" cvd help - displays summary help for available commands"),
HelpParagraph::Raw(" cvd help <command> - displays more detailed help "
"for the specific command"),
};
}

std::string CvdHelpHandler::TopLevelHelp() {
std::stringstream help_message;
help_message << kHelpIntroText;
std::vector<HelpParagraph> paragraphs;
paragraphs.emplace_back("Cuttlefish Virtual Device (CVD) CLI.");
paragraphs.emplace_back(
"Cuttlefish is a configurable virtual Android device offering "
"high-fidelity Android emulation for platform and app development, and "
"automated testing.");
Comment on lines +158 to +160

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"offering... and automated testing" is a bit odd. The device is especially convenient to use in an automated test, but the device isn't providing the test.


paragraphs.emplace_back(HelpParagraph::Raw(
R"(Device Organization:
Cuttlefish devices are organized into Instance Groups and Instances.
- An Instance represents a single virtual Android device.
- An Instance Group is a logical collection of one or more Instances created
and managed together.
- Group and Instance Naming:
- Each group and instance has a name. Names can be user-provided or
automatically generated by cvd.
- Group names must be unique across the host for the current user.
- Instance names must be unique within their containing group.)"));

paragraphs.emplace_back(HelpParagraph::Raw(
R"(Cuttlefish devices lifecycle:
- create: Cuttlefish devices must be "created" (`cvd create` command)
before they can be used. The instance group directory structure is created,
host resources like virtual networks and instance ids are allocated and
build artifacts are fetched during this step. Cuttlefish devices are
automatically started at the end of the creation process unless the user
passes the --nostart option.
- start|stop Turn the virtual devices ON or OFF respectively. These actions
can be performed repeatedly just like in a physical Android device. Virtual
device state and disks are preserved across a stop-start cycle.
- remove: The opposite of create, this action completely removes the
devices from the system. Logs and virtual disks in particular are deleted
during this step. Host resources, context ids and cuttlefish names are also
released.)"));

paragraphs.emplace_back(HelpParagraph::Raw(
R"(Selector Arguments:
Many commands act on an existing instance or group. If only one group or
instance exists, cvd will select that one as the command's target, otherwise
it will ask you to select one from a list. Selector options can be used
*before* the subcommand explicitly select a target and avoid the interactive
Comment on lines +194 to +195

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned lifting the requirement of passing selector options first, was that change made?

seleccion step:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

selection

cvd -group_name <group_name> <command>
cvd -instance_name <instance_name> <command>)"));

paragraphs.emplace_back("Build Fetching and Caching:");
paragraphs.emplace_back(
"cvd can automatically download Android builds from the Android Build "
"servers (e.g., "
"\"@ab/aosp-android-latest-release/"
"aosp_cf_x86_64_only_phone-userdebug\"). cvd fetches the required host "
"tools and device images, caching them locally to accelerate future "
"device creation.");

paragraphs.emplace_back(HelpParagraph::Raw(
R"(Usage:
cvd [selector/global options] <command> [args]
cvd help [<command> [args]])"));

std::stringstream help_message;
help_message << FormatHelpText(paragraphs);

help_message << "Global Options:\n";
std::string verbosity_val = "INFO";
std::vector<Flag> global_flags = {
GflagsCompatFlag("verbosity", verbosity_val)
.Help("Adjust Cvd verbosity level. LEVEL is one of ERROR, WARNING, "
"INFO, DEBUG, VERBOSE."),
};
help_message << FormatFlagsHelp(global_flags);

help_message << "Selector Options:\n";
selector::SelectorOptions dummy_selector_options;
auto selector_flags =
selector::BuildCommonSelectorFlags(dummy_selector_options);
help_message << FormatFlagsHelp(selector_flags);

help_message << "Commands (cvd help <command> for more information):\n\n";
for (const auto& handler : request_handlers_) {
if (!handler->RequiresDeviceExists()) {
PrintHandler(help_message, *handler);
}
}

help_message << kSelectorOptionsText;
help_message << "\nDevice-Specific Commands (cvd help <command> for more "
"information):\n";
help_message << "\n Device-Specific Commands (cvd help <command> for more "
"information):\n\n";
for (const auto& handler : request_handlers_) {
if (handler->RequiresDeviceExists()) {
PrintHandler(help_message, *handler);
}
}

help_message << FormatHelpText({HelpParagraph::Raw(kHelpExamplesText)});

return help_message.str();
}

Expand Down
3 changes: 1 addition & 2 deletions base/cvd/cuttlefish/host/commands/cvd/cli/commands/help.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ class CvdHelpHandler : public CvdCommandHandler {

std::string SummaryHelp() const override;
bool RequiresHostConfiguration() const override;
Result<std::string> DetailedHelp(
const CommandRequest& request) override;
std::vector<HelpParagraph> Description() const override;

private:
std::string TopLevelHelp();
Expand Down
Loading