Skip to content

Commit 3a91c38

Browse files
committed
Attach fetch.log to cvd bugreports
When available. The file is usually at the same location as the system images (when using cvd fetch) or in its parent (when using cvd load). Bug: b/434224140
1 parent 498749e commit 3a91c38

File tree

2 files changed

+84
-13
lines changed

2 files changed

+84
-13
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ cf_cc_library(
8080
"//cuttlefish/host/commands/cvd/cli/selector",
8181
"//cuttlefish/host/commands/cvd/instances",
8282
"//cuttlefish/host/commands/cvd/utils",
83+
"//cuttlefish/host/libs/zip:zip_cc",
84+
"//cuttlefish/host/libs/zip:zip_file",
85+
"//libbase",
8386
"@fmt",
8487
],
8588
)

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

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@
2222
#include <functional>
2323
#include <memory>
2424
#include <string>
25+
#include <utility>
2526
#include <vector>
2627

2728
#include <fmt/core.h>
2829

30+
#include "android-base/file.h"
31+
#include "android-base/logging.h"
2932
#include "cuttlefish/common/libs/utils/files.h"
3033
#include "cuttlefish/common/libs/utils/flag_parser.h"
3134
#include "cuttlefish/common/libs/utils/result.h"
@@ -37,20 +40,59 @@
3740
#include "cuttlefish/host/commands/cvd/cli/selector/selector.h"
3841
#include "cuttlefish/host/commands/cvd/cli/types.h"
3942
#include "cuttlefish/host/commands/cvd/cli/utils.h"
43+
#include "cuttlefish/host/commands/cvd/instances/instance_group_record.h"
4044
#include "cuttlefish/host/commands/cvd/instances/instance_manager.h"
4145
#include "cuttlefish/host/commands/cvd/utils/common.h"
46+
#include "cuttlefish/host/libs/zip/zip_cc.h"
47+
#include "cuttlefish/host/libs/zip/zip_file.h"
4248

4349
namespace cuttlefish {
4450
namespace {
4551

4652
constexpr char kSummaryHelpText[] =
4753
"Run cvd bugreport --help for command description";
4854

55+
// Accepts a copy of the args to not modify the original.
56+
Result<std::string> OutputFileFromArgs(cvd_common::Args args) {
57+
// This flag must match the one defined in
58+
// //cuttlefish/host/commands/host_bugreport/main.cc
59+
std::string output = "host_bugreport.zip";
60+
std::vector<Flag> flags = {
61+
GflagsCompatFlag("output", output),
62+
};
63+
CF_EXPECT(ConsumeFlags(flags, args));
64+
return output;
65+
}
66+
67+
Result<void> AddFetchLogIfPresent(const LocalInstanceGroup& instance_group,
68+
const std::string& output_file) {
69+
std::string fetch_log_path = instance_group.ProductOutPath() + "/fetch.log";
70+
if (!FileExists(fetch_log_path)) {
71+
// The fetch log is in the parent of the host artifacts path when cvd create
72+
// --config_file was used.
73+
fetch_log_path =
74+
android::base::Dirname(instance_group.HostArtifactsPath()) +
75+
"/fetch.log";
76+
}
77+
if (!FileExists(fetch_log_path)) {
78+
// There will be no fetch log when running from local sources
79+
return {};
80+
}
81+
LOG(INFO) << "Attaching fetch.log to report";
82+
WritableZip archive = CF_EXPECT(ZipOpenReadWrite(output_file));
83+
CF_EXPECT(AddFileAt(archive, fetch_log_path, "fetch.log"));
84+
CF_EXPECT(WritableZip::Finalize(std::move(archive)));
85+
return {};
86+
}
87+
4988
class CvdBugreportCommandHandler : public CvdCommandHandler {
5089
public:
5190
CvdBugreportCommandHandler(InstanceManager& instance_manager);
5291

5392
Result<void> Handle(const CommandRequest& request) override;
93+
Result<void> HandleHelp(const cvd_common::Envs& env,
94+
const cvd_common::Args& cmd_args,
95+
const CommandRequest& request);
5496
cvd_common::Args CmdList() const override;
5597
Result<std::string> SummaryHelp() const override;
5698
bool ShouldInterceptHelp() const override;
@@ -77,19 +119,24 @@ Result<void> CvdBugreportCommandHandler::Handle(const CommandRequest& request) {
77119

78120
std::string android_host_out;
79121
std::string home = CF_EXPECT(SystemWideUserHome());
80-
if (!CF_EXPECT(HasHelpFlag(cmd_args))) {
81-
bool has_instance_groups = CF_EXPECT(instance_manager_.HasInstanceGroups());
82-
CF_EXPECTF(!!has_instance_groups, "{}", NoGroupMessage(request));
83-
84-
auto instance_group =
85-
CF_EXPECT(selector::SelectGroup(instance_manager_, request));
86-
android_host_out = instance_group.HostArtifactsPath();
87-
home = instance_group.HomeDir();
88-
env["HOME"] = home;
89-
env[kAndroidHostOut] = android_host_out;
90-
} else {
91-
android_host_out = CF_EXPECT(AndroidHostPath(env));
122+
123+
if (CF_EXPECT(HasHelpFlag(cmd_args))) {
124+
CF_EXPECT(HandleHelp(env, cmd_args, request));
125+
return {};
92126
}
127+
128+
std::string output_file =
129+
CF_EXPECT(OutputFileFromArgs(cmd_args), "Failed to parse output flag");
130+
131+
bool has_instance_groups = CF_EXPECT(instance_manager_.HasInstanceGroups());
132+
CF_EXPECTF(!!has_instance_groups, "{}", NoGroupMessage(request));
133+
134+
auto instance_group =
135+
CF_EXPECT(selector::SelectGroup(instance_manager_, request));
136+
android_host_out = instance_group.HostArtifactsPath();
137+
home = instance_group.HomeDir();
138+
env["HOME"] = home;
139+
env[kAndroidHostOut] = android_host_out;
93140
auto bin_path = ConcatToString(android_host_out, "/bin/", kHostBugreportBin);
94141

95142
ConstructCommandParam construct_cmd_param{.bin_path = bin_path,
@@ -100,11 +147,32 @@ Result<void> CvdBugreportCommandHandler::Handle(const CommandRequest& request) {
100147
.command_name = kHostBugreportBin};
101148
Command command = CF_EXPECT(ConstructCommand(construct_cmd_param));
102149

150+
// Wait for the command to finish but ignore the result. The command will fail
151+
// for reasons like the device failing to initialize the home directory or
152+
// errors during fetch, which are still debuggable states that require a
153+
// report.
154+
(void)command.Start().Wait();
155+
156+
auto result = AddFetchLogIfPresent(instance_group, output_file);
157+
if (!result.ok()) {
158+
LOG(ERROR) << "Failed to add fetch log to bugreport: "
159+
<< result.error().FormatForEnv();
160+
}
161+
162+
return {};
163+
}
164+
165+
Result<void> CvdBugreportCommandHandler::HandleHelp(
166+
const cvd_common::Envs& env, const cvd_common::Args& cmd_args,
167+
const CommandRequest& request) {
168+
std::string android_host_out = CF_EXPECT(AndroidHostPath(env));
169+
Command command = CF_EXPECT(
170+
ConstructCvdHelpCommand(kHostBugreportBin, env, cmd_args, request));
171+
103172
siginfo_t infop; // NOLINT(misc-include-cleaner)
104173
command.Start().Wait(&infop, WEXITED);
105174

106175
CF_EXPECT(CheckProcessExitedNormally(infop));
107-
108176
return {};
109177
}
110178

0 commit comments

Comments
 (0)