Skip to content

Commit 7b92ba6

Browse files
committed
Add metadata extraction from the target files zip
Bug: b/471268335
1 parent 00ee244 commit 7b92ba6

File tree

3 files changed

+200
-0
lines changed

3 files changed

+200
-0
lines changed

base/cvd/cuttlefish/host/commands/assemble_cvd/android_build/BUILD.bazel

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,23 @@ cf_cc_library(
7777
"@fmt",
7878
],
7979
)
80+
81+
cf_cc_library(
82+
name = "target_files",
83+
srcs = ["target_files.cc"],
84+
hdrs = ["target_files.h"],
85+
deps = [
86+
"//cuttlefish/common/libs/key_equals_value",
87+
"//cuttlefish/host/commands/assemble_cvd/android_build",
88+
"//cuttlefish/host/commands/assemble_cvd/android_build:combined_android_build",
89+
"//cuttlefish/host/commands/assemble_cvd/android_build:find_build_archive",
90+
"//cuttlefish/host/commands/assemble_cvd/android_build:misc_info_metadata",
91+
"//cuttlefish/host/libs/config:build_archive",
92+
"//cuttlefish/host/libs/config:fetcher_config",
93+
"//cuttlefish/host/libs/config:file_source",
94+
"//cuttlefish/result",
95+
"@abseil-cpp//absl/strings",
96+
"@abseil-cpp//absl/strings:str_format",
97+
"@fmt",
98+
],
99+
)
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//
2+
// Copyright (C) 2025 The Android Open Source Project
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
#include "cuttlefish/host/commands/assemble_cvd/android_build/target_files.h"
17+
18+
#include <functional>
19+
#include <map>
20+
#include <memory>
21+
#include <optional>
22+
#include <ostream>
23+
#include <set>
24+
#include <string>
25+
#include <string_view>
26+
#include <utility>
27+
#include <vector>
28+
29+
#include "absl/strings/str_cat.h"
30+
#include "absl/strings/str_split.h"
31+
#include "absl/strings/strip.h"
32+
#include "cuttlefish/host/commands/assemble_cvd/android_build/combined_android_build.h"
33+
#include "fmt/ostream.h"
34+
35+
#include "cuttlefish/common/libs/key_equals_value/key_equals_value.h"
36+
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_build.h"
37+
#include "cuttlefish/host/commands/assemble_cvd/android_build/find_build_archive.h"
38+
#include "cuttlefish/host/commands/assemble_cvd/android_build/misc_info_metadata.h"
39+
#include "cuttlefish/host/libs/config/build_archive.h"
40+
#include "cuttlefish/host/libs/config/fetcher_config.h"
41+
#include "cuttlefish/host/libs/config/file_source.h"
42+
#include "cuttlefish/result/result.h"
43+
44+
namespace cuttlefish {
45+
namespace {
46+
47+
static constexpr std::string_view kTargetFilesMatch = "-target_files-";
48+
static constexpr std::string_view kImgSuffix = ".img";
49+
50+
class TargetFilesImpl : public AndroidBuild {
51+
public:
52+
static Result<std::unique_ptr<TargetFilesImpl>> FromBuildArchive(
53+
BuildArchive archive) {
54+
TargetFilesImpl target_files(std::move(archive));
55+
56+
CF_EXPECT(!target_files.archive_.Members().empty());
57+
58+
return std::make_unique<TargetFilesImpl>(std::move(target_files));
59+
}
60+
61+
Result<std::map<std::string, std::string>> MiscInfo() {
62+
static constexpr std::string_view kMiscInfoTxt = "META/misc_info.txt";
63+
std::string contents = CF_EXPECT(archive_.MemberContents(kMiscInfoTxt));
64+
return CF_EXPECT(ParseKeyEqualsValue(contents));
65+
}
66+
67+
// Image files are stored as `IMAGES/*.img` archive members.
68+
Result<std::set<std::string, std::less<void>>> Images() override {
69+
std::set<std::string, std::less<void>> partitions;
70+
for (std::string_view member : archive_.Members()) {
71+
if (!absl::ConsumeSuffix(&member, kImgSuffix)) {
72+
continue;
73+
}
74+
absl::ConsumePrefix(&member, "/");
75+
if (!absl::ConsumePrefix(&member, "IMAGES/")) {
76+
continue;
77+
}
78+
partitions.emplace(member);
79+
}
80+
return partitions;
81+
}
82+
83+
Result<std::string> ImageFile(
84+
std::string_view name,
85+
std::optional<std::string_view> extract_dir) override {
86+
std::string member_name = absl::StrCat(name, kImgSuffix);
87+
return CF_EXPECT(archive_.MemberFilepath(member_name, extract_dir));
88+
}
89+
90+
Result<std::set<std::string, std::less<void>>> AbPartitions() override {
91+
static constexpr std::string_view kAbTxt = "META/ab_partitions.txt";
92+
std::string contents = CF_EXPECT(archive_.MemberContents(kAbTxt));
93+
return absl::StrSplit(contents, "\n", absl::SkipEmpty());
94+
}
95+
96+
private:
97+
TargetFilesImpl(BuildArchive archive) : archive_(std::move(archive)) {}
98+
99+
// The `META/ab_partitions.txt` archive member has one entry per line.
100+
101+
std::ostream& Format(std::ostream& out) const override {
102+
fmt::print(out, "TargetFiles {{ {} }}", archive_);
103+
return out;
104+
}
105+
106+
BuildArchive archive_;
107+
};
108+
109+
Result<std::unique_ptr<AndroidBuild>> TargetFiles(BuildArchive archive) {
110+
std::unique_ptr<TargetFilesImpl> target =
111+
CF_EXPECT(TargetFilesImpl::FromBuildArchive(std::move(archive)));
112+
113+
std::map<std::string, std::string> misc_info = CF_EXPECT(target->MiscInfo());
114+
115+
std::unique_ptr<AndroidBuild> misc_info_build =
116+
CF_EXPECT(AndroidBuildFromMiscInfo(std::move(misc_info)));
117+
118+
std::vector<std::unique_ptr<AndroidBuild>> builds;
119+
builds.emplace_back(std::move(target));
120+
builds.emplace_back(std::move(misc_info_build));
121+
return CF_EXPECT(CombinedAndroidBuild("TargetFiles", std::move(builds)));
122+
}
123+
124+
} // namespace
125+
126+
Result<std::unique_ptr<AndroidBuild>> TargetFiles(const FetcherConfig& config,
127+
FileSource source) {
128+
BuildArchive archive =
129+
CF_EXPECT(FindBuildArchive(config, source, kTargetFilesMatch));
130+
return CF_EXPECT(TargetFiles(std::move(archive)));
131+
}
132+
133+
Result<std::unique_ptr<AndroidBuild>> TargetFiles(const std::string& path) {
134+
BuildArchive archive = CF_EXPECT(FindBuildArchive(path, kTargetFilesMatch));
135+
return CF_EXPECT(TargetFiles(std::move(archive)));
136+
}
137+
138+
} // namespace cuttlefish
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//
2+
// Copyright (C) 2025 The Android Open Source Project
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
#pragma once
17+
18+
#include <memory>
19+
#include <string>
20+
21+
#include "cuttlefish/host/commands/assemble_cvd/android_build/android_build.h"
22+
#include "cuttlefish/host/libs/config/fetcher_config.h"
23+
#include "cuttlefish/host/libs/config/file_source.h"
24+
#include "cuttlefish/result/result.h"
25+
26+
namespace cuttlefish {
27+
28+
/**
29+
* Finds Android build artifacts from a *-target_files-* zip file downloaded and
30+
* possibly extracted by `cvd fetch`.
31+
*/
32+
Result<std::unique_ptr<AndroidBuild>> TargetFiles(const FetcherConfig&,
33+
FileSource);
34+
35+
/**
36+
* Finds android build artifacts from a *-target_files-* zip file that is
37+
* present in a directory, likely the `out/dist` directory of a local Android
38+
* build.
39+
*/
40+
Result<std::unique_ptr<AndroidBuild>> TargetFiles(const std::string& path);
41+
42+
} // namespace cuttlefish

0 commit comments

Comments
 (0)