minimize_size: New option for qemu-img-based shrinking

This commit is contained in:
Tomasz Melcer 2017-07-09 23:34:58 +02:00
parent 6a96a2b5b1
commit 75e0ce86f0
4 changed files with 70 additions and 16 deletions

View file

@ -15,17 +15,21 @@ footprint:
deallocate unused sectors on the volume. On an unpartitioned volume
this will be done for the entire volume, while it will only happen on
the root partition for partitioned volumes.
- Use
`vmware-vdiskmanager <https://www.vmware.com/support/ws45/doc/disks_vdiskmanager_eg_ws.html>`__
to shrink the real volume size (only applicable when using vmdk
backing). The tool is part of the `VMWare
Workstation <https://my.vmware.com/web/vmware/info/slug/desktop_end_user_computing/vmware_workstation/10_0>`__
package.
- Shrink the real volume size. Supported tools are:
- `vmware-vdiskmanager <https://www.vmware.com/support/ws45/doc/disks_vdiskmanager_eg_ws.html>`__
(only applicable when using vmdk backing). The tool is part of the
`VMWare Workstation <https://my.vmware.com/web/vmware/info/slug/desktop_end_user_computing/vmware_workstation/10_0>`__
package.
- `qemu-img` (only applicaple when using vmdk or vdi backing). This
tool is part of the `QEMU emulator <https://www.qemu.org/>`__.
- Tell apt to only download specific language files. See the
`apt.conf manpage <http://manpages.debian.org/cgi-bin/man.cgi?query=apt.conf>`__
for more details ("Languages" in the "Acquire group" section).
- Configure debootstrap and dpkg to filter out specific paths when installing packages
Settings
~~~~~~~~
@ -35,8 +39,13 @@ Settings
Default: false
``optional``
- ``shrink``: Whether the volume should be shrunk. This setting works
best in conjunction with the zerofree tool.
Valid values: true, false
best in conjunction with the zerofree tool. Valid values:
- false: Do not shrink.
- ``vmware-vdiskmanager`` or true: Shrink using the `vmware-vdiskmanager`
utility.
- ``qemu-img``: Shrink using the `qemu-img` utility.
Default: false
``optional``
- ``apt``: Apt specific configurations. ``optional``

View file

@ -5,12 +5,29 @@ import tasks.dpkg
from bootstrapvz.common.tasks import locale
def get_shrink_type(plugins):
"""Gets the type of shrinking process requested by the user, taking into account backward compatibility
values
:param dict plugins: the part of the manifest related to plugins
:return: None (if none selected), "vmware-vdiskmanager" or "qemu-img" (tool to be used)"""
shrink_type = plugins['minimize_size'].get('shrink')
if shrink_type is True:
shrink_type = 'vmware-vdiskmanager'
elif shrink_type is False:
shrink_type = None
return shrink_type
def validate_manifest(data, validator, error):
from bootstrapvz.common.tools import rel_path
validator(data, rel_path(__file__, 'manifest-schema.yml'))
if data['plugins']['minimize_size'].get('shrink', False) and data['volume']['backing'] != 'vmdk':
error('Can only shrink vmdk images', ['plugins', 'minimize_size', 'shrink'])
shrink_type = get_shrink_type(data['plugins'])
if shrink_type == 'vmware-vdiskmanager' and data['volume']['backing'] != 'vmdk':
error('Can only shrink vmdk images with vmware-vdiskmanager', ['plugins', 'minimize_size', 'shrink'])
if shrink_type == 'qemu-img' and data['volume']['backing'] not in ('vmdk', 'vdi'):
error('Can only shrink vmdk and vdi images with qemu-img', ['plugins', 'minimize_size', 'shrink'])
def resolve_tasks(taskset, manifest):
@ -20,9 +37,12 @@ def resolve_tasks(taskset, manifest):
if manifest.plugins['minimize_size'].get('zerofree', False):
taskset.add(tasks.shrink.AddRequiredZeroFreeCommand)
taskset.add(tasks.shrink.Zerofree)
if manifest.plugins['minimize_size'].get('shrink', False):
if get_shrink_type(manifest.plugins) == 'vmware-vdiskmanager':
taskset.add(tasks.shrink.AddRequiredVDiskManagerCommand)
taskset.add(tasks.shrink.ShrinkVolume)
taskset.add(tasks.shrink.ShrinkVolumeWithVDiskManager)
if get_shrink_type(manifest.plugins) == 'qemu-img':
taskset.add(tasks.shrink.AddRequiredQemuImgCommand)
taskset.add(tasks.shrink.ShrinkVolumeWithQemuImg)
if 'apt' in manifest.plugins['minimize_size']:
apt = manifest.plugins['minimize_size']['apt']
if apt.get('autoclean', False):

View file

@ -6,7 +6,9 @@ properties:
minimize_size:
properties:
shrink:
type: boolean
anyOf:
- type: boolean
- enum: [vmware-vdiskmanager, qemu-img]
zerofree:
type: boolean
apt:

View file

@ -19,7 +19,7 @@ class AddRequiredZeroFreeCommand(Task):
class AddRequiredVDiskManagerCommand(Task):
description = 'Adding command required for reducing volume size'
description = 'Adding vmware-vdiskmanager command required for reducing volume size'
phase = phases.validation
successors = [host.CheckExternalCommands]
@ -29,6 +29,16 @@ class AddRequiredVDiskManagerCommand(Task):
info.host_dependencies['vmware-vdiskmanager'] = link
class AddRequiredQemuImgCommand(Task):
description = 'Adding qemu-img command required for reducing volume size'
phase = phases.validation
successors = [host.CheckExternalCommands]
@classmethod
def run(cls, info):
info.host_dependencies['qemu-img'] = 'qemu-img'
class Zerofree(Task):
description = 'Zeroing unused blocks on the root partition'
phase = phases.volume_unmounting
@ -40,8 +50,8 @@ class Zerofree(Task):
log_check_call(['zerofree', info.volume.partition_map.root.device_path])
class ShrinkVolume(Task):
description = 'Shrinking the volume'
class ShrinkVolumeWithVDiskManager(Task):
description = 'Shrinking the volume with vmware-vdiskmanager'
phase = phases.volume_unmounting
predecessors = [volume.Detach]
@ -50,3 +60,16 @@ class ShrinkVolume(Task):
perm = os.stat(info.volume.image_path).st_mode & 0777
log_check_call(['/usr/bin/vmware-vdiskmanager', '-k', info.volume.image_path])
os.chmod(info.volume.image_path, perm)
class ShrinkVolumeWithQemuImg(Task):
description = 'Shrinking the volume with qemu-img'
phase = phases.volume_unmounting
predecessors = [volume.Detach]
@classmethod
def run(cls, info):
tmp_name = os.path.join(info.workspace, 'shrinked.' + info.volume.extension)
log_check_call(
['qemu-img', 'convert', '-O', info.volume.extension, info.volume.image_path, tmp_name])
os.rename(tmp_name, info.volume.image_path)