Don't use DictClass for provider namespaces

It's a hack only for the manifest vars and shouldn't be used for anything else
This commit is contained in:
Anders Ingemann 2014-04-10 00:20:35 +02:00
parent d84e02247a
commit 3b23ccf92c
8 changed files with 67 additions and 68 deletions

View file

@ -68,12 +68,24 @@ class BootstrapInformation(object):
# Add a dictionary that can be accessed via info._pluginname for the provider and every plugin
# Information specific to the module can be added to that 'namespace', this avoids clutter.
providername = manifest.modules['provider'].__name__.split('.')[-1]
setattr(self, '_' + providername, DictClass())
setattr(self, '_' + providername, {})
for plugin in manifest.modules['plugins']:
pluginname = plugin.__name__.split('.')[-1]
setattr(self, '_' + pluginname, DictClass())
setattr(self, '_' + pluginname, {})
def __create_manifest_vars(self, manifest, additional_vars={}):
class DictClass(dict):
"""Tiny extension of dict to allow setting and getting keys via attributes
"""
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, value):
self[name] = value
def __delattr__(self, name):
del self[name]
def set_manifest_vars(obj, data):
"""Runs through the manifest and creates DictClasses for every key
@ -109,16 +121,3 @@ class BootstrapInformation(object):
# They are added last so that they may override previous variables
set_manifest_vars(manifest_vars, additional_vars)
return manifest_vars
class DictClass(dict):
"""Tiny extension of dict to allow setting and getting keys via attributes
"""
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, value):
self[name] = value
def __delattr__(self, name):
del self[name]

View file

@ -18,10 +18,10 @@ class AddFolderMounts(Task):
@classmethod
def run(cls, info):
info._minimize_size.foldermounts = os.path.join(info.workspace, 'minimize_size')
os.mkdir(info._minimize_size.foldermounts)
info._minimize_size['foldermounts'] = os.path.join(info.workspace, 'minimize_size')
os.mkdir(info._minimize_size['foldermounts'])
for folder in folders:
temp_path = os.path.join(info._minimize_size.foldermounts, folder.replace('/', '_'))
temp_path = os.path.join(info._minimize_size['foldermounts'], folder.replace('/', '_'))
os.mkdir(temp_path)
full_path = os.path.join(info.root, folder)
@ -37,14 +37,14 @@ class RemoveFolderMounts(Task):
def run(cls, info):
import shutil
for folder in folders:
temp_path = os.path.join(info._minimize_size.foldermounts, folder.replace('/', '_'))
temp_path = os.path.join(info._minimize_size['foldermounts'], folder.replace('/', '_'))
full_path = os.path.join(info.root, folder)
info.volume.partition_map.root.remove_mount(full_path)
shutil.rmtree(temp_path)
os.rmdir(info._minimize_size.foldermounts)
del info._minimize_size.foldermounts
os.rmdir(info._minimize_size['foldermounts'])
del info._minimize_size['foldermounts']
class AddRequiredCommands(Task):

View file

@ -34,9 +34,9 @@ class CreateFromSnapshot(Task):
@classmethod
def run(cls, info):
snapshot = info.manifest.plugins['prebootstrapped']['snapshot']
ebs_volume = info._ec2.connection.create_volume(info.volume.size.get_qty_in('GiB'),
info._ec2.host['availabilityZone'],
snapshot=snapshot)
ebs_volume = info._ec2['connection'].create_volume(info.volume.size.get_qty_in('GiB'),
info._ec2['host']['availabilityZone'],
snapshot=snapshot)
while ebs_volume.volume_state() != 'available':
time.sleep(5)
ebs_volume.update()

View file

@ -21,8 +21,8 @@ class CheckBoxPath(Task):
from bootstrapvz.common.exceptions import TaskError
msg = 'The vagrant box `{name}\' already exists at `{path}\''.format(name=box_name, path=box_path)
raise TaskError(msg)
info._vagrant.box_name = box_name
info._vagrant.box_path = box_path
info._vagrant['box_name'] = box_name
info._vagrant['box_path'] = box_path
class CreateVagrantBoxDir(Task):
@ -32,8 +32,8 @@ class CreateVagrantBoxDir(Task):
@classmethod
def run(cls, info):
info._vagrant.folder = os.path.join(info.workspace, 'vagrant')
os.mkdir(info._vagrant.folder)
info._vagrant['folder'] = os.path.join(info.workspace, 'vagrant')
os.mkdir(info._vagrant['folder'])
class AddPackages(Task):
@ -137,7 +137,7 @@ class PackageBox(Task):
@classmethod
def run(cls, info):
vagrantfile_source = os.path.join(assets, 'Vagrantfile')
vagrantfile = os.path.join(info._vagrant.folder, 'Vagrantfile')
vagrantfile = os.path.join(info._vagrant['folder'], 'Vagrantfile')
shutil.copy(vagrantfile_source, vagrantfile)
import random
@ -146,26 +146,26 @@ class PackageBox(Task):
sed_i(vagrantfile, '\\[MAC_ADDRESS\\]', mac_address)
metadata_source = os.path.join(assets, 'metadata.json')
metadata = os.path.join(info._vagrant.folder, 'metadata.json')
metadata = os.path.join(info._vagrant['folder'], 'metadata.json')
shutil.copy(metadata_source, metadata)
from bootstrapvz.common.tools import log_check_call
disk_name = 'box-disk1.{ext}'.format(ext=info.volume.extension)
disk_link = os.path.join(info._vagrant.folder, disk_name)
disk_link = os.path.join(info._vagrant['folder'], disk_name)
log_check_call(['ln', '-s', info.volume.image_path, disk_link])
ovf_path = os.path.join(info._vagrant.folder, 'box.ovf')
ovf_path = os.path.join(info._vagrant['folder'], 'box.ovf')
cls.write_ovf(info, ovf_path, mac_address, disk_name)
box_files = os.listdir(info._vagrant.folder)
box_files = os.listdir(info._vagrant['folder'])
log_check_call(['tar', '--create', '--gzip', '--dereference',
'--file', info._vagrant.box_path,
'--directory', info._vagrant.folder]
'--file', info._vagrant['box_path'],
'--directory', info._vagrant['folder']]
+ box_files
)
import logging
logging.getLogger(__name__).info('The vagrant box has been placed at {box_path}'
.format(box_path=info._vagrant.box_path))
.format(box_path=info._vagrant['box_path']))
@classmethod
def write_ovf(cls, info, destination, mac_address, disk_name):
@ -207,16 +207,16 @@ class PackageBox(Task):
attr(disk, 'ovf:uuid', volume_uuid)
[system] = root.findall('./ovf:VirtualSystem', namespaces)
attr(system, 'ovf:id', info._vagrant.box_name)
attr(system, 'ovf:id', info._vagrant['box_name'])
[sysid] = system.findall('./ovf:VirtualHardwareSection/ovf:System/'
'vssd:VirtualSystemIdentifier', namespaces)
sysid.text = info._vagrant.box_name
sysid.text = info._vagrant['box_name']
[machine] = system.findall('./vbox:Machine', namespaces)
import uuid
attr(machine, 'ovf:uuid', uuid.uuid4())
attr(machine, 'ovf:name', info._vagrant.box_name)
attr(machine, 'ovf:name', info._vagrant['box_name'])
from datetime import datetime
attr(machine, 'ovf:lastStateChange', datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ'))
[nic] = machine.findall('./ovf:Hardware/ovf:Network/ovf:Adapter', namespaces)
@ -237,5 +237,5 @@ class RemoveVagrantBoxDir(Task):
@classmethod
def run(cls, info):
shutil.rmtree(info._vagrant.folder)
del info._vagrant.folder
shutil.rmtree(info._vagrant['folder'])
del info._vagrant['folder']

View file

@ -21,13 +21,13 @@ class AMIName(Task):
ami_name = info.manifest.image['name'].format(**info.manifest_vars)
ami_description = info.manifest.image['description'].format(**info.manifest_vars)
images = info._ec2.connection.get_all_images()
images = info._ec2['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._ec2.ami_name = ami_name
info._ec2.ami_description = ami_description
info._ec2['ami_name'] = ami_name
info._ec2['ami_description'] = ami_description
class BundleImage(Task):
@ -37,7 +37,7 @@ class BundleImage(Task):
@classmethod
def run(cls, info):
bundle_name = 'bundle-{id}'.format(id=info.run_id)
info._ec2.bundle_path = os.path.join(info.workspace, bundle_name)
info._ec2['bundle_path'] = os.path.join(info.workspace, bundle_name)
arch = {'i386': 'i386', 'amd64': 'x86_64'}.get(info.manifest.system['architecture'])
log_check_call(['euca-bundle-image',
'--image', info.volume.image_path,
@ -46,8 +46,8 @@ class BundleImage(Task):
'--privatekey', info.credentials['private-key'],
'--cert', info.credentials['certificate'],
'--ec2cert', cert_ec2,
'--destination', info._ec2.bundle_path,
'--prefix', info._ec2.ami_name])
'--destination', info._ec2['bundle_path'],
'--prefix', info._ec2['ami_name']])
class UploadImage(Task):
@ -57,21 +57,21 @@ 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':
manifest_file = os.path.join(info._ec2['bundle_path'], info._ec2['ami_name'] + '.manifest.xml')
if info._ec2['host']['region'] == 'us-east-1':
s3_url = 'https://s3.amazonaws.com/'
elif info._ec2.host['region'] == 'cn-north-1':
elif info._ec2['host']['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'])
info._ec2.manifest_location = info.manifest.image['bucket'] + '/' + info._ec2.ami_name + '.manifest.xml'
s3_url = 'https://s3-{region}.amazonaws.com/'.format(region=info._ec2['host']['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'],
'--manifest', manifest_file,
'--access-key', info.credentials['access-key'],
'--secret-key', info.credentials['secret-key'],
'--url', s3_url,
'--region', info._ec2.host['region'],
'--region', info._ec2['host']['region'],
'--ec2cert', cert_ec2])
@ -83,8 +83,8 @@ class RemoveBundle(Task):
@classmethod
def run(cls, info):
from shutil import rmtree
rmtree(info._ec2.bundle_path)
del info._ec2.bundle_path
rmtree(info._ec2['bundle_path'])
del info._ec2['bundle_path']
class RegisterAMI(Task):
@ -94,13 +94,13 @@ class RegisterAMI(Task):
@classmethod
def run(cls, info):
registration_params = {'name': info._ec2.ami_name,
'description': info._ec2.ami_description}
registration_params = {'name': info._ec2['ami_name'],
'description': info._ec2['ami_description']}
registration_params['architecture'] = {'i386': 'i386',
'amd64': 'x86_64'}.get(info.manifest.system['architecture'])
if info.manifest.volume['backing'] == 's3':
registration_params['image_location'] = info._ec2.manifest_location
registration_params['image_location'] = info._ec2['manifest_location']
else:
root_dev_name = {'pvm': '/dev/sda',
'hvm': '/dev/xvda'}.get(info.manifest.data['virtualization'])
@ -108,7 +108,7 @@ class RegisterAMI(Task):
from boto.ec2.blockdevicemapping import BlockDeviceType
from boto.ec2.blockdevicemapping import BlockDeviceMapping
block_device = BlockDeviceType(snapshot_id=info._ec2.snapshot.id, delete_on_termination=True,
block_device = BlockDeviceType(snapshot_id=info._ec2['snapshot'].id, delete_on_termination=True,
size=info.volume.size.get_qty_in('GiB'))
registration_params['block_device_map'] = BlockDeviceMapping()
registration_params['block_device_map'][root_dev_name] = block_device
@ -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['host']['region'],
info.manifest.system['architecture']])
info._ec2.image = info._ec2.connection.register_image(**registration_params)
info._ec2['image'] = info._ec2['connection'].register_image(**registration_params)

View file

@ -41,6 +41,6 @@ class Connect(Task):
@classmethod
def run(cls, info):
from boto.ec2 import connect_to_region
info._ec2.connection = connect_to_region(info._ec2.host['region'],
aws_access_key_id=info.credentials['access-key'],
aws_secret_access_key=info.credentials['secret-key'])
info._ec2['connection'] = connect_to_region(info._ec2['host']['region'],
aws_access_key_id=info.credentials['access-key'],
aws_secret_access_key=info.credentials['secret-key'])

View file

@ -8,7 +8,7 @@ class Create(Task):
@classmethod
def run(cls, info):
info.volume.create(info._ec2.connection, info._ec2.host['availabilityZone'])
info.volume.create(info._ec2['connection'], info._ec2['host']['availabilityZone'])
class Attach(Task):
@ -18,7 +18,7 @@ class Attach(Task):
@classmethod
def run(cls, info):
info.volume.attach(info._ec2.host['instanceId'])
info.volume.attach(info._ec2['host']['instanceId'])
class Snapshot(Task):
@ -27,4 +27,4 @@ class Snapshot(Task):
@classmethod
def run(cls, info):
info._ec2.snapshot = info.volume.snapshot()
info._ec2['snapshot'] = info.volume.snapshot()

View file

@ -25,4 +25,4 @@ class GetInfo(Task):
import json
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['host'] = json.load(response)