diff options
author | Chad Reynolds <chadreynolds@google.com> | 2024-04-24 17:10:25 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-04-24 17:10:25 +0000 |
commit | 1294bb53b4ec148a21c258f03596343bdd030b1e (patch) | |
tree | f8ce8211c7961b34bbfdfeb1a9ada06a4b687fa9 /host | |
parent | 022bb1732c4b3594687731c1c1c7e6bd347f5305 (diff) | |
parent | 6526a9968b590a96d07934df1c8775dfa10f0665 (diff) | |
download | cuttlefish-1294bb53b4ec148a21c258f03596343bdd030b1e.tar.gz |
Merge changes Ie5738db2,I528e72c2 into main
* changes:
Continue CombineTargetFiles refactor
Clean up super_image_mixer
Diffstat (limited to 'host')
-rw-r--r-- | host/commands/assemble_cvd/flags.cc | 2 | ||||
-rw-r--r-- | host/commands/assemble_cvd/misc_info.cc | 34 | ||||
-rw-r--r-- | host/commands/assemble_cvd/misc_info.h | 4 | ||||
-rw-r--r-- | host/commands/assemble_cvd/super_image_mixer.cc | 260 |
4 files changed, 160 insertions, 140 deletions
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc index 6b86737f8..4a74ac5e7 100644 --- a/host/commands/assemble_cvd/flags.cc +++ b/host/commands/assemble_cvd/flags.cc @@ -543,7 +543,7 @@ Result<std::string> GetAndroidInfoConfig( CF_EXPECT(FileExists(android_info_file_path)); std::string android_info_contents = ReadFile(android_info_file_path); - auto android_info_map = ParseMiscInfo(android_info_contents); + auto android_info_map = CF_EXPECT(ParseMiscInfo(android_info_contents)); CF_EXPECT(android_info_map.find(key) != android_info_map.end()); return android_info_map[key]; } diff --git a/host/commands/assemble_cvd/misc_info.cc b/host/commands/assemble_cvd/misc_info.cc index e96099c4d..292258b96 100644 --- a/host/commands/assemble_cvd/misc_info.cc +++ b/host/commands/assemble_cvd/misc_info.cc @@ -16,14 +16,26 @@ #include "misc_info.h" #include <algorithm> +#include <string> +#include <vector> #include <android-base/logging.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include "common/libs/utils/contains.h" +#include "common/libs/utils/result.h" + namespace cuttlefish { +namespace { + +constexpr char kDynamicPartitions[] = "dynamic_partition_list"; +constexpr char kGoogleDynamicPartitions[] = "google_dynamic_partitions"; +constexpr char kSuperPartitionGroups[] = "super_partition_groups"; + +} // namespace -MiscInfo ParseMiscInfo(const std::string& misc_info_contents) { +Result<MiscInfo> ParseMiscInfo(const std::string& misc_info_contents) { auto lines = android::base::Split(misc_info_contents, "\n"); MiscInfo misc_info; for (auto& line : lines) { @@ -37,13 +49,13 @@ MiscInfo ParseMiscInfo(const std::string& misc_info_contents) { continue; } // Not using android::base::Split here to only capture the first = - auto key = android::base::Trim(line.substr(0, eq_pos)); - auto value = android::base::Trim(line.substr(eq_pos + 1)); - if (misc_info.find(key) != misc_info.end() && misc_info[key] != value) { - LOG(ERROR) << "Duplicate key: \"" << key << "\". First value: \"" - << misc_info[key] << "\", Second value: \"" << value << "\""; - return {}; - } + const auto key = android::base::Trim(line.substr(0, eq_pos)); + const auto value = android::base::Trim(line.substr(eq_pos + 1)); + const bool duplicate = Contains(misc_info, key) && misc_info[key] != value; + CF_EXPECTF(!duplicate, + "Duplicate key with different value. key:\"{}\", previous " + "value:\"{}\", this value:\"{}\"", + key, misc_info[key], value); misc_info[key] = value; } return misc_info; @@ -57,8 +69,6 @@ std::string WriteMiscInfo(const MiscInfo& misc_info) { return out.str(); } -static const std::string kDynamicPartitions = "dynamic_partition_list"; - std::vector<std::string> SuperPartitionComponents(const MiscInfo& info) { auto value_it = info.find(kDynamicPartitions); if (value_it == info.end()) { @@ -73,10 +83,6 @@ std::vector<std::string> SuperPartitionComponents(const MiscInfo& info) { return components; } -static constexpr const char* kGoogleDynamicPartitions = - "google_dynamic_partitions"; -static constexpr const char* kSuperPartitionGroups = "super_partition_groups"; - bool SetSuperPartitionComponents(const std::vector<std::string>& components, MiscInfo* misc_info) { auto super_partition_groups = misc_info->find(kSuperPartitionGroups); diff --git a/host/commands/assemble_cvd/misc_info.h b/host/commands/assemble_cvd/misc_info.h index aa130bcc9..f832a4c5f 100644 --- a/host/commands/assemble_cvd/misc_info.h +++ b/host/commands/assemble_cvd/misc_info.h @@ -19,11 +19,13 @@ #include <string> #include <vector> +#include "common/libs/utils/result.h" + namespace cuttlefish { using MiscInfo = std::map<std::string, std::string>; -MiscInfo ParseMiscInfo(const std::string& file_contents); +Result<MiscInfo> ParseMiscInfo(const std::string& file_contents); std::string WriteMiscInfo(const MiscInfo& info); std::vector<std::string> SuperPartitionComponents(const MiscInfo&); diff --git a/host/commands/assemble_cvd/super_image_mixer.cc b/host/commands/assemble_cvd/super_image_mixer.cc index 8f445310a..b59d163fb 100644 --- a/host/commands/assemble_cvd/super_image_mixer.cc +++ b/host/commands/assemble_cvd/super_image_mixer.cc @@ -30,6 +30,7 @@ #include "common/libs/utils/archive.h" #include "common/libs/utils/contains.h" #include "common/libs/utils/files.h" +#include "common/libs/utils/result.h" #include "common/libs/utils/subprocess.h" #include "host/commands/assemble_cvd/misc_info.h" #include "host/libs/config/config_utils.h" @@ -37,59 +38,8 @@ #include "host/libs/config/fetcher_config.h" namespace cuttlefish { - -Result<bool> SuperImageNeedsRebuilding(const FetcherConfig& fetcher_config, - const std::string& default_target_zip, - const std::string& system_target_zip) { - bool has_default_target_zip = false; - bool has_system_target_zip = false; - if (default_target_zip != "" && - default_target_zip != "unset") { - has_default_target_zip = true; - } - if (system_target_zip != "" && - system_target_zip != "unset") { - has_system_target_zip = true; - } - CF_EXPECT(has_default_target_zip == has_system_target_zip, - "default_target_zip and system_target_zip " - "flags must be specified together"); - // at this time, both should be the same, either true or false - // therefore, I only check one variable - if (has_default_target_zip) { - return true; - } - - bool has_default_build = false; - bool has_system_build = false; - for (const auto& file_iter : fetcher_config.get_cvd_files()) { - if (file_iter.second.source == FileSource::DEFAULT_BUILD) { - has_default_build = true; - } else if (file_iter.second.source == FileSource::SYSTEM_BUILD) { - has_system_build = true; - } - } - return has_default_build && has_system_build; -} - namespace { -std::string TargetFilesZip(const FetcherConfig& fetcher_config, - FileSource source) { - for (const auto& file_iter : fetcher_config.get_cvd_files()) { - const auto& file_path = file_iter.first; - const auto& file_info = file_iter.second; - if (file_info.source != source) { - continue; - } - std::string expected_filename = "target_files-" + file_iter.second.build_id; - if (file_path.find(expected_filename) != std::string::npos) { - return file_path; - } - } - return ""; -} - constexpr char kMiscInfoPath[] = "META/misc_info.txt"; constexpr std::array kVendorTargetImages = { "IMAGES/boot.img", @@ -115,6 +65,13 @@ constexpr std::array kVendorTargetBuildProps = { "VENDOR/etc/build.prop", }; +struct TargetFiles { + Archive vendor_zip; + Archive system_zip; + std::vector<std::string> vendor_contents; + std::vector<std::string> system_contents; +}; + void FindImports(Archive* archive, const std::string& build_prop_file) { auto contents = archive->ExtractToMemory(build_prop_file); auto lines = android::base::Split(contents, "\n"); @@ -126,119 +83,126 @@ void FindImports(Archive* archive, const std::string& build_prop_file) { } } -Result<void> CombineTargetZipFiles(const std::string& default_target_zip, - const std::string& system_target_zip, - const std::string& output_path) { - Archive default_target_archive(default_target_zip); - auto default_target_contents = default_target_archive.Contents(); - CF_EXPECT(default_target_contents.size() != 0, - "Could not open " << default_target_zip); - - Archive system_target_archive(system_target_zip); - auto system_target_contents = system_target_archive.Contents(); - CF_EXPECT(system_target_contents.size() != 0, - "Could not open " << system_target_zip); - - CF_EXPECT( - mkdir(output_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) >= 0, - "Could not create directory " << output_path); - - std::string output_meta = output_path + "/META"; - CF_EXPECT( - mkdir(output_meta.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) >= 0, - "Could not create directory " << output_meta); - - CF_EXPECT( - std::find(default_target_contents.begin(), default_target_contents.end(), - kMiscInfoPath) != default_target_contents.end(), - "Default target files zip does not have " << kMiscInfoPath); - - CF_EXPECT( - std::find(system_target_contents.begin(), system_target_contents.end(), - kMiscInfoPath) != system_target_contents.end(), - "System target files zip does not have " << kMiscInfoPath); - - const auto default_misc = - ParseMiscInfo(default_target_archive.ExtractToMemory(kMiscInfoPath)); - CF_EXPECT(default_misc.size() != 0, - "Could not read the default misc_info.txt file."); - - const auto system_misc = - ParseMiscInfo(system_target_archive.ExtractToMemory(kMiscInfoPath)); - CF_EXPECT(system_misc.size() != 0, - "Could not read the system misc_info.txt file."); +bool IsTargetFilesImage(const std::string& filename) { + return android::base::StartsWith(filename, "IMAGES/") && + android::base::EndsWith(filename, ".img"); +} + +bool IsTargetFilesBuildProp(const std::string& filename) { + return android::base::EndsWith(filename, "build.prop"); +} + +Result<TargetFiles> GetTargetFiles(const std::string& vendor_zip_path, + const std::string& system_zip_path) { + auto result = TargetFiles{ + .vendor_zip = Archive(vendor_zip_path), + .system_zip = Archive(system_zip_path), + }; + result.vendor_contents = result.vendor_zip.Contents(); + result.system_contents = result.system_zip.Contents(); + CF_EXPECTF(!result.vendor_contents.empty(), "Could not open {}", + vendor_zip_path); + CF_EXPECTF(!result.system_contents.empty(), "Could not open {}", + system_zip_path); + return result; +} + +Result<void> CombineMiscInfo(TargetFiles& target_files, + const std::string& misc_output_path) { + CF_EXPECTF(Contains(target_files.vendor_contents, kMiscInfoPath), + "Default target files zip does not contain {}", kMiscInfoPath); + CF_EXPECTF(Contains(target_files.system_contents, kMiscInfoPath), + "System target files zip does not contain {}", kMiscInfoPath); + + const MiscInfo default_misc = CF_EXPECT( + ParseMiscInfo(target_files.vendor_zip.ExtractToMemory(kMiscInfoPath))); + const MiscInfo system_misc = CF_EXPECT( + ParseMiscInfo(target_files.system_zip.ExtractToMemory(kMiscInfoPath))); auto output_misc = default_misc; auto system_super_partitions = SuperPartitionComponents(system_misc); // Ensure specific skipped partitions end up in the misc_info.txt for (auto partition : {"odm", "odm_dlkm", "vendor", "vendor_dlkm", "system_dlkm"}) { - if (std::find(system_super_partitions.begin(), system_super_partitions.end(), - partition) == system_super_partitions.end()) { + if (!Contains(system_super_partitions, partition)) { system_super_partitions.push_back(partition); } } CF_EXPECT(SetSuperPartitionComponents(system_super_partitions, &output_misc), "Failed to update super partitions components for misc_info"); - auto misc_output_path = output_path + "/" + kMiscInfoPath; - SharedFD misc_output_file = - SharedFD::Creat(misc_output_path.c_str(), 0644); + SharedFD misc_output_file = SharedFD::Creat(misc_output_path.c_str(), 0644); CF_EXPECT(misc_output_file->IsOpen(), "Failed to open output misc file: " << misc_output_file->StrError()); CF_EXPECT(WriteAll(misc_output_file, WriteMiscInfo(output_misc)) >= 0, "Failed to write output misc file contents: " << misc_output_file->StrError()); + return {}; +} - for (const auto& name : default_target_contents) { - if (!android::base::StartsWith(name, "IMAGES/")) { - continue; - } else if (!android::base::EndsWith(name, ".img")) { +Result<void> ExtractTargetFiles(TargetFiles& target_files, + const std::string& combined_output_path) { + for (const auto& name : target_files.vendor_contents) { + if (!IsTargetFilesImage(name)) { continue; } else if (!Contains(kVendorTargetImages, name)) { continue; } - LOG(INFO) << "Writing " << name; - CF_EXPECT(default_target_archive.ExtractFiles({name}, output_path), - "Failed to extract " << name << " from the default target zip"); + LOG(INFO) << "Writing " << name << " from vendor target"; + CF_EXPECT( + target_files.vendor_zip.ExtractFiles({name}, combined_output_path), + "Failed to extract " << name << " from the vendor target zip"); } - for (const auto& name : default_target_contents) { - if (!android::base::EndsWith(name, "build.prop")) { + for (const auto& name : target_files.vendor_contents) { + if (!IsTargetFilesBuildProp(name)) { continue; } else if (!Contains(kVendorTargetBuildProps, name)) { continue; } - FindImports(&default_target_archive, name); - LOG(INFO) << "Writing " << name; - CF_EXPECT(default_target_archive.ExtractFiles({name}, output_path), - "Failed to extract " << name << " from the default target zip"); + FindImports(&target_files.vendor_zip, name); + LOG(INFO) << "Writing " << name << " from vendor target"; + CF_EXPECT( + target_files.vendor_zip.ExtractFiles({name}, combined_output_path), + "Failed to extract " << name << " from the vendor target zip"); } - for (const auto& name : system_target_contents) { - if (!android::base::StartsWith(name, "IMAGES/")) { - continue; - } else if (!android::base::EndsWith(name, ".img")) { + for (const auto& name : target_files.system_contents) { + if (!IsTargetFilesImage(name)) { continue; } else if (Contains(kVendorTargetImages, name)) { continue; } - LOG(INFO) << "Writing " << name; - CF_EXPECT(system_target_archive.ExtractFiles({name}, output_path), - "Failed to extract " << name << " from the system target zip"); + LOG(INFO) << "Writing " << name << " from system target"; + CF_EXPECT( + target_files.system_zip.ExtractFiles({name}, combined_output_path), + "Failed to extract " << name << " from the system target zip"); } - for (const auto& name : system_target_contents) { - if (!android::base::EndsWith(name, "build.prop")) { + for (const auto& name : target_files.system_contents) { + if (!IsTargetFilesBuildProp(name)) { continue; } else if (Contains(kVendorTargetBuildProps, name)) { continue; } - FindImports(&system_target_archive, name); - LOG(INFO) << "Writing " << name; - CF_EXPECT(system_target_archive.ExtractFiles({name}, output_path), - "Failed to extract " << name << " from the default target zip"); + FindImports(&target_files.system_zip, name); + LOG(INFO) << "Writing " << name << " from system target"; + CF_EXPECT( + target_files.system_zip.ExtractFiles({name}, combined_output_path), + "Failed to extract " << name << " from the system target zip"); } + return {}; +} +Result<void> CombineTargetZipFiles(const std::string& vendor_zip_path, + const std::string& system_zip_path, + const std::string& output_path) { + CF_EXPECT(EnsureDirectoryExists(output_path)); + CF_EXPECT(EnsureDirectoryExists(output_path + "/META")); + auto target_files = + CF_EXPECT(GetTargetFiles(vendor_zip_path, system_zip_path)); + CF_EXPECT(ExtractTargetFiles(target_files, output_path)); + const auto misc_output_path = output_path + "/" + kMiscInfoPath; + CF_EXPECT(CombineMiscInfo(target_files, misc_output_path)); return {}; } @@ -258,6 +222,22 @@ bool BuildSuperImage(const std::string& combined_target_zip, }) == 0; } +std::string TargetFilesZip(const FetcherConfig& fetcher_config, + FileSource source) { + for (const auto& file_iter : fetcher_config.get_cvd_files()) { + const auto& file_path = file_iter.first; + const auto& file_info = file_iter.second; + if (file_info.source != source) { + continue; + } + std::string expected_filename = "target_files-" + file_iter.second.build_id; + if (file_path.find(expected_filename) != std::string::npos) { + return file_path; + } + } + return ""; +} + Result<void> RebuildSuperImage(const FetcherConfig& fetcher_config, const CuttlefishConfig& config, const std::string& output_path) { @@ -319,6 +299,38 @@ class SuperImageRebuilderImpl : public SuperImageRebuilder { } // namespace +Result<bool> SuperImageNeedsRebuilding(const FetcherConfig& fetcher_config, + const std::string& default_target_zip, + const std::string& system_target_zip) { + bool has_default_target_zip = false; + bool has_system_target_zip = false; + if (default_target_zip != "" && default_target_zip != "unset") { + has_default_target_zip = true; + } + if (system_target_zip != "" && system_target_zip != "unset") { + has_system_target_zip = true; + } + CF_EXPECT(has_default_target_zip == has_system_target_zip, + "default_target_zip and system_target_zip " + "flags must be specified together"); + // at this time, both should be the same, either true or false + // therefore, I only check one variable + if (has_default_target_zip) { + return true; + } + + bool has_default_build = false; + bool has_system_build = false; + for (const auto& file_iter : fetcher_config.get_cvd_files()) { + if (file_iter.second.source == FileSource::DEFAULT_BUILD) { + has_default_build = true; + } else if (file_iter.second.source == FileSource::SYSTEM_BUILD) { + has_system_build = true; + } + } + return has_default_build && has_system_build; +} + fruit::Component<fruit::Required<const FetcherConfig, const CuttlefishConfig, const CuttlefishConfig::InstanceSpecific>, SuperImageRebuilder> @@ -328,4 +340,4 @@ SuperImageRebuilderComponent() { .addMultibinding<SetupFeature, SuperImageRebuilder>(); } -} // namespace cuttlefish +} // namespace cuttlefish |