Set per-partition timestamps in OTA generation
update_engine can also accept payload with per-partition timestamps.
This CL updates OTA generation script to emit per-partition timestamps
when writing an OTA package.
Test: Generate && serve an ota
Change-Id: I17529a004b8e0bbcb7d69dde93fb0fd7124b3b17
diff --git a/payload_generator/generate_delta_main.cc b/payload_generator/generate_delta_main.cc
index 18cff4b..dd41a29 100644
--- a/payload_generator/generate_delta_main.cc
+++ b/payload_generator/generate_delta_main.cc
@@ -14,6 +14,7 @@
// limitations under the License.
//
+#include <map>
#include <string>
#include <vector>
@@ -22,6 +23,7 @@
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
+#include <base/strings/string_util.h>
#include <brillo/flag_helper.h>
#include <brillo/key_value_store.h>
#include <brillo/message_loops/base_message_loop.h>
@@ -47,6 +49,7 @@
// and an output file as arguments and the path to an output file and
// generates a delta that can be sent to Chrome OS clients.
+using std::map;
using std::string;
using std::vector;
@@ -294,6 +297,39 @@
return true;
}
+template <typename Key, typename Val>
+string ToString(const map<Key, Val>& map) {
+ vector<string> result;
+ result.reserve(map.size());
+ for (const auto& it : map) {
+ result.emplace_back(it.first + ": " + it.second);
+ }
+ return "{" + base::JoinString(result, ",") + "}";
+}
+
+bool ParsePerPartitionTimestamps(const string& partition_timestamps,
+ PayloadGenerationConfig* config) {
+ base::StringPairs pairs;
+ CHECK(base::SplitStringIntoKeyValuePairs(
+ partition_timestamps, ':', ',', &pairs))
+ << "--partition_timestamps accepts commad "
+ "separated pairs. e.x. system:1234,vendor:5678";
+ map<string, string> partition_timestamps_map{
+ std::move_iterator(pairs.begin()), std::move_iterator(pairs.end())};
+ for (auto&& partition : config->target.partitions) {
+ auto&& it = partition_timestamps_map.find(partition.name);
+ if (it != partition_timestamps_map.end()) {
+ partition.version = std::move(it->second);
+ partition_timestamps_map.erase(it);
+ }
+ }
+ if (!partition_timestamps_map.empty()) {
+ LOG(ERROR) << "Unused timestamps: " << ToString(partition_timestamps_map);
+ return false;
+ }
+ return true;
+}
+
int Main(int argc, char** argv) {
DEFINE_string(old_image, "", "Path to the old rootfs");
DEFINE_string(new_image, "", "Path to the new rootfs");
@@ -384,6 +420,11 @@
0,
"The maximum timestamp of the OS allowed to apply this "
"payload.");
+ DEFINE_string(
+ partition_timestamps,
+ "",
+ "The per-partition maximum timestamps which the OS allowed to apply this "
+ "payload. Passed in comma separated pairs, e.x. system:1234,vendor:5678");
DEFINE_string(old_channel,
"",
@@ -709,6 +750,10 @@
}
payload_config.max_timestamp = FLAGS_max_timestamp;
+ if (!FLAGS_partition_timestamps.empty()) {
+ CHECK(ParsePerPartitionTimestamps(FLAGS_partition_timestamps,
+ &payload_config));
+ }
if (payload_config.is_delta &&
payload_config.version.minor >= kVerityMinorPayloadVersion)
diff --git a/payload_generator/payload_file.cc b/payload_generator/payload_file.cc
index c1594c7..1388f2d 100644
--- a/payload_generator/payload_file.cc
+++ b/payload_generator/payload_file.cc
@@ -92,6 +92,7 @@
part.aops = std::move(aops);
part.postinstall = new_conf.postinstall;
part.verity = new_conf.verity;
+ part.version = new_conf.version;
// Initialize the PartitionInfo objects if present.
if (!old_conf.path.empty())
TEST_AND_RETURN_FALSE(
@@ -132,6 +133,9 @@
for (const auto& part : part_vec_) {
PartitionUpdate* partition = manifest_.add_partitions();
partition->set_partition_name(part.name);
+ if (!part.version.empty()) {
+ partition->set_version(part.version);
+ }
if (part.postinstall.run) {
partition->set_run_postinstall(true);
if (!part.postinstall.path.empty())
diff --git a/payload_generator/payload_file.h b/payload_generator/payload_file.h
index d1f8196..3dce00f 100644
--- a/payload_generator/payload_file.h
+++ b/payload_generator/payload_file.h
@@ -96,6 +96,8 @@
PostInstallConfig postinstall;
VerityConfig verity;
+ // Per partition timestamp.
+ std::string version;
};
std::vector<Partition> part_vec_;
diff --git a/payload_generator/payload_generation_config.h b/payload_generator/payload_generation_config.h
index 9abb97f..ec63043 100644
--- a/payload_generator/payload_generation_config.h
+++ b/payload_generator/payload_generation_config.h
@@ -119,6 +119,9 @@
// Enables the on device fec data computation by default.
bool disable_fec_computation = false;
+
+ // Per-partition version, usually a number representing timestamp.
+ std::string version;
};
// The ImageConfig struct describes a pair of binaries kernel and rootfs and the