mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 15:36:27 +00:00
Minimize size plugin can now shrink vmdk images
It requires vmware workstation to be installed (and zerofree optionally, but highly recommended)
This commit is contained in:
parent
8902e5d93f
commit
d85ad7f598
4 changed files with 119 additions and 1 deletions
|
@ -1,10 +1,27 @@
|
|||
import tasks
|
||||
|
||||
|
||||
def validate_manifest(data, validator, error):
|
||||
import os.path
|
||||
schema_path = os.path.join(os.path.dirname(__file__), 'manifest-schema.json')
|
||||
validator(data, schema_path)
|
||||
if 'zerofree' in data['plugins']['minimize_size']:
|
||||
zerofree_schema_path = os.path.join(os.path.dirname(__file__), 'manifest-schema-zerofree.json')
|
||||
validator(data, zerofree_schema_path)
|
||||
if data['plugins']['minimize_size'].get('shrink', False) and data['volume']['backing'] != 'vmdk':
|
||||
error('Can only shrink vmdk images', ['plugins', 'minimize_size', 'shrink'])
|
||||
|
||||
|
||||
def resolve_tasks(taskset, manifest):
|
||||
taskset.update([tasks.AddFolderMounts,
|
||||
tasks.RemoveFolderMounts,
|
||||
])
|
||||
if 'zerofree' in manifest.plugins['minimize_size']:
|
||||
taskset.add(tasks.CheckZerofreePath)
|
||||
taskset.add(tasks.Zerofree)
|
||||
if manifest.plugins['minimize_size'].get('shrink', False):
|
||||
taskset.add(tasks.CheckVMWareDMCommand)
|
||||
taskset.add(tasks.ShrinkVolume)
|
||||
|
||||
|
||||
def resolve_rollback_tasks(taskset, manifest, counter_task):
|
||||
|
|
18
plugins/minimize_size/manifest-schema-zerofree.json
Normal file
18
plugins/minimize_size/manifest-schema-zerofree.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "Minimize size plugin manifest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"volume": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"partitions": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "enum": ["none"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
plugins/minimize_size/manifest-schema.json
Normal file
25
plugins/minimize_size/manifest-schema.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "Minimize size plugin manifest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"plugins": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"minimize_size": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"shrink": { "type": "boolean" },
|
||||
"zerofree": { "$ref": "#/definitions/absolute_path" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"absolute_path": {
|
||||
"type": "string",
|
||||
"pattern": "^/[^\\0]+$"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
from base import Task
|
||||
from common import phases
|
||||
from common.tasks import bootstrap
|
||||
from common.tasks import apt
|
||||
from common.tasks import bootstrap
|
||||
from common.tasks import filesystem
|
||||
from common.tasks import partitioning
|
||||
from common.tasks import volume
|
||||
import os
|
||||
|
||||
folders = ['tmp', 'var/lib/apt/lists']
|
||||
|
@ -41,3 +44,58 @@ class RemoveFolderMounts(Task):
|
|||
|
||||
os.rmdir(info.minimize_size_folder)
|
||||
del info.minimize_size_folder
|
||||
|
||||
|
||||
class CheckZerofreePath(Task):
|
||||
description = 'Checking path to zerofree tool'
|
||||
phase = phases.preparation
|
||||
|
||||
@classmethod
|
||||
def run(cls, info):
|
||||
from common.exceptions import TaskError
|
||||
import os
|
||||
zerofree = info.manifest.plugins['minimize_size']['zerofree']
|
||||
if not os.path.isfile(zerofree):
|
||||
raise TaskError('The path `{path}\' does not exist or is not a file'.format(path=zerofree))
|
||||
if not os.access(zerofree, os.X_OK):
|
||||
raise TaskError('The path `{path}\' is not executable'.format(path=zerofree))
|
||||
|
||||
|
||||
# Get zerofree here: http://intgat.tigress.co.uk/rmy/uml/index.html
|
||||
class Zerofree(Task):
|
||||
description = 'Zeroing unused blocks on the volume'
|
||||
phase = phases.volume_unmounting
|
||||
predecessors = [filesystem.UnmountRoot, partitioning.UnmapPartitions]
|
||||
successors = [volume.Detach]
|
||||
|
||||
@classmethod
|
||||
def run(cls, info):
|
||||
from common.tools import log_check_call
|
||||
zerofree = info.manifest.plugins['minimize_size']['zerofree']
|
||||
log_check_call([zerofree, info.volume.device_path])
|
||||
|
||||
|
||||
class CheckVMWareDMCommand(Task):
|
||||
description = 'Checking path to vmware-vdiskmanager tool'
|
||||
phase = phases.preparation
|
||||
|
||||
@classmethod
|
||||
def run(cls, info):
|
||||
from common.exceptions import TaskError
|
||||
import os
|
||||
vdiskmngr = '/usr/bin/vmware-vdiskmanager'
|
||||
if not os.path.isfile(vdiskmngr):
|
||||
raise TaskError('Unable to find vmware-vdiskmanager at `{path}\''.format(path=vdiskmngr))
|
||||
if not os.access(vdiskmngr, os.X_OK):
|
||||
raise TaskError('vmware-vdiskmanager at `{path}\' is not executable'.format(path=vdiskmngr))
|
||||
|
||||
|
||||
class ShrinkVolume(Task):
|
||||
description = 'Shrinking the volume'
|
||||
phase = phases.volume_unmounting
|
||||
predecessors = [volume.Detach]
|
||||
|
||||
@classmethod
|
||||
def run(cls, info):
|
||||
from common.tools import log_check_call
|
||||
log_check_call(['/usr/bin/vmware-vdiskmanager', '-k', info.volume.image_path])
|
||||
|
|
Loading…
Add table
Reference in a new issue