update_payload: Implement applying for major version 2 payloads
This commit adds payload major version 2 support to paycheck.py
applying.
BUG=b:794404
TEST=no errors during run_unittests and paycheck.py <major version 2
payload> --part_names boot system --out_dst_part_paths /tmp/boot_part
/tmp/system_part (./test_paycheck.sh does not pass for major version 2
payloads since it currently does not detect version 2 payloads, and
specifies rootfs/kernel as the partitions to paycheck.py instead of
system/boot; no regressions when running on major version 1 payloads)
Change-Id: Ic411607cee6f032851d1fa9545bed68fe2d3da77
Reviewed-on: https://chromium-review.googlesource.com/1106656
Commit-Ready: Tudor Brindus <tbrindus@chromium.org>
Tested-by: Tudor Brindus <tbrindus@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/scripts/update_payload/applier.py b/scripts/update_payload/applier.py
index dad5ba3..49db8ae 100644
--- a/scripts/update_payload/applier.py
+++ b/scripts/update_payload/applier.py
@@ -632,39 +632,54 @@
Raises:
PayloadError if payload application failed.
"""
+ if old_parts is None:
+ old_parts = {}
+
self.payload.ResetFile()
- # TODO(tbrindus): make payload applying work for major version 2 partitions
- new_kernel_part = new_parts[common.KERNEL]
- new_rootfs_part = new_parts[common.ROOTFS]
- old_kernel_part = old_parts.get(common.KERNEL, None) if old_parts else None
- old_rootfs_part = old_parts.get(common.ROOTFS, None) if old_parts else None
+ new_part_info = {}
+ old_part_info = {}
+ install_operations = []
+
+ manifest = self.payload.manifest
+ if self.payload.header.version == 1:
+ for name in common.CROS_PARTITIONS:
+ new_part_info[name] = getattr(manifest, 'new_%s_info' % name)
+ old_part_info[name] = getattr(manifest, 'old_%s_info' % name)
+
+ install_operations.append((common.ROOTFS, manifest.install_operations))
+ install_operations.append((common.KERNEL,
+ manifest.kernel_install_operations))
+ else:
+ for part in manifest.partitions:
+ name = part.partition_name
+ new_part_info[name] = part.new_partition_info
+ old_part_info[name] = part.old_partition_info
+ install_operations.append((name, part.operations))
+
+ part_names = set(new_part_info.keys()) # Equivalently, old_part_info.keys()
# Make sure the arguments are sane and match the payload.
- if not (new_kernel_part and new_rootfs_part):
- raise PayloadError('missing dst {kernel,rootfs} partitions')
+ new_part_names = set(new_parts.keys())
+ if new_part_names != part_names:
+ raise PayloadError('missing dst partition(s) %s' %
+ ', '.join(part_names - new_part_names))
- if not (old_kernel_part or old_rootfs_part):
- if not self.payload.IsFull():
- raise PayloadError('trying to apply a non-full update without src '
- '{kernel,rootfs} partitions')
- elif old_kernel_part and old_rootfs_part:
- if not self.payload.IsDelta():
- raise PayloadError('trying to apply a non-delta update onto src '
- '{kernel,rootfs} partitions')
+ old_part_names = set(old_parts.keys())
+ if part_names - old_part_names:
+ if self.payload.IsDelta():
+ raise PayloadError('trying to apply a delta update without src '
+ 'partition(s) %s' %
+ ', '.join(part_names - old_part_names))
+ elif old_part_names == part_names:
+ if self.payload.IsFull():
+ raise PayloadError('trying to apply a full update onto src partitions')
else:
raise PayloadError('not all src partitions provided')
- # Apply update to rootfs.
- self._ApplyToPartition(
- self.payload.manifest.install_operations, 'rootfs',
- 'install_operations', new_rootfs_part,
- self.payload.manifest.new_rootfs_info, old_rootfs_part,
- self.payload.manifest.old_rootfs_info)
+ for name, operations in install_operations:
+ # Apply update to partition.
+ self._ApplyToPartition(
+ operations, name, '%s_install_operations' % name, new_parts[name],
+ new_part_info[name], old_parts.get(name, None), old_part_info[name])
- # Apply update to kernel update.
- self._ApplyToPartition(
- self.payload.manifest.kernel_install_operations, 'kernel',
- 'kernel_install_operations', new_kernel_part,
- self.payload.manifest.new_kernel_info, old_kernel_part,
- self.payload.manifest.old_kernel_info)