Resize partition table after image resize

The command 'kiwi image resize' allows to resize the size
of a disk image. Depending on the partition table type it
is also required to resize the partition table inside of
the image to let the file size change become effective
This Fixes #534
This commit is contained in:
Marcus Schäfer 2018-03-02 16:31:14 +01:00
parent 34685e3963
commit a4e582eb6d
No known key found for this signature in database
GPG Key ID: AD11DD02B44996EF
11 changed files with 104 additions and 6 deletions

View File

@ -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

View File

@ -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

View File

@ -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
]
)

View File

@ -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

View File

@ -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')

View File

@ -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(

View File

@ -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()

View File

@ -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()

View File

@ -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']
)

View File

@ -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()

View File

@ -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
)