Implement the TargetFile and BuildInfo
The TargetFile class parses a target-file and provides functions to read
its contents. And the BuildInfo tries to simulate the device with files
on host. Some work it does includes parsing the build properties,
and extracting the image files for partitions specified in the fstab.
Bug: 131911365
Test: unit tests pass, run simulator with cuttlefish, wear devices and from extracted TF.
Change-Id: Iefe4a96d619d2e4b3d038e31480f11a0f9a70afa
diff --git a/updater/include/updater/build_info.h b/updater/include/updater/build_info.h
new file mode 100644
index 0000000..a1355e8
--- /dev/null
+++ b/updater/include/updater/build_info.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <list>
+#include <map>
+#include <string>
+#include <string_view>
+
+#include <android-base/file.h>
+
+// This class serves as the aggregation of the fake block device information during update
+// simulation on host. In specific, it has the name of the block device, its mount point, and the
+// path to the temporary file that fakes this block device.
+class FakeBlockDevice {
+ public:
+ FakeBlockDevice(std::string block_device, std::string mount_point, std::string temp_file_path)
+ : blockdev_name(std::move(block_device)),
+ mount_point(std::move(mount_point)),
+ mounted_file_path(std::move(temp_file_path)) {}
+
+ std::string blockdev_name;
+ std::string mount_point;
+ std::string mounted_file_path; // path to the temp file that mocks the block device
+};
+
+// This class stores the information of the source build. For example, it creates and maintains
+// the temporary files to simulate the block devices on host. Therefore, the simulator runtime can
+// query the information and run the update on host.
+class BuildInfo {
+ public:
+ explicit BuildInfo(const std::string_view work_dir) : work_dir_(work_dir) {}
+ // Returns the value of the build properties.
+ std::string GetProperty(const std::string_view key, const std::string_view default_value) const;
+ // Returns the path to the mock block device.
+ std::string FindBlockDeviceName(const std::string_view name) const;
+ // Parses the given target-file, initializes the build properties and extracts the images.
+ bool ParseTargetFile(const std::string_view target_file_path, bool extracted_input);
+
+ private:
+ // A map to store the system properties during simulation.
+ std::map<std::string, std::string, std::less<>> build_props_;
+ // A map from the blockdev_name to the FakeBlockDevice object, which contains the path to the
+ // temporary file.
+ std::map<std::string, FakeBlockDevice, std::less<>> blockdev_map_;
+
+ std::list<TemporaryFile> temp_files_;
+ std::string work_dir_; // A temporary directory to store the extracted image files
+};
diff --git a/updater/include/updater/simulator_runtime.h b/updater/include/updater/simulator_runtime.h
index 93fa2a4..6290958 100644
--- a/updater/include/updater/simulator_runtime.h
+++ b/updater/include/updater/simulator_runtime.h
@@ -24,11 +24,11 @@
#include <vector>
#include "edify/updater_runtime_interface.h"
-#include "updater/target_files.h"
+#include "updater/build_info.h"
class SimulatorRuntime : public UpdaterRuntimeInterface {
public:
- explicit SimulatorRuntime(TargetFiles* source) : source_(source) {}
+ explicit SimulatorRuntime(BuildInfo* source) : source_(source) {}
bool IsSimulator() const override {
return true;
@@ -53,6 +53,6 @@
private:
std::string FindBlockDeviceName(const std::string_view name) const override;
- TargetFiles* source_;
+ BuildInfo* source_;
std::map<std::string, std::string, std::less<>> mounted_partitions_;
};
diff --git a/updater/include/updater/target_files.h b/updater/include/updater/target_files.h
index 9ef1a5b..860d47a 100644
--- a/updater/include/updater/target_files.h
+++ b/updater/include/updater/target_files.h
@@ -16,21 +16,56 @@
#pragma once
+#include <map>
#include <string>
+#include <string_view>
+#include <vector>
-// This class parses a given target file for the build properties and image files. Then it creates
-// and maintains the temporary files to simulate the block devices on host.
-class TargetFiles {
+#include <android-base/file.h>
+#include <ziparchive/zip_archive.h>
+
+// This class represents the mount information for each line in a fstab file.
+class FstabInfo {
public:
- TargetFiles(std::string path, std::string work_dir)
- : path_(std::move(path)), work_dir_(std::move(work_dir)) {}
+ FstabInfo(std::string blockdev_name, std::string mount_point, std::string fs_type)
+ : blockdev_name(std::move(blockdev_name)),
+ mount_point(std::move(mount_point)),
+ fs_type(std::move(fs_type)) {}
- std::string GetProperty(const std::string_view key, const std::string_view default_value) const;
+ std::string blockdev_name;
+ std::string mount_point;
+ std::string fs_type;
+};
- std::string FindBlockDeviceName(const std::string_view name) const;
+// This class parses a target file from a zip file or an extracted directory. It also provides the
+// function to read the its content for simulation.
+class TargetFile {
+ public:
+ TargetFile(std::string path, bool extracted_input)
+ : path_(std::move(path)), extracted_input_(extracted_input) {}
+
+ // Opens the input target file (or extracted directory) and parses the misc_info.txt.
+ bool Open();
+ // Parses the build properties in all possible locations and save them in |props_map|
+ bool GetBuildProps(std::map<std::string, std::string, std::less<>>* props_map) const;
+ // Parses the fstab and save the information about each partition to mount into |fstab_info_list|.
+ bool ParseFstabInfo(std::vector<FstabInfo>* fstab_info_list) const;
+ // Returns true if the given entry exists in the target file.
+ bool EntryExists(const std::string_view name) const;
+ // Extracts the image file |entry_name|. Returns true on success.
+ bool ExtractImage(const std::string_view entry_name, const FstabInfo& fstab_info,
+ const std::string_view work_dir, TemporaryFile* image_file) const;
private:
- std::string path_; // Path to the target file.
+ // Wrapper functions to read the entry from either the zipped target-file, or the extracted input
+ // directory.
+ bool ReadEntryToString(const std::string_view name, std::string* content) const;
+ bool ExtractEntryToTempFile(const std::string_view name, TemporaryFile* temp_file) const;
- std::string work_dir_; // A temporary directory to store the extracted image files
+ std::string path_; // Path to the zipped target-file or an extracted directory.
+ bool extracted_input_; // True if the target-file has been extracted.
+ ZipArchiveHandle handle_{ nullptr };
+
+ // The properties under META/misc_info.txt
+ std::map<std::string, std::string, std::less<>> misc_info_;
};