From f572703eccc836d1ad037f02607b6891250ab92c Mon Sep 17 00:00:00 2001 From: Anders Ingemann Date: Wed, 14 Oct 2015 22:39:42 +0200 Subject: [PATCH] Bootstrap azure images directly to VHD --- bootstrapvz/base/fs/__init__.py | 2 ++ bootstrapvz/common/fs/virtualharddisk.py | 23 +++++++++++++++ bootstrapvz/providers/azure/__init__.py | 3 +- .../providers/azure/manifest-schema.yml | 2 +- bootstrapvz/providers/azure/tasks/image.py | 28 ------------------- 5 files changed, 27 insertions(+), 31 deletions(-) create mode 100644 bootstrapvz/common/fs/virtualharddisk.py delete mode 100644 bootstrapvz/providers/azure/tasks/image.py diff --git a/bootstrapvz/base/fs/__init__.py b/bootstrapvz/base/fs/__init__.py index 9f7742b..1b8c7ab 100644 --- a/bootstrapvz/base/fs/__init__.py +++ b/bootstrapvz/base/fs/__init__.py @@ -22,10 +22,12 @@ def load_volume(data, bootloader): from bootstrapvz.common.fs.loopbackvolume import LoopbackVolume from bootstrapvz.providers.ec2.ebsvolume import EBSVolume from bootstrapvz.common.fs.virtualdiskimage import VirtualDiskImage + from bootstrapvz.common.fs.virtualharddisk import VirtualHardDisk from bootstrapvz.common.fs.virtualmachinedisk import VirtualMachineDisk volume_backing = {'raw': LoopbackVolume, 's3': LoopbackVolume, 'vdi': VirtualDiskImage, + 'vhd': VirtualHardDisk, 'vmdk': VirtualMachineDisk, 'ebs': EBSVolume }.get(data['backing']) diff --git a/bootstrapvz/common/fs/virtualharddisk.py b/bootstrapvz/common/fs/virtualharddisk.py new file mode 100644 index 0000000..8a71ed2 --- /dev/null +++ b/bootstrapvz/common/fs/virtualharddisk.py @@ -0,0 +1,23 @@ +from qemuvolume import QEMUVolume +from ..tools import log_check_call + + +class VirtualHardDisk(QEMUVolume): + + extension = 'vhd' + qemu_format = 'vpc' + ovf_uri = 'http://go.microsoft.com/fwlink/?LinkId=137171' + + # Azure requires the image size to be a multiple of 1 MiB. + # VHDs are dynamic by default, so we add the option + # to make the image size fixed (subformat=fixed) + def _before_create(self, e): + self.image_path = e.image_path + vol_size = str(self.size.bytes.get_qty_in('MiB')) + 'M' + log_check_call(['qemu-img', 'create', '-o', 'subformat=fixed', '-f', self.qemu_format, self.image_path, vol_size]) + + def get_uuid(self): + if not hasattr(self, 'uuid'): + import uuid + self.uuid = uuid.uuid4() + return self.uuid diff --git a/bootstrapvz/providers/azure/__init__.py b/bootstrapvz/providers/azure/__init__.py index 970a5db..3f28a67 100644 --- a/bootstrapvz/providers/azure/__init__.py +++ b/bootstrapvz/providers/azure/__init__.py @@ -1,7 +1,6 @@ from bootstrapvz.common import task_groups import tasks.packages import tasks.boot -import tasks.image from bootstrapvz.common.tasks import loopback from bootstrapvz.common.tasks import initd from bootstrapvz.common.tasks import ssh @@ -20,6 +19,7 @@ def resolve_tasks(taskset, manifest): tasks.packages.DefaultPackages, loopback.AddRequiredCommands, loopback.Create, + loopback.MoveImage, initd.InstallInitScripts, ssh.AddOpenSSHPackage, ssh.ShredHostkeys, @@ -27,7 +27,6 @@ def resolve_tasks(taskset, manifest): tasks.packages.Waagent, tasks.boot.ConfigureGrub, tasks.boot.PatchUdev, - tasks.image.ConvertToVhd, ]) diff --git a/bootstrapvz/providers/azure/manifest-schema.yml b/bootstrapvz/providers/azure/manifest-schema.yml index 8d9a34d..5fe33c2 100644 --- a/bootstrapvz/providers/azure/manifest-schema.yml +++ b/bootstrapvz/providers/azure/manifest-schema.yml @@ -26,7 +26,7 @@ properties: properties: backing: type: string - enum: [raw] + enum: [vhd] partitions: type: object properties: diff --git a/bootstrapvz/providers/azure/tasks/image.py b/bootstrapvz/providers/azure/tasks/image.py deleted file mode 100644 index e940ee2..0000000 --- a/bootstrapvz/providers/azure/tasks/image.py +++ /dev/null @@ -1,28 +0,0 @@ -from bootstrapvz.base import Task -from bootstrapvz.common import phases - - -class ConvertToVhd(Task): - description = 'Convert raw image to vhd disk' - phase = phases.image_registration - - @classmethod - def run(cls, info): - image_name = info.manifest.image['name'].format(**info.manifest_vars) - filename = image_name + '.vhd' - import os.path - destination = os.path.join(info.manifest.bootstrapper['workspace'], filename) - - file_size = os.path.getsize(info.volume.image_path) - rounded_vol_size = str(((file_size / (1024 * 1024) + 1) * (1024 * 1024))) - - from bootstrapvz.common.tools import log_check_call - log_check_call(['qemu-img', 'resize', info.volume.image_path, rounded_vol_size]) - log_check_call(['qemu-img', 'convert', - '-o', 'subformat=fixed', - '-O', 'vpc', - info.volume.image_path, destination]) - os.remove(info.volume.image_path) - import logging - log = logging.getLogger(__name__) - log.info('The volume image has been moved to ' + destination)