From 2d985ecd13c8d28c085751fcf4fef0ba42997f91 Mon Sep 17 00:00:00 2001 From: My Name Date: Thu, 28 May 2026 13:01:01 +0000 Subject: [PATCH] feat(backend): Update cvd start to handle single instances --- .../commands/cvd/cli/commands/BUILD.bazel | 1 + .../host/commands/cvd/cli/commands/start.cpp | 86 ++++++++++++++++++- .../host/commands/cvd/cli/commands/start.h | 4 + 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel index e27d3cf39db..0afa1f8bba1 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/BUILD.bazel @@ -419,6 +419,7 @@ cf_cc_library( srcs = ["start.cpp"], hdrs = ["start.h"], deps = [ + "//cuttlefish/common/libs/fs", "//cuttlefish/common/libs/utils:contains", "//cuttlefish/common/libs/utils:files", "//cuttlefish/common/libs/utils:flag_parser", diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp index a1f32dea81f..1825401fe6e 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,7 @@ #include "absl/strings/str_join.h" #include "absl/strings/str_split.h" +#include "cuttlefish/common/libs/fs/shared_fd.h" #include "cuttlefish/common/libs/utils/contains.h" #include "cuttlefish/common/libs/utils/files.h" #include "cuttlefish/common/libs/utils/flag_parser.h" @@ -314,7 +316,8 @@ Result> GetCvdInternalStartFlags( CvdStartCommandHandler::CvdStartCommandHandler( InstanceManager& instance_manager) - : instance_manager_(instance_manager) {} + : instance_manager_(instance_manager) { +} static Result ConsumeDaemonModeFlag(cvd_common::Args& args) { Flag flag = @@ -368,6 +371,19 @@ Result CvdStartCommandHandler::Handle(const CommandRequest& request) { return CF_ERR(NoGroupMessage(request)); } + if (request.Selectors().instance_names) { + auto [instance, group] = + CF_EXPECT(selector::SelectInstance(instance_manager_, request)); + + auto config_path = + group.AssemblyDir() + "/cuttlefish_config.json"; + if (FileExists(config_path)) { + return LaunchSingleInstance(instance, group, request); + } else { + LOG(INFO) << "Group configuration does not exist on disk. Proceeding with normal group start."; + } + } + CF_EXPECT(ConsumeDaemonModeFlag(subcmd_args)); subcmd_args.push_back("--daemon=true"); @@ -508,6 +524,74 @@ Result CvdStartCommandHandler::LaunchDeviceInterruptible( return {}; } +Result CvdStartCommandHandler::LaunchSingleInstance( + LocalInstance& instance, LocalInstanceGroup& group, + const CommandRequest& request) { + auto bin_path = group.HostArtifactsPath() + "/bin/run_cvd"; + cvd_common::Envs run_cvd_envs = request.Env(); + run_cvd_envs[kCuttlefishInstanceEnvVarName] = std::to_string(instance.id()); + run_cvd_envs["HOME"] = group.HomeDir(); + run_cvd_envs[kAndroidHostOut] = group.HostArtifactsPath(); + run_cvd_envs[kAndroidProductOut] = group.ProductOutPath(); + run_cvd_envs[kAndroidSoongHostOut] = group.HostArtifactsPath(); + run_cvd_envs[kCvdMarkEnv] = "true"; + + ConstructCommandParam construct_cmd_param{.bin_path = bin_path, + .home = group.HomeDir(), + .args = cvd_common::Args{}, + .envs = run_cvd_envs, + .working_dir = CurrentDirectory(), + .command_name = "run_cvd"}; + + Command command = CF_EXPECT(ConstructCommand(construct_cmd_param)); + command.RedirectStdIO(Subprocess::StdIOChannel::kStdOut, + Subprocess::StdIOChannel::kStdErr); + SharedFD dev_null = SharedFD::Open("/dev/null", O_RDONLY); + if (dev_null->IsOpen()) { + command.RedirectStdIO(Subprocess::StdIOChannel::kStdIn, dev_null); + } else { + LOG(ERROR) << "Failed to open /dev/null: " << dev_null->StrError(); + } + + auto symlink_config_res = SymlinkPreviousConfig(group.HomeDir()); + if (!symlink_config_res.ok()) { + LOG(ERROR) << "Failed to symlink the config file at system wide home: " + << symlink_config_res.error(); + } + + auto set_instance_state = [&group, &instance](cvd::InstanceState state) { + for (auto& inst : group.Instances()) { + if (inst.id() == instance.id()) { + inst.set_state(state); + break; + } + } + }; + + set_instance_state(cvd::INSTANCE_STATE_STARTING); + group.SetStartTime(CvdServerClock::now()); + CF_EXPECT(instance_manager_.UpdateInstanceGroup(group)); + + Result start_res = + LaunchDevice(std::move(command), group, run_cvd_envs, request); + + if (!start_res.ok()) { + set_instance_state(cvd::INSTANCE_STATE_BOOT_FAILED); + CF_EXPECT(instance_manager_.UpdateInstanceGroup(group)); + return start_res; + } + + set_instance_state(cvd::INSTANCE_STATE_RUNNING); + CF_EXPECT(instance_manager_.UpdateInstanceGroup(group)); + + auto group_json = CF_EXPECT(group.FetchStatus()); + std::cout << group_json.toStyledString(); + + return {}; +} + + + std::vector CvdStartCommandHandler::Description() const { std::vector description; description.emplace_back( diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.h b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.h index 8091f4306e3..d913c91370a 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.h +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/start.h @@ -43,6 +43,10 @@ class CvdStartCommandHandler : public CvdCommandHandler { bool RequiresDeviceExists() const override { return true; } private: + Result LaunchSingleInstance(LocalInstance& instance, + LocalInstanceGroup& group, + const CommandRequest& request); + Result LaunchDevice(Command command, LocalInstanceGroup& group, const cvd_common::Envs& envs, const CommandRequest& request);