S3 images can now be bootstrapped outside EC2.
However, this fix adds the requirement of a "region" setting.
At some point we could make "region" optional and fail when bootstrap-vz
is run outside EC2 and no "region" is set.
This commit is contained in:
Anders Ingemann 2014-05-03 10:43:14 +02:00
parent a1bc55fbff
commit 056f1968c1
7 changed files with 45 additions and 20 deletions

View file

@ -69,7 +69,6 @@ def resolve_tasks(taskset, manifest):
taskset.update([tasks.host.AddExternalCommands,
tasks.packages.DefaultPackages,
tasks.connection.GetCredentials,
tasks.host.GetInfo,
tasks.ami.AMIName,
tasks.connection.Connect,
@ -97,11 +96,13 @@ def resolve_tasks(taskset, manifest):
else:
taskset.update(task_groups.bootloader_set.get(manifest.system['bootloader']))
backing_specific_tasks = {'ebs': [tasks.ebs.Create,
backing_specific_tasks = {'ebs': [tasks.host.GetInstanceMetadata,
tasks.ebs.Create,
tasks.ebs.Attach,
filesystem.FStab,
tasks.ebs.Snapshot],
's3': [loopback.AddRequiredCommands,
tasks.host.SetRegion,
loopback.Create,
volume.Attach,
tasks.filesystem.S3FStab,

View file

@ -22,9 +22,12 @@
"properties": {
"bucket": {
"type": "string"
},
"region": {
"$ref": "#/definitions/aws-region"
}
},
"required": ["bucket"]
"required": ["bucket", "region"]
},
"volume": {
"type": "object",
@ -38,5 +41,14 @@
}
}
},
"required": ["image"]
"required": ["image"],
"definitions": {
"aws-region": {
"enum": ["ap-northeast-1", "ap-southeast-1",
"ap-southeast-2", "eu-west-1",
"sa-east-1", "us-east-1",
"us-gov-west-1", "us-west-1",
"us-west-2", "cn-north-1"]
}
}
}

View file

@ -58,12 +58,12 @@ class UploadImage(Task):
@classmethod
def run(cls, info):
manifest_file = os.path.join(info._ec2['bundle_path'], info._ec2['ami_name'] + '.manifest.xml')
if info._ec2['host']['region'] == 'us-east-1':
if info._ec2['region'] == 'us-east-1':
s3_url = 'https://s3.amazonaws.com/'
elif info._ec2['host']['region'] == 'cn-north-1':
elif info._ec2['region'] == 'cn-north-1':
s3_url = 'https://s3.cn-north-1.amazonaws.com.cn'
else:
s3_url = 'https://s3-{region}.amazonaws.com/'.format(region=info._ec2['host']['region'])
s3_url = 'https://s3-{region}.amazonaws.com/'.format(region=info._ec2['region'])
info._ec2['manifest_location'] = info.manifest.image['bucket'] + '/' + info._ec2['ami_name'] + '.manifest.xml'
log_check_call(['euca-upload-bundle',
'--bucket', info.manifest.image['bucket'],
@ -71,7 +71,7 @@ class UploadImage(Task):
'--access-key', info.credentials['access-key'],
'--secret-key', info.credentials['secret-key'],
'--url', s3_url,
'--region', info._ec2['host']['region'],
'--region', info._ec2['region'],
'--ec2cert', cert_ec2])
@ -119,7 +119,7 @@ class RegisterAMI(Task):
registration_params['virtualization_type'] = 'paravirtual'
akis_path = os.path.join(os.path.dirname(__file__), 'ami-akis.json')
from bootstrapvz.common.tools import config_get
registration_params['kernel_id'] = config_get(akis_path, [info._ec2['host']['region'],
registration_params['kernel_id'] = config_get(akis_path, [info._ec2['region'],
info.manifest.system['architecture']])
info._ec2['image'] = info._ec2['connection'].register_image(**registration_params)

View file

@ -36,11 +36,11 @@ class GetCredentials(Task):
class Connect(Task):
description = 'Connecting to EC2'
phase = phases.preparation
predecessors = [GetCredentials, host.GetInfo]
predecessors = [GetCredentials, host.GetInstanceMetadata, host.SetRegion]
@classmethod
def run(cls, info):
from boto.ec2 import connect_to_region
info._ec2['connection'] = connect_to_region(info._ec2['host']['region'],
info._ec2['connection'] = connect_to_region(info._ec2['region'],
aws_access_key_id=info.credentials['access-key'],
aws_secret_access_key=info.credentials['secret-key'])

View file

@ -15,7 +15,7 @@ class AddExternalCommands(Task):
info.host_dependencies['euca-upload-bundle'] = 'euca2ools'
class GetInfo(Task):
class GetInstanceMetadata(Task):
description = 'Retrieving instance metadata'
phase = phases.preparation
@ -26,3 +26,13 @@ class GetInfo(Task):
metadata_url = 'http://169.254.169.254/latest/dynamic/instance-identity/document'
response = urllib2.urlopen(url=metadata_url, timeout=5)
info._ec2['host'] = json.load(response)
info._ec2['region'] = info._ec2['host']['region']
class SetRegion(Task):
description = 'Setting the AWS region'
phase = phases.preparation
@classmethod
def run(cls, info):
info._ec2['region'] = info.manifest.image['region']

View file

@ -15,7 +15,8 @@
"image": {
"name": "debian-{system.release}-{system.architecture}-{virtualization}-{%Y}-{%m}-{%d}",
"description": "Debian {system.release} {system.architecture} AMI",
"bucket": "debian-amis-cn-north-1"
"bucket": "debian-amis-cn-north-1",
"region": "cn-north-1"
},
"system": {
"release": "wheezy",
@ -38,10 +39,10 @@
}
}
},
"plugins": {
"cloud_init": {
"username": "admin",
"disable_modules": [ "landscape", "byobu", "ssh-import-id" ]
}
}
"plugins": {
"cloud_init": {
"username": "admin",
"disable_modules": [ "landscape", "byobu", "ssh-import-id" ]
}
}
}

View file

@ -15,7 +15,8 @@
"image": {
"name": "debian-{system.release}-{system.architecture}-{virtualization}-{%y}{%m}{%d}",
"description": "Debian {system.release} {system.architecture} AMI",
"bucket": "debian-amis"
"bucket": "debian-amis",
"region": "us-west-1"
},
"system": {
"release": "wheezy",