- output("Shrinking image (this may take a while)...", False)
-
- if self.parttype not in 'msdos' 'gpt':
- raise FatalError("You have a %s partition table. "
- "Only msdos and gpt partitions are supported" % self.parttype)
-
- last_partition = self.g.part_list(self.guestfs_device)[-1]
-
- if self.parttype == 'msdos' and last_partition['part_num'] > 4:
- raise FatalError("This disk contains logical partitions. "
- "Only primary partitions are supported.")
-
- part_dev = "%s%d" % (self.guestfs_device, last_partition['part_num'])
- fs_type = self.g.vfs_type(part_dev)
- if not re.match("ext[234]", fs_type):
- warn("Don't know how to resize %s partitions." % fs_type)
- return self.size
-
- self.g.e2fsck_f(part_dev)
- self.g.resize2fs_M(part_dev)
-
- out = self.g.tune2fs_l(part_dev)
- block_size = int(
- filter(lambda x: x[0] == 'Block size', out)[0][1])
- block_cnt = int(
- filter(lambda x: x[0] == 'Block count', out)[0][1])
-
- sector_size = self.g.blockdev_getss(self.guestfs_device)
-
- start = last_partition['part_start'] / sector_size
- end = start + (block_size * block_cnt) / sector_size - 1
-
- self.g.part_del(self.guestfs_device, last_partition['part_num'])
- self.g.part_add(self.guestfs_device, 'p', start, end)
-
- self.size = (end + 1) * sector_size
- success("new size is %dMB" % ((self.size + 2 ** 20 - 1) // 2 ** 20))
-
- if self.parttype == 'gpt':
- ptable = GPTPartitionTable(self.real_device)
- self.size = ptable.shrink(self.size)
-
- return self.size
-
- def dump(self, outfile):
- """Dumps the content of device into a file.
-
- This method will only dump the actual payload, found by reading the
- partition table. Empty space in the end of the device will be ignored.
- """
- blocksize = 2 ** 22 # 4MB
- progress_size = (self.size + 2 ** 20 - 1) // 2 ** 20 # in MB
- progressbar = progress("Dumping image file: ", 'mb')
- progressbar.max = progress_size
-
- with open(self.real_device, 'r') as src:
- with open(outfile, "w") as dst:
- left = self.size
- offset = 0
- progressbar.next()
- while left > 0:
- length = min(left, blocksize)
- sent = sendfile(dst.fileno(), src.fileno(), offset, length)
- offset += sent
- left -= sent
- progressbar.goto((self.size - left) // 2 ** 20)
- output("\rDumping image file...\033[K", False)
- success('image file %s was successfully created' % outfile)