From 5dd8c27c6ada726a4ba2b0f4f85888c127f6f0ff Mon Sep 17 00:00:00 2001 From: Anders Ingemann Date: Sun, 7 Jul 2013 20:28:24 +0200 Subject: [PATCH] ImageRegistration task implemented --- manifests/ec2-ebs-pvm.manifest.json | 4 +- providers/ec2/__init__.py | 12 +++-- providers/ec2/manifest.py | 1 + providers/ec2/tasks/ami.py | 76 +++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 providers/ec2/tasks/ami.py diff --git a/manifests/ec2-ebs-pvm.manifest.json b/manifests/ec2-ebs-pvm.manifest.json index 425ed86..38a8247 100644 --- a/manifests/ec2-ebs-pvm.manifest.json +++ b/manifests/ec2-ebs-pvm.manifest.json @@ -11,7 +11,7 @@ "tarball": true }, "image": { - "name" : "debian-{release}-{architecture}-{virtualization}-{year}{month}{day}", + "name" : "debian-{release}-{architecture}-{virtualization}-{%y}{%M}{%d}", "description": "Debian {release} {architecture} AMI ({virtualization})" }, "system": { @@ -28,7 +28,7 @@ }, "plugins": { "admin_user": { - "enabled": true + "enabled": false }, "build_metadata": { "enabled": false, diff --git a/providers/ec2/__init__.py b/providers/ec2/__init__.py index 148ea58..aca29e3 100644 --- a/providers/ec2/__init__.py +++ b/providers/ec2/__init__.py @@ -3,6 +3,7 @@ import logging from tasks import packages from tasks import connection from tasks import host +from tasks import ami from tasks import ebs from tasks import filesystem from tasks import bootstrap @@ -26,6 +27,7 @@ def tasks(tasklist, manifest): host.CheckPackages(), connection.GetCredentials(), host.GetInfo(), + ami.AMIName(), connection.Connect()) if manifest.volume['backing'].lower() == 'ebs': tasklist.add(ebs.CreateVolume(), @@ -35,7 +37,8 @@ def tasks(tasklist, manifest): tasklist.add(filesystem.AddXFSProgs()) if manifest.volume['filesystem'].lower() in ['ext2', 'ext3', 'ext4']: tasklist.add(filesystem.TuneVolumeFS()) - tasklist.add(filesystem.CreateMountDir(), filesystem.MountVolume()) + tasklist.add(filesystem.CreateMountDir(), + filesystem.MountVolume()) if manifest.bootstrapper['tarball']: tasklist.add(bootstrap.MakeTarball()) tasklist.add(bootstrap.Bootstrap(), @@ -68,10 +71,9 @@ def tasks(tasklist, manifest): filesystem.DeleteMountDir()) if manifest.volume['backing'].lower() == 'ebs': tasklist.add(ebs.DetachVolume(), - ebs.CreateSnapshot()) - - from common.tasks import TriggerRollback - tasklist.add(TriggerRollback()) + ebs.CreateSnapshot(), + ebs.DeleteVolume()) + tasklist.add(ami.RegisterAMI()) def rollback_tasks(tasklist, tasks_completed, manifest): diff --git a/providers/ec2/manifest.py b/providers/ec2/manifest.py index 6c86356..d2e0f2c 100644 --- a/providers/ec2/manifest.py +++ b/providers/ec2/manifest.py @@ -12,3 +12,4 @@ class Manifest(base.Manifest): super(Manifest, self).parse(data) self.credentials = data['credentials'] self.virtualization = data['virtualization'] + self.image = data['image'] diff --git a/providers/ec2/tasks/ami.py b/providers/ec2/tasks/ami.py new file mode 100644 index 0000000..fbabbf3 --- /dev/null +++ b/providers/ec2/tasks/ami.py @@ -0,0 +1,76 @@ +from base import Task +from common import phases +from ebs import CreateSnapshot +from connection import Connect +from common.exceptions import TaskError + + +class AMIName(Task): + description = 'Determining the AMI name' + phase = phases.preparation + after = [Connect] + + def run(self, info): + image_vars = {'release': info.manifest.system['release'], + 'architecture': info.manifest.system['architecture'], + 'virtualization': info.manifest.virtualization, + 'backing': info.manifest.volume['backing']} + from datetime import datetime + now = datetime.now() + time_vars = ['%a', '%A', '%b', '%B', '%c', '%d', '%f', '%H', + '%I', '%j', '%m', '%M', '%p', '%S', '%U', '%w', + '%W', '%x', '%X', '%y', '%Y', '%z', '%Z'] + for var in time_vars: + image_vars[var] = now.strftime(var) + + ami_name = info.manifest.image['name'].format(**image_vars) + ami_description = info.manifest.image['description'].format(**image_vars) + + images = info.connection.get_all_images() + for image in images: + if ami_name == image.name: + msg = 'An image by the name {ami_name} already exists.'.format(ami_name=ami_name) + raise TaskError(msg) + info.ami_name = ami_name + info.ami_description = ami_description + + +class RegisterAMI(Task): + description = 'Registering the image as an AMI' + phase = phases.image_registration + after = [CreateSnapshot] + + def run(self, info): + arch = {'i386': 'i386', + 'amd64': 'x86_64'}.get(info.manifest.system['architecture']) + kernel_mapping = {'us-east-1': {'amd64': 'aki-88aa75e1', + 'i386': 'aki-b6aa75df'}, + 'us-west-1': {'amd64': 'aki-f77e26b2', + 'i386': 'aki-f57e26b0'}, + 'us-west-2': {'amd64': 'aki-fc37bacc', + 'i386': 'aki-fa37baca'}, + 'eu-west-1': {'amd64': 'aki-71665e05', + 'i386': 'aki-75665e01'}, + 'ap-southeast-1': {'amd64': 'aki-fe1354ac', + 'i386': 'aki-f81354aa'}, + 'ap-southeast-2': {'amd64': 'aki-31990e0b', + 'i386': 'aki-33990e09'}, + 'ap-northeast-1': {'amd64': 'aki-44992845', + 'i386': 'aki-42992843'}, + 'sa-east-1': {'amd64': 'aki-c48f51d9', + 'i386': 'aki-ca8f51d7'}, + 'us-gov-west-1': {'amd64': 'aki-79a4c05a', + 'i386': 'aki-7ba4c058'}} + kernel_id = kernel_mapping.get(info.host['region']).get(info.manifest.system['architecture']) + + from boto.ec2.blockdevicemapping import BlockDeviceType + from boto.ec2.blockdevicemapping import BlockDeviceMapping + block_device = BlockDeviceType(snapshot_id=info.snapshot.id, delete_on_termination=True, + size=int(info.manifest.volume['size']/1024)) + block_device_map = BlockDeviceMapping() + block_device_map['/dev/sda1'] = block_device + + info.image = info.connection.register_image(name=info.ami_name, description=info.ami_description, + architecture=arch, kernel_id=kernel_id, + root_device_name='/dev/sda1', + block_device_map=block_device_map)