+ is_extended = lambda p: p.type == parted.PARTITION_EXTENDED
+ is_logical = lambda p: p.type == parted.PARTITION_LOGICAL
+
+ partitions = self._get_partitions(self.disk)
+
+ last = partitions[-1]
+ if last.fs == 'linux-swap(v1)':
+ MB = 2 ** 20
+ size = (last.end - last.start + 1) * self.disk.device.sectorSize
+ self.meta['SWAP'] = "%d:%s" % (last.num, (size + MB - 1) // MB)
+
+ image_disk.deletePartition(
+ image_disk.getPartitionBySector(last.start))
+ image_disk.commitToDevice()
+
+ if is_logical(last) and last.num == 5:
+ extended = image_disk.getExtendedPartition()
+ image_disk.deletePartition(extended)
+ image_disk.commitToDevice()
+ partitions.remove(filter(is_extended, partitions)[0])
+
+ partitions.remove(last)
+ last = partitions[-1]
+
+ new_end = last.end
+
+ mount_options = self._get_mount_options(
+ self.disk.getPartitionBySector(last.start).path)
+ if mount_options is not None:
+ stat = os.statvfs(mount_options.mpoint)
+ # Shrink the last partition. The new size should be the size of the
+ # occupied blocks
+ blcks = stat.f_blocks - stat.f_bavail
+ new_size = (blcks * stat.f_frsize) // self.disk.device.sectorSize
+
+ # Add 10% just to be on the safe side
+ part_end = last.start + (new_size * 11) // 10
+ # Align to 2048
+ part_end = ((part_end + 2047) // 2048) * 2048
+
+ # Make sure the partition starts where the old partition started.
+ constraint = parted.Constraint(device=image_disk.device)
+ constraint.startRange = parted.Geometry(device=image_disk.device,
+ start=last.start, length=1)
+
+ image_disk.setPartitionGeometry(
+ image_disk.getPartitionBySector(last.start), constraint,
+ start=last.start, end=part_end)
+ image_disk.commitToDevice()
+
+ # Parted may have changed this for better alignment
+ part_end = image_disk.getPartitionBySector(last.start).geometry.end
+ last = last._replace(end=part_end)
+ partitions[-1] = last
+
+ new_end = part_end
+
+ if last.type == parted.PARTITION_LOGICAL:
+ # Fix the extended partition
+ image_disk.minimizeExtendedPartition()
+
+ return (new_end, self._get_partitions(image_disk))
+
+ def _map_partition(self, dev, num, start, end):
+ name = os.path.basename(dev) + "_" + uuid.uuid4().hex
+ tablefd, table = tempfile.mkstemp()