Added support for boot from volume (or snapshot)

This commit is contained in:
Gaurav Gupta 2011-10-25 13:45:59 -07:00
parent 5c38baf65a
commit c37a8b3371
3 changed files with 69 additions and 12 deletions

@ -26,7 +26,7 @@ class BootingManagerWithFind(base.ManagerWithFind):
meta=None, files=None, zone_blob=None, userdata=None,
reservation_id=None, return_raw=False, min_count=None,
max_count=None, security_groups=None, key_name=None,
availability_zone=None):
availability_zone=None, block_device_mapping=None):
"""
Create (boot) a new server.
@ -51,6 +51,8 @@ class BootingManagerWithFind(base.ManagerWithFind):
:param key_name: (optional extension) name of keypair to inject into
the instance
:param availability_zone: The :class:`Zone`.
:param block_device_mapping: A list of dict of block device mappingsi
for this server.
"""
body = {"server": {
"name": name,
@ -99,5 +101,33 @@ class BootingManagerWithFind(base.ManagerWithFind):
if availability_zone:
body["server"]["availability_zone"] = availability_zone
# Block device mappings are passed as a list of dictionaries
if block_device_mapping:
bdm = body['server']['block_device_mapping'] = []
for device_name, mapping in block_device_mapping.items():
#
# The mapping is in the format:
# <id>:[<type>]:[<size(GB)>]:[<delete_on_terminate>]
#
bdm_dict = {
'device_name': device_name }
mapping_parts = mapping.split(':')
id = mapping_parts[0]
if len(mapping_parts) == 1:
bdm_dict['volume_id'] = id
if len(mapping_parts) > 1:
type = mapping_parts[1]
if type.startswith('snap'):
bdm_dict['snapshot_id'] = id
else:
bdm_dict['volume_id'] = id
if len(mapping_parts) > 2:
bdm_dict['volume_size'] = mapping_parts[2]
if len(mapping_parts) > 3:
bdm_dict['delete_on_termination'] = mapping_parts[3]
bdm.append(bdm_dict)
return self._create(resource_url, body, response_key,
return_raw=return_raw)

@ -327,7 +327,8 @@ class ServerManager(local_base.BootingManagerWithFind):
def create(self, name, image, flavor, meta=None, files=None,
zone_blob=None, reservation_id=None, min_count=None,
max_count=None, security_groups=None, userdata=None,
key_name=None, availability_zone=None):
key_name=None, availability_zone=None,
block_device_mapping=None):
# TODO: (anthony) indicate in doc string if param is an extension
# and/or optional
"""
@ -354,19 +355,32 @@ class ServerManager(local_base.BootingManagerWithFind):
:param key_name: (optional extension) name of previously created
keypair to inject into the instance.
:param availability_zone: The :class:`Zone`.
:param block_device_mapping: (optional extension) A list of dict of
block device mappings for this server.
"""
print block_device_mapping
if not min_count:
min_count = 1
if not max_count:
max_count = min_count
if min_count > max_count:
min_count = max_count
return self._boot("/servers", "server", name, image, flavor,
meta=meta, files=files, userdata=userdata,
zone_blob=zone_blob, reservation_id=reservation_id,
min_count=min_count, max_count=max_count,
security_groups=security_groups, key_name=key_name,
availability_zone=availability_zone)
if block_device_mapping:
return self._boot("/os-volumes_boot", "server",
name, image, flavor,
meta=meta, files=files, userdata=userdata,
zone_blob=zone_blob, reservation_id=reservation_id,
min_count=min_count, max_count=max_count,
security_groups=security_groups, key_name=key_name,
availability_zone=availability_zone,
block_device_mapping=block_device_mapping)
else:
return self._boot("/servers", "server", name, image, flavor,
meta=meta, files=files, userdata=userdata,
zone_blob=zone_blob, reservation_id=reservation_id,
min_count=min_count, max_count=max_count,
security_groups=security_groups, key_name=key_name,
availability_zone=availability_zone)
def update(self, server, name=None):
"""

@ -105,9 +105,16 @@ def _boot(cs, args, reservation_id=None, min_count=None, max_count=None):
security_groups = args.security_groups.split(',')
else:
security_groups = None
block_device_mapping = {}
for bdm in args.block_device_mapping:
device_name, mapping = bdm.split('=', 1)
block_device_mapping[device_name] = mapping
return (args.name, image, flavor, metadata, files, key_name,
reservation_id, min_count, max_count, user_data, \
availability_zone, security_groups)
availability_zone, security_groups, block_device_mapping)
@utils.arg('--flavor',
@ -155,11 +162,17 @@ def _boot(cs, args, reservation_id=None, min_count=None, max_count=None):
default=None,
metavar='<security_groups>',
help="comma separated list of security group names.")
@utils.arg('--block_device_mapping',
metavar="<dev_name=mapping>",
action='append',
default=[],
help="Block device mapping in the format "
"<dev_name=<id>:<type>:<size(GB)>:<delete_on_terminate>.")
def do_boot(cs, args):
"""Boot a new server."""
name, image, flavor, metadata, files, key_name, reservation_id, \
min_count, max_count, user_data, availability_zone, \
security_groups = _boot(cs, args)
security_groups, block_device_mapping = _boot(cs, args)
server = cs.servers.create(args.name, image, flavor,
meta=metadata,
@ -169,8 +182,8 @@ def do_boot(cs, args):
userdata=user_data,
availability_zone=availability_zone,
security_groups=security_groups,
key_name=key_name)
key_name=key_name,
block_device_mapping=block_device_mapping)
info = server._info
flavor = info.get('flavor', {})