+ # Create the Extended boot records (EBRs) in the image
+ create_EBRs(src_disk, img)
+
+ img_dev = parted.Device(img)
+ img_disk = parted.Disk(img_dev)
+
+ Partition = namedtuple('Partition', 'num start end type fs mpoint')
+
+ partitions = []
+ for p in src_disk.partitions:
+ g = p.geometry
+ f = p.fileSystem
+ partitions.append(Partition(p.number, g.start, g.end, p.type,
+ f.type if f is not None else '', mpoint(p.path)))
+
+ last = partitions[-1]
+ new_end = src_dev.getLength()
+ if last.fs == 'linux-swap(v1)':
+ size = (last.end - last.start + 1) * src_dev.sectorSize
+ MB = 2 ** 20
+ meta['SWAP'] = "%d:%s" % (last.num, ((size + MB - 1) // MB))
+ img_disk.deletePartition(img_disk.getPartitionBySector(last.start))
+ if last.type == parted.PARTITION_LOGICAL and last.num == 5:
+ img_disk.deletePartition(img_disk.getExtendedPartition())
+ partitions.remove(last)
+ last = partitions[-1]
+
+ # Leave 2048 blocks at the end
+ new_end = last.end + 2048
+
+ if last.mpoint:
+ stat = statvfs(last.mpoint)
+ occupied_blocks = stat.f_blocks - stat.f_bavail
+ new_size = (occupied * stat.f_frsize) // src_dev.sectorSize
+ # Add 10% just to be on the safe side
+ last.end = last.start + (new_size * 11) // 10
+
+ # Alighn to 2048
+ last.end = ((last.end + 2047) // 2048) * 2048
+
+ # Leave 2048 blocks at the end.
+ new_end = new_size + 2048
+
+ img_disk.setPartitionGeometry(
+ img_disk.getPartitionBySector(last.start),
+ parted.Constraint(device=img_dev), start=last.star, end=last.end)
+
+ if last.type == parted.PARTITION_LOGICAL:
+ # Fix the extended partition
+ ext = disk.getExtendedPartition()
+
+ img_disk.setPartitionGeometry(ext,
+ parted.Constraint(device=img_dev), ext.geometry.start,
+ end=last.end)
+
+ # Check if we have the available space on the filesystem hosting /mnt
+ # for the image.
+ out.output("Examining available space in /mnt ... ", False)
+ stat = os.statvfs('/mnt')
+ image_size = (new_end + 1) * src_dev.sectorSize
+ available = stat.f_bavail * stat.f_frsize
+
+ if available <= image_size:
+ raise FatalError('Not enough space in /mnt to host the image')
+
+ out.success("sufficient")
+
+ return img