mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-22 18:00:35 +00:00
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:
parent
d84e02247a
commit
3b23ccf92c
8 changed files with 67 additions and 68 deletions
|
@ -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]
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'])
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue