Revert "update_engine: Deprecate major version 1"
This partially reverts commit 55c75417e22d5026971276997924a345d9973bbc.
It turns out that we forgot a scenario when we deprecated major version
1. We use update_engine in lab tests (specifically
autoupdate_EndToEndTests on stable channel) to update a DUT to an
old (very old) versions using actual update payloads so we can test that
they can get updated to newer versions. However, deprecating major
version 1 in the update_engine caused trouble because we no longer can
update from a newer version to a version before M72 (to prepare the
device for update test). We need to put this feature back until we find
a better solution for it.
On this CL, we only support major version 1 in the client and only for
test (non-official) images. We don't even bother adding paygen support
for it.
This CL should be reverted once we figured out what to do with
provisioning the autoupdate end to end tests.
BUG=chromium:1043428
TEST=FEATURES=test emerge-reef update_engine
TEST=cros deployed it, then cros flash using an m71 payload, it succeeded.
Change-Id: I1fecbe3ae845b2e419f0999adc53e4732b1f7696
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2013884
Reviewed-by: Tianjie Xu <xunchang@google.com>
Reviewed-by: Sen Jiang <senj@chromium.org>
Tested-by: Amin Hassani <ahassani@chromium.org>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 3263ff7..262e8bc 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -437,7 +437,7 @@
if (!IsHeaderParsed()) {
MetadataParseResult result =
- payload_metadata_.ParsePayloadHeader(payload, error);
+ payload_metadata_.ParsePayloadHeader(payload, hardware_, error);
if (result != MetadataParseResult::kSuccess)
return result;
@@ -728,7 +728,8 @@
// In major version 2, we don't add dummy operation to the payload.
// If we already extracted the signature we should skip this step.
- if (manifest_.has_signatures_offset() && manifest_.has_signatures_size() &&
+ if (major_payload_version_ == kBrilloMajorPayloadVersion &&
+ manifest_.has_signatures_offset() && manifest_.has_signatures_size() &&
signatures_message_data_.empty()) {
if (manifest_.signatures_offset() != buffer_offset_) {
LOG(ERROR) << "Payload signatures offset points to blob offset "
@@ -763,11 +764,51 @@
}
bool DeltaPerformer::ParseManifestPartitions(ErrorCode* error) {
- partitions_.clear();
- for (const PartitionUpdate& partition : manifest_.partitions()) {
- partitions_.push_back(partition);
+ if (major_payload_version_ == kBrilloMajorPayloadVersion) {
+ partitions_.clear();
+ for (const PartitionUpdate& partition : manifest_.partitions()) {
+ partitions_.push_back(partition);
+ }
+ manifest_.clear_partitions();
+ } else if (major_payload_version_ == kChromeOSMajorPayloadVersion) {
+ LOG(INFO) << "Converting update information from old format.";
+ PartitionUpdate root_part;
+ root_part.set_partition_name(kPartitionNameRoot);
+#ifdef __ANDROID__
+ LOG(WARNING) << "Legacy payload major version provided to an Android "
+ "build. Assuming no post-install. Please use major version "
+ "2 or newer.";
+ root_part.set_run_postinstall(false);
+#else
+ root_part.set_run_postinstall(true);
+#endif // __ANDROID__
+ if (manifest_.has_old_rootfs_info()) {
+ *root_part.mutable_old_partition_info() = manifest_.old_rootfs_info();
+ manifest_.clear_old_rootfs_info();
+ }
+ if (manifest_.has_new_rootfs_info()) {
+ *root_part.mutable_new_partition_info() = manifest_.new_rootfs_info();
+ manifest_.clear_new_rootfs_info();
+ }
+ *root_part.mutable_operations() = manifest_.install_operations();
+ manifest_.clear_install_operations();
+ partitions_.push_back(std::move(root_part));
+
+ PartitionUpdate kern_part;
+ kern_part.set_partition_name(kPartitionNameKernel);
+ kern_part.set_run_postinstall(false);
+ if (manifest_.has_old_kernel_info()) {
+ *kern_part.mutable_old_partition_info() = manifest_.old_kernel_info();
+ manifest_.clear_old_kernel_info();
+ }
+ if (manifest_.has_new_kernel_info()) {
+ *kern_part.mutable_new_partition_info() = manifest_.new_kernel_info();
+ manifest_.clear_new_kernel_info();
+ }
+ *kern_part.mutable_operations() = manifest_.kernel_install_operations();
+ manifest_.clear_kernel_install_operations();
+ partitions_.push_back(std::move(kern_part));
}
- manifest_.clear_partitions();
// Fill in the InstallPlan::partitions based on the partitions from the
// payload.
@@ -928,6 +969,14 @@
TEST_AND_RETURN_FALSE(buffer_offset_ == operation.data_offset());
TEST_AND_RETURN_FALSE(buffer_.size() >= operation.data_length());
+ // Extract the signature message if it's in this operation.
+ if (ExtractSignatureMessageFromOperation(operation)) {
+ // If this is dummy replace operation, we ignore it after extracting the
+ // signature.
+ DiscardBuffer(true, 0);
+ return true;
+ }
+
// Setup the ExtentWriter stack based on the operation type.
std::unique_ptr<ExtentWriter> writer = std::make_unique<DirectExtentWriter>();
@@ -1378,6 +1427,19 @@
return true;
}
+bool DeltaPerformer::ExtractSignatureMessageFromOperation(
+ const InstallOperation& operation) {
+ if (operation.type() != InstallOperation::REPLACE ||
+ !manifest_.has_signatures_offset() ||
+ manifest_.signatures_offset() != operation.data_offset()) {
+ return false;
+ }
+ TEST_AND_RETURN_FALSE(manifest_.has_signatures_size() &&
+ manifest_.signatures_size() == operation.data_length());
+ TEST_AND_RETURN_FALSE(ExtractSignatureMessage());
+ return true;
+}
+
bool DeltaPerformer::ExtractSignatureMessage() {
TEST_AND_RETURN_FALSE(signatures_message_data_.empty());
TEST_AND_RETURN_FALSE(buffer_offset_ == manifest_.signatures_offset());
@@ -1429,11 +1491,11 @@
// Perform assorted checks to sanity check the manifest, make sure it
// matches data from other sources, and that it is a supported version.
- bool has_old_fields = std::any_of(manifest_.partitions().begin(),
- manifest_.partitions().end(),
- [](const PartitionUpdate& partition) {
- return partition.has_old_partition_info();
- });
+ bool has_old_fields =
+ (manifest_.has_old_kernel_info() || manifest_.has_old_rootfs_info());
+ for (const PartitionUpdate& partition : manifest_.partitions()) {
+ has_old_fields = has_old_fields || partition.has_old_partition_info();
+ }
// The presence of an old partition hash is the sole indicator for a delta
// update.
@@ -1475,12 +1537,16 @@
}
}
- if (manifest_.has_old_rootfs_info() || manifest_.has_new_rootfs_info() ||
- manifest_.has_old_kernel_info() || manifest_.has_new_kernel_info() ||
- manifest_.install_operations_size() != 0 ||
- manifest_.kernel_install_operations_size() != 0) {
- LOG(ERROR) << "Manifest contains deprecated fields.";
- return ErrorCode::kPayloadMismatchedType;
+ if (major_payload_version_ != kChromeOSMajorPayloadVersion) {
+ if (manifest_.has_old_rootfs_info() || manifest_.has_new_rootfs_info() ||
+ manifest_.has_old_kernel_info() || manifest_.has_new_kernel_info() ||
+ manifest_.install_operations_size() != 0 ||
+ manifest_.kernel_install_operations_size() != 0) {
+ LOG(ERROR) << "Manifest contains deprecated field only supported in "
+ << "major payload version 1, but the payload major version is "
+ << major_payload_version_;
+ return ErrorCode::kPayloadMismatchedType;
+ }
}
if (manifest_.max_timestamp() < hardware_->GetBuildTimestamp()) {
@@ -1491,6 +1557,16 @@
return ErrorCode::kPayloadTimestampError;
}
+ if (major_payload_version_ == kChromeOSMajorPayloadVersion) {
+ if (manifest_.has_dynamic_partition_metadata()) {
+ LOG(ERROR)
+ << "Should not contain dynamic_partition_metadata for major version "
+ << kChromeOSMajorPayloadVersion
+ << ". Please use major version 2 or above.";
+ return ErrorCode::kPayloadMismatchedType;
+ }
+ }
+
// TODO(crbug.com/37661) we should be adding more and more manifest checks,
// such as partition boundaries, etc.