diff --git a/kiwi/partitioner/base.py b/kiwi/partitioner/base.py index b04840f7..03d79a08 100644 --- a/kiwi/partitioner/base.py +++ b/kiwi/partitioner/base.py @@ -98,3 +98,11 @@ class PartitionerBase(object): Implementation in specialized partitioner class """ raise NotImplementedError + + def resize_table(self, entries=None): + """ + Resize partition table + + :param int entries: unused + """ + raise NotImplementedError diff --git a/kiwi/partitioner/dasd.py b/kiwi/partitioner/dasd.py index 91bf46a2..93c59b7a 100644 --- a/kiwi/partitioner/dasd.py +++ b/kiwi/partitioner/dasd.py @@ -76,3 +76,11 @@ class PartitionerDasd(PartitionerBase): # are not able to detect real errors with the fdasd operation at # that point. log.debug('potential fdasd errors were ignored') + + def resize_table(self, entries=None): + """ + Resize partition table + + Nothing to be done here for DASD devices + """ + pass diff --git a/kiwi/partitioner/gpt.py b/kiwi/partitioner/gpt.py index 4e59d74c..c30c437c 100644 --- a/kiwi/partitioner/gpt.py +++ b/kiwi/partitioner/gpt.py @@ -136,3 +136,16 @@ class PartitionerGpt(PartitionerBase): if efi_partition_number: # turn former EFI partition into standard linux partition self.set_flag(efi_partition_number, 't.linux') + + def resize_table(self, entries=128): + """ + Resize partition table + + :param int entries: default entries + """ + Command.run( + [ + 'sgdisk', '--resize-table', '{0}'.format(entries), + self.disk_device + ] + ) diff --git a/kiwi/partitioner/msdos.py b/kiwi/partitioner/msdos.py index 3636fe90..fbdf512a 100644 --- a/kiwi/partitioner/msdos.py +++ b/kiwi/partitioner/msdos.py @@ -120,3 +120,11 @@ class PartitionerMsDos(PartitionerBase): ) else: log.warning('Flag %s ignored on msdos', flag_name) + + def resize_table(self, entries=None): + """ + Resize partition table + + Nothing to be done here for msdos table + """ + pass diff --git a/kiwi/storage/loop_device.py b/kiwi/storage/loop_device.py index e776705a..84adbd36 100644 --- a/kiwi/storage/loop_device.py +++ b/kiwi/storage/loop_device.py @@ -72,14 +72,19 @@ class LoopDevice(DeviceProvider): """ return True - def create(self): + def create(self, overwrite=True): """ - Setup a loop device of the specified size and blocksize + Setup a loop device of the blocksize given in the constructor + The file to loop is created with the size specified in the + constructor unless an existing one should not be overwritten + + :param bool overwrite: overwrite existing file to loop """ - qemu_img_size = format(self.filesize_mbytes) + 'M' - Command.run( - ['qemu-img', 'create', self.filename, qemu_img_size] - ) + if overwrite: + qemu_img_size = format(self.filesize_mbytes) + 'M' + Command.run( + ['qemu-img', 'create', self.filename, qemu_img_size] + ) loop_options = [] if self.blocksize_bytes and self.blocksize_bytes != 512: loop_options.append('--logical-blocksize') diff --git a/kiwi/tasks/image_resize.py b/kiwi/tasks/image_resize.py index b5401991..27d6122e 100644 --- a/kiwi/tasks/image_resize.py +++ b/kiwi/tasks/image_resize.py @@ -46,6 +46,9 @@ options: import os # project +from kiwi.firmware import FirmWare +from kiwi.storage.loop_device import LoopDevice +from kiwi.partitioner import Partitioner from kiwi.tasks.base import CliTask from kiwi.help import Help from kiwi.logger import log @@ -107,10 +110,23 @@ class ImageResizeTask(CliTask): new_disk_size = StringToSize.to_bytes(self.command_args['--size']) + # resize raw disk log.info( 'Resizing raw disk to {0} bytes'.format(new_disk_size) ) resize_result = image_format.resize_raw_disk(new_disk_size) + + # resize raw disk partition table + firmware = FirmWare(self.xml_state) + loop_provider = LoopDevice(image_format.diskname) + loop_provider.create(overwrite=False) + partitioner = Partitioner( + firmware.get_partition_table_type(), loop_provider + ) + partitioner.resize_table() + del loop_provider + + # resize disk format from resized raw disk if disk_format and resize_result is True: log.info( 'Creating {0} disk format from resized raw disk'.format( diff --git a/test/unit/partitioner_base_test.py b/test/unit/partitioner_base_test.py index 4771d28a..2742a5c6 100644 --- a/test/unit/partitioner_base_test.py +++ b/test/unit/partitioner_base_test.py @@ -31,3 +31,7 @@ class TestPartitionerBase(object): @raises(NotImplementedError) def test_set_mbr(self): self.partitioner.set_mbr() + + @raises(NotImplementedError) + def test_resize_table(self): + self.partitioner.resize_table() diff --git a/test/unit/partitioner_dasd_test.py b/test/unit/partitioner_dasd_test.py index 01a8eb4d..50cbb035 100644 --- a/test/unit/partitioner_dasd_test.py +++ b/test/unit/partitioner_dasd_test.py @@ -65,3 +65,6 @@ class TestPartitionerDasd(object): self.file_mock.write.assert_called_once_with( 'n\np\n\n\nw\nq\n' ) + + def test_resize_table(self): + self.partitioner.resize_table() diff --git a/test/unit/partitioner_gpt_test.py b/test/unit/partitioner_gpt_test.py index 3260a7da..0c40320a 100644 --- a/test/unit/partitioner_gpt_test.py +++ b/test/unit/partitioner_gpt_test.py @@ -77,3 +77,10 @@ class TestPartitionerGpt(object): call(['sgdisk', '-m', '1:2:3:4', '/dev/loop0']), call(['sgdisk', '-t', '4:8300', '/dev/loop0']) ] + + @patch('kiwi.partitioner.gpt.Command.run') + def test_resize_table(self, mock_command): + self.partitioner.resize_table(42) + mock_command.assert_called_once_with( + ['sgdisk', '--resize-table', '42', '/dev/loop0'] + ) diff --git a/test/unit/partitioner_msdos_test.py b/test/unit/partitioner_msdos_test.py index c64e2ee3..d1857ee5 100644 --- a/test/unit/partitioner_msdos_test.py +++ b/test/unit/partitioner_msdos_test.py @@ -106,3 +106,6 @@ class TestPartitionerMsDos(object): def test_set_flag_ignored(self, mock_warn): self.partitioner.set_flag(1, 't.csm') assert mock_warn.called + + def test_resize_table(self): + self.partitioner.resize_table() diff --git a/test/unit/tasks_image_resize_test.py b/test/unit/tasks_image_resize_test.py index 2b0e0c59..2f5207f2 100644 --- a/test/unit/tasks_image_resize_test.py +++ b/test/unit/tasks_image_resize_test.py @@ -29,12 +29,27 @@ class TestImageResizeTask(object): return_value=mock.Mock() ) + self.firmware = mock.Mock() + self.firmware.get_partition_table_type = mock.Mock( + return_value='gpt' + ) + self.partitioner = mock.Mock() + self.loop_provider = mock.Mock() self.image_format = mock.Mock() self.image_format.has_raw_disk = mock.Mock() self.image_format.diskname = 'some-disk.raw' kiwi.tasks.image_resize.DiskFormat = mock.Mock( return_value=self.image_format ) + kiwi.tasks.image_resize.FirmWare = mock.Mock( + return_value=self.firmware + ) + kiwi.tasks.image_resize.LoopDevice = mock.Mock( + return_value=self.loop_provider + ) + kiwi.tasks.image_resize.Partitioner = mock.Mock( + return_value=self.partitioner + ) self.task = ImageResizeTask() @@ -74,6 +89,8 @@ class TestImageResizeTask(object): self.task.command_args['resize'] = True self.image_format.resize_raw_disk.return_value = True self.task.process() + self.loop_provider.create.assert_called_once_with(overwrite=False) + self.partitioner.resize_table.assert_called_once_with() self.image_format.resize_raw_disk.assert_called_once_with( 42 * 1024 * 1024 * 1024 ) @@ -85,6 +102,8 @@ class TestImageResizeTask(object): self.task.command_args['--size'] = '42m' self.image_format.resize_raw_disk.return_value = True self.task.process() + self.loop_provider.create.assert_called_once_with(overwrite=False) + self.partitioner.resize_table.assert_called_once_with() self.image_format.resize_raw_disk.assert_called_once_with( 42 * 1024 * 1024 ) @@ -96,6 +115,8 @@ class TestImageResizeTask(object): self.task.command_args['--size'] = '42' self.image_format.resize_raw_disk.return_value = True self.task.process() + self.loop_provider.create.assert_called_once_with(overwrite=False) + self.partitioner.resize_table.assert_called_once_with() self.image_format.resize_raw_disk.assert_called_once_with( 42 ) @@ -108,6 +129,8 @@ class TestImageResizeTask(object): self.task.command_args['--size'] = '42' self.image_format.resize_raw_disk.return_value = False self.task.process() + self.loop_provider.create.assert_called_once_with(overwrite=False) + self.partitioner.resize_table.assert_called_once_with() self.image_format.resize_raw_disk.assert_called_once_with( 42 )