diff --git a/bootstrapvz/plugins/prebootstrapped/README.rst b/bootstrapvz/plugins/prebootstrapped/README.rst index bc30de8..6cb1f28 100644 --- a/bootstrapvz/plugins/prebootstrapped/README.rst +++ b/bootstrapvz/plugins/prebootstrapped/README.rst @@ -21,6 +21,8 @@ Settings ~~~~~~~~ - ``snapshot``: ID of the EBS snapshot to use. This setting only works - with EBS backed EC2 configurations. + with the volume backing ``ebs``. - ``image``: Path to the loopbackvolume snapshot. This setting works - with all configurable volume backings except EBS. + with the volume backings ``raw``, ``s3``, ``vdi``, ``vmdk`` +- ``folder``: Path to the folder copy. This setting works + with the volume backing ``folder`` diff --git a/bootstrapvz/plugins/prebootstrapped/__init__.py b/bootstrapvz/plugins/prebootstrapped/__init__.py index 2dc9796..c0fca42 100644 --- a/bootstrapvz/plugins/prebootstrapped/__init__.py +++ b/bootstrapvz/plugins/prebootstrapped/__init__.py @@ -1,11 +1,9 @@ -from tasks import Snapshot -from tasks import CopyImage -from tasks import CreateFromSnapshot -from tasks import CreateFromImage +import tasks from bootstrapvz.providers.ec2.tasks import ebs from bootstrapvz.providers.virtualbox.tasks import guest_additions from bootstrapvz.common.tasks import loopback from bootstrapvz.common.tasks import volume +from bootstrapvz.common.tasks import folder from bootstrapvz.common.tasks import locale from bootstrapvz.common.tasks import apt from bootstrapvz.common.tasks import bootstrap @@ -23,6 +21,7 @@ def resolve_tasks(taskset, manifest): settings = manifest.plugins['prebootstrapped'] skip_tasks = [ebs.Create, loopback.Create, + folder.Create, filesystem.Format, partitioning.PartitionVolume, @@ -38,20 +37,28 @@ def resolve_tasks(taskset, manifest): ] if manifest.volume['backing'] == 'ebs': if settings.get('snapshot', None) is not None: - taskset.add(CreateFromSnapshot) + taskset.add(tasks.CreateFromSnapshot) [taskset.discard(task) for task in skip_tasks] else: - taskset.add(Snapshot) + taskset.add(tasks.Snapshot) + elif manifest.volume['backing'] == 'folder': + if settings.get('folder', None) is not None: + taskset.add(tasks.CreateFromFolder) + [taskset.discard(task) for task in skip_tasks] + else: + taskset.add(tasks.CopyFolder) else: if settings.get('image', None) is not None: - taskset.add(CreateFromImage) + taskset.add(tasks.CreateFromImage) [taskset.discard(task) for task in skip_tasks] else: - taskset.add(CopyImage) + taskset.add(tasks.CopyImage) def resolve_rollback_tasks(taskset, manifest, completed, counter_task): if manifest.volume['backing'] == 'ebs': - counter_task(taskset, CreateFromSnapshot, volume.Delete) + counter_task(taskset, tasks.CreateFromSnapshot, volume.Delete) + elif manifest.volume['backing'] == 'folder': + counter_task(taskset, tasks.CreateFromFolder, folder.Delete) else: - counter_task(taskset, CreateFromImage, volume.Delete) + counter_task(taskset, tasks.CreateFromImage, volume.Delete) diff --git a/bootstrapvz/plugins/prebootstrapped/manifest-schema.yml b/bootstrapvz/plugins/prebootstrapped/manifest-schema.yml index d01820c..b2f405c 100644 --- a/bootstrapvz/plugins/prebootstrapped/manifest-schema.yml +++ b/bootstrapvz/plugins/prebootstrapped/manifest-schema.yml @@ -14,6 +14,7 @@ properties: - s3 - vdi - vmdk + - folder required: [backing] plugins: type: object @@ -23,4 +24,5 @@ properties: properties: image: {type: string} snapshot: {type: string} + folder: {type: string} additionalProperties: false diff --git a/bootstrapvz/plugins/prebootstrapped/tasks.py b/bootstrapvz/plugins/prebootstrapped/tasks.py index 53c7d6d..d1f6294 100644 --- a/bootstrapvz/plugins/prebootstrapped/tasks.py +++ b/bootstrapvz/plugins/prebootstrapped/tasks.py @@ -5,6 +5,7 @@ from bootstrapvz.common.tasks import packages from bootstrapvz.providers.virtualbox.tasks import guest_additions from bootstrapvz.providers.ec2.tasks import ebs from bootstrapvz.common.fs import unmounted +from bootstrapvz.common.tools import log_check_call from shutil import copyfile import os.path import time @@ -75,6 +76,33 @@ class CreateFromImage(Task): set_fs_states(info.volume) +class CopyFolder(Task): + description = 'Creating a copy of the bootstrap folder' + phase = phases.package_installation + predecessors = [packages.InstallPackages, guest_additions.InstallGuestAdditions] + + @classmethod + def run(cls, info): + folder_backup_name = '{id}.{ext}.backup'.format(id=info.run_id, ext=info.volume.extension) + destination = os.path.join(info.manifest.bootstrapper['workspace'], folder_backup_name) + log_check_call(['cp', '-a', info.volume.path, destination]) + msg = 'A copy of the bootstrapped volume was created. Path: ' + destination + log.info(msg) + + +class CreateFromFolder(Task): + description = 'Creating bootstrap folder from a copy' + phase = phases.volume_creation + successors = [volume.Attach] + + @classmethod + def run(cls, info): + info.root = os.path.join(info.workspace, 'root') + log_check_call(['cp', '-a', info.manifest.plugins['prebootstrapped']['folder'], info.root]) + info.volume.path = info.root + info.volume.fsm.current = 'attached' + + def set_fs_states(volume): volume.fsm.current = 'detached'