2013-07-07 20:28:24 +02:00
|
|
|
from base import Task
|
|
|
|
from common import phases
|
2013-07-14 23:16:37 +02:00
|
|
|
from common.exceptions import TaskError
|
|
|
|
from common.tools import log_check_call
|
2013-07-13 13:55:12 +02:00
|
|
|
from ebs import Snapshot
|
2013-09-15 16:59:56 +02:00
|
|
|
from common.tasks import workspace
|
2013-07-07 20:28:24 +02:00
|
|
|
from connection import Connect
|
2013-12-29 23:21:50 +01:00
|
|
|
from . import assets
|
2013-07-14 23:16:37 +02:00
|
|
|
import os.path
|
|
|
|
|
2013-12-29 23:21:50 +01:00
|
|
|
cert_ec2 = os.path.join(assets, 'certs/cert-ec2.pem')
|
2013-07-07 20:28:24 +02:00
|
|
|
|
|
|
|
|
|
|
|
class AMIName(Task):
|
|
|
|
description = 'Determining the AMI name'
|
|
|
|
phase = phases.preparation
|
2013-11-21 15:54:42 +01:00
|
|
|
predecessors = [Connect]
|
2013-07-07 20:28:24 +02:00
|
|
|
|
2014-01-05 15:57:11 +01:00
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
2013-12-29 16:48:55 +01:00
|
|
|
ami_name = info.manifest.image['name'].format(**info.manifest_vars)
|
|
|
|
ami_description = info.manifest.image['description'].format(**info.manifest_vars)
|
2013-07-07 20:28:24 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
2013-07-13 15:10:04 +02:00
|
|
|
class BundleImage(Task):
|
|
|
|
description = 'Bundling the image'
|
|
|
|
phase = phases.image_registration
|
|
|
|
|
2014-01-05 15:57:11 +01:00
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
2013-12-28 13:56:48 +01:00
|
|
|
bundle_name = 'bundle-{id}'.format(id=info.run_id)
|
2013-09-15 16:59:56 +02:00
|
|
|
info.bundle_path = os.path.join(info.workspace, bundle_name)
|
2013-07-14 23:16:37 +02:00
|
|
|
log_check_call(['/usr/bin/euca-bundle-image',
|
2013-10-27 17:47:39 +01:00
|
|
|
'--image', info.volume.image_path,
|
2013-07-14 23:16:37 +02:00
|
|
|
'--user', info.credentials['user-id'],
|
|
|
|
'--privatekey', info.credentials['private-key'],
|
|
|
|
'--cert', info.credentials['certificate'],
|
|
|
|
'--ec2cert', cert_ec2,
|
|
|
|
'--destination', info.bundle_path,
|
|
|
|
'--prefix', info.ami_name])
|
|
|
|
|
|
|
|
|
|
|
|
class UploadImage(Task):
|
|
|
|
description = 'Uploading the image bundle'
|
|
|
|
phase = phases.image_registration
|
2013-11-21 15:54:42 +01:00
|
|
|
predecessors = [BundleImage]
|
2013-07-14 23:16:37 +02:00
|
|
|
|
2014-01-05 15:57:11 +01:00
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
2013-07-14 23:16:37 +02:00
|
|
|
manifest_file = os.path.join(info.bundle_path, info.ami_name + '.manifest.xml')
|
|
|
|
if info.host['region'] == 'us-east-1':
|
|
|
|
s3_url = 'https://s3.amazonaws.com/'
|
|
|
|
else:
|
|
|
|
s3_url = 'https://s3-{region}.amazonaws.com/'.format(region=info.host['region'])
|
|
|
|
log_check_call(['/usr/bin/euca-upload-bundle',
|
|
|
|
'--bucket', info.manifest.image['bucket'],
|
|
|
|
'--manifest', manifest_file,
|
|
|
|
'--access-key', info.credentials['access-key'],
|
|
|
|
'--secret-key', info.credentials['secret-key'],
|
|
|
|
'--url', s3_url,
|
|
|
|
'--region', info.host['region'],
|
|
|
|
'--ec2cert', cert_ec2])
|
2013-07-13 15:10:04 +02:00
|
|
|
|
|
|
|
|
|
|
|
class RemoveBundle(Task):
|
|
|
|
description = 'Removing the bundle files'
|
|
|
|
phase = phases.cleaning
|
2013-11-21 15:54:42 +01:00
|
|
|
successors = [workspace.DeleteWorkspace]
|
2013-07-13 15:10:04 +02:00
|
|
|
|
2014-01-05 15:57:11 +01:00
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
2013-07-13 15:10:04 +02:00
|
|
|
from shutil import rmtree
|
2013-07-14 23:16:37 +02:00
|
|
|
rmtree(info.bundle_path)
|
|
|
|
del info.bundle_path
|
2013-07-13 15:10:04 +02:00
|
|
|
|
|
|
|
|
2013-07-07 20:28:24 +02:00
|
|
|
class RegisterAMI(Task):
|
|
|
|
description = 'Registering the image as an AMI'
|
|
|
|
phase = phases.image_registration
|
2013-11-21 15:54:42 +01:00
|
|
|
predecessors = [Snapshot, UploadImage]
|
2013-07-07 20:28:24 +02:00
|
|
|
|
2013-10-27 17:47:39 +01:00
|
|
|
# Source: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedKernels.html#AmazonKernelImageIDs
|
2013-12-14 19:37:23 +01:00
|
|
|
kernel_mapping = {'ap-northeast-1': # Asia Pacific (Tokyo) Region
|
|
|
|
{'hd0': {'i386': 'aki-136bf512', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-176bf516'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-196bf518', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-1f6bf51e'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
},
|
|
|
|
'ap-southeast-1': # Asia Pacific (Singapore) Region
|
|
|
|
{'hd0': {'i386': 'aki-ae3973fc', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-503e7402'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-563e7404', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-5e3e740c'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
},
|
|
|
|
'ap-southeast-2': # Asia Pacific (Sydney) Region
|
|
|
|
{'hd0': {'i386': 'aki-cd62fff7', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-c362fff9'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-c162fffb', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-3b1d8001'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
},
|
|
|
|
'eu-west-1': # EU (Ireland) Region
|
|
|
|
{'hd0': {'i386': 'aki-68a3451f', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-52a34525'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-5ea34529', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-58a3452f'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
},
|
|
|
|
'sa-east-1': # South America (Sao Paulo) Region
|
|
|
|
{'hd0': {'i386': 'aki-5b53f446', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-5553f448'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-5753f44a', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-5153f44c'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
},
|
|
|
|
'us-east-1': # US East (Northern Virginia) Region
|
|
|
|
{'hd0': {'i386': 'aki-8f9dcae6', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-919dcaf8'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-659ccb0c', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-499ccb20'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
},
|
|
|
|
'us-gov-west-1': # AWS GovCloud (US)
|
|
|
|
{'hd0': {'i386': 'aki-1fe98d3c', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-1de98d3e'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-63e98d40', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-61e98d42'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
},
|
|
|
|
'us-west-1': # US West (Northern California) Region
|
|
|
|
{'hd0': {'i386': 'aki-8e0531cb', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-880531cd'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-960531d3', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-920531d7'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
},
|
|
|
|
'us-west-2': # US West (Oregon) Region
|
|
|
|
{'hd0': {'i386': 'aki-f08f11c0', # pv-grub-hd0_1.04-i386.gz
|
|
|
|
'amd64': 'aki-fc8f11cc'}, # pv-grub-hd0_1.04-x86_64.gz
|
|
|
|
'hd00': {'i386': 'aki-e28f11d2', # pv-grub-hd00_1.04-i386.gz
|
|
|
|
'amd64': 'aki-e68f11d6'} # pv-grub-hd00_1.04-x86_64.gz
|
|
|
|
}
|
|
|
|
}
|
2013-07-13 13:18:01 +02:00
|
|
|
|
2014-01-05 15:57:11 +01:00
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
2013-12-01 23:50:32 +01:00
|
|
|
registration_params = {'name': info.ami_name,
|
|
|
|
'description': info.ami_description}
|
|
|
|
registration_params['architecture'] = {'i386': 'i386',
|
|
|
|
'amd64': 'x86_64'}.get(info.manifest.system['architecture'])
|
2013-10-27 17:47:39 +01:00
|
|
|
|
2013-12-01 23:50:32 +01:00
|
|
|
if info.manifest.volume['backing'] == 's3':
|
2013-10-27 17:47:39 +01:00
|
|
|
grub_boot_device = 'hd0'
|
|
|
|
else:
|
2014-01-05 02:18:59 +01:00
|
|
|
root_dev_name = {'pvm': '/dev/sda',
|
2014-01-05 14:03:04 +01:00
|
|
|
'hvm': '/dev/xvda'}.get(info.manifest.data['virtualization'])
|
2014-01-05 02:18:59 +01:00
|
|
|
registration_params['root_device_name'] = root_dev_name
|
2013-12-01 23:50:32 +01:00
|
|
|
from base.fs.partitionmaps.none import NoPartitions
|
|
|
|
if isinstance(info.volume.partition_map, NoPartitions):
|
|
|
|
grub_boot_device = 'hd0'
|
|
|
|
else:
|
|
|
|
grub_boot_device = 'hd00'
|
|
|
|
|
|
|
|
from boto.ec2.blockdevicemapping import BlockDeviceType
|
|
|
|
from boto.ec2.blockdevicemapping import BlockDeviceMapping
|
|
|
|
block_device = BlockDeviceType(snapshot_id=info.snapshot.id, delete_on_termination=True,
|
2014-01-19 12:39:07 +01:00
|
|
|
size=info.volume.size.get_qty_in('GiB'))
|
2013-12-01 23:50:32 +01:00
|
|
|
registration_params['block_device_map'] = BlockDeviceMapping()
|
2014-01-05 02:18:59 +01:00
|
|
|
registration_params['block_device_map'][root_dev_name] = block_device
|
2013-12-01 23:50:32 +01:00
|
|
|
|
2014-01-05 14:03:04 +01:00
|
|
|
if info.manifest.data['virtualization'] == 'hvm':
|
2013-12-01 23:50:32 +01:00
|
|
|
registration_params['virtualization_type'] = 'hvm'
|
|
|
|
else:
|
|
|
|
registration_params['virtualization_type'] = 'paravirtual'
|
2014-01-05 15:57:11 +01:00
|
|
|
registration_params['kernel_id'] = (cls.kernel_mapping
|
2013-12-01 23:50:32 +01:00
|
|
|
.get(info.host['region'])
|
|
|
|
.get(grub_boot_device)
|
|
|
|
.get(info.manifest.system['architecture']))
|
|
|
|
|
|
|
|
info.image = info.connection.register_image(**registration_params)
|