summaryrefslogtreecommitdiffstats
path: root/nova/compute
diff options
context:
space:
mode:
authorChris Behrens <cbehrens@codestud.com>2011-07-07 05:56:15 -0700
committerChris Behrens <cbehrens@codestud.com>2011-07-07 05:56:15 -0700
commite817896c7aaf43822cf363a48fac60f013a5ecb0 (patch)
tree0035dcc42ce5b2737d0a424975980cad4e8e0b77 /nova/compute
parentace9aa5d91d839f66998c39a977857b7a7c466a4 (diff)
parent44d4994eadc7413e27ebe60d7880278fc0365b6f (diff)
merged trunk
Diffstat (limited to 'nova/compute')
-rw-r--r--nova/compute/api.py98
-rw-r--r--nova/compute/manager.py34
2 files changed, 99 insertions, 33 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index d2f104805..4ac0ffef2 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -23,6 +23,7 @@ import novaclient
import re
import time
+from nova import block_device
from nova import db
from nova import exception
from nova import flags
@@ -33,7 +34,6 @@ from nova import quota
from nova import rpc
from nova import utils
from nova import volume
-from nova.api.ec2 import ec2utils
from nova.compute import instance_types
from nova.compute import power_state
from nova.compute.utils import terminate_volumes
@@ -219,7 +219,7 @@ class API(base.Base):
if reservation_id is None:
reservation_id = utils.generate_uid('r')
- root_device_name = ec2utils.properties_root_device_name(
+ root_device_name = block_device.properties_root_device_name(
image['properties'])
base_options = {
@@ -251,34 +251,64 @@ class API(base.Base):
return (num_instances, base_options, image)
- def _update_image_block_device_mapping(self, elevated_context, instance_id,
+ @staticmethod
+ def _ephemeral_size(instance_type, ephemeral_name):
+ num = block_device.ephemeral_num(ephemeral_name)
+
+ # TODO(yamahata): ephemeralN where N > 0
+ # Only ephemeral0 is allowed for now because InstanceTypes
+ # table only allows single local disk, local_gb.
+ # In order to enhance it, we need to add a new columns to
+ # instance_types table.
+ if num > 0:
+ return 0
+
+ return instance_type.get('local_gb')
+
+ def _update_image_block_device_mapping(self, elevated_context,
+ instance_type, instance_id,
mappings):
"""tell vm driver to create ephemeral/swap device at boot time by
updating BlockDeviceMapping
"""
- for bdm in ec2utils.mappings_prepend_dev(mappings):
+ instance_type = (instance_type or
+ instance_types.get_default_instance_type())
+
+ for bdm in block_device.mappings_prepend_dev(mappings):
LOG.debug(_("bdm %s"), bdm)
virtual_name = bdm['virtual']
if virtual_name == 'ami' or virtual_name == 'root':
continue
- assert (virtual_name == 'swap' or
- virtual_name.startswith('ephemeral'))
+ if not block_device.is_swap_or_ephemeral(virtual_name):
+ continue
+
+ size = 0
+ if virtual_name == 'swap':
+ size = instance_type.get('swap', 0)
+ elif block_device.is_ephemeral(virtual_name):
+ size = self._ephemeral_size(instance_type, virtual_name)
+
+ if size == 0:
+ continue
+
values = {
'instance_id': instance_id,
'device_name': bdm['device'],
- 'virtual_name': virtual_name, }
+ 'virtual_name': virtual_name,
+ 'volume_size': size}
self.db.block_device_mapping_update_or_create(elevated_context,
values)
- def _update_block_device_mapping(self, elevated_context, instance_id,
+ def _update_block_device_mapping(self, elevated_context,
+ instance_type, instance_id,
block_device_mapping):
"""tell vm driver to attach volume at boot time by updating
BlockDeviceMapping
"""
+ LOG.debug(_("block_device_mapping %s"), block_device_mapping)
for bdm in block_device_mapping:
- LOG.debug(_('bdm %s'), bdm)
assert 'device_name' in bdm
values = {'instance_id': instance_id}
@@ -287,10 +317,18 @@ class API(base.Base):
'no_device'):
values[key] = bdm.get(key)
+ virtual_name = bdm.get('virtual_name')
+ if (virtual_name is not None and
+ block_device.is_ephemeral(virtual_name)):
+ size = self._ephemeral_size(instance_type, virtual_name)
+ if size == 0:
+ continue
+ values['volume_size'] = size
+
# NOTE(yamahata): NoDevice eliminates devices defined in image
# files by command line option.
# (--block-device-mapping)
- if bdm.get('virtual_name') == 'NoDevice':
+ if virtual_name == 'NoDevice':
values['no_device'] = True
for k in ('delete_on_termination', 'volume_id',
'snapshot_id', 'volume_id', 'volume_size',
@@ -300,8 +338,8 @@ class API(base.Base):
self.db.block_device_mapping_update_or_create(elevated_context,
values)
- def create_db_entry_for_new_instance(self, context, image, base_options,
- security_group, block_device_mapping, num=1):
+ def create_db_entry_for_new_instance(self, context, instance_type, image,
+ base_options, security_group, block_device_mapping, num=1):
"""Create an entry in the DB for this new instance,
including any related table updates (such as security group,
etc).
@@ -334,12 +372,12 @@ class API(base.Base):
security_group_id)
# BlockDeviceMapping table
- self._update_image_block_device_mapping(elevated, instance_id,
- image['properties'].get('mappings', []))
- self._update_block_device_mapping(elevated, instance_id,
+ self._update_image_block_device_mapping(elevated, instance_type,
+ instance_id, image['properties'].get('mappings', []))
+ self._update_block_device_mapping(elevated, instance_type, instance_id,
image['properties'].get('block_device_mapping', []))
# override via command line option
- self._update_block_device_mapping(elevated, instance_id,
+ self._update_block_device_mapping(elevated, instance_type, instance_id,
block_device_mapping)
# Set sane defaults if not specified
@@ -457,7 +495,8 @@ class API(base.Base):
instances = []
LOG.debug(_("Going to run %s instances..."), num_instances)
for num in range(num_instances):
- instance = self.create_db_entry_for_new_instance(context, image,
+ instance = self.create_db_entry_for_new_instance(context,
+ instance_type, image,
base_options, security_group,
block_device_mapping, num=num)
instances.append(instance)
@@ -1201,11 +1240,20 @@ class API(base.Base):
"""Delete the given metadata item from an instance."""
self.db.instance_metadata_delete(context, instance_id, key)
- def update_or_create_instance_metadata(self, context, instance_id,
- metadata):
- """Updates or creates instance metadata."""
- combined_metadata = self.get_instance_metadata(context, instance_id)
- combined_metadata.update(metadata)
- self._check_metadata_properties_quota(context, combined_metadata)
- self.db.instance_metadata_update_or_create(context, instance_id,
- metadata)
+ def update_instance_metadata(self, context, instance_id,
+ metadata, delete=False):
+ """Updates or creates instance metadata.
+
+ If delete is True, metadata items that are not specified in the
+ `metadata` argument will be deleted.
+
+ """
+ if delete:
+ _metadata = metadata
+ else:
+ _metadata = self.get_instance_metadata(context, instance_id)
+ _metadata.update(metadata)
+
+ self._check_metadata_properties_quota(context, _metadata)
+ self.db.instance_metadata_update(context, instance_id, _metadata, True)
+ return _metadata
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index cb6617c33..d38213083 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -45,6 +45,7 @@ import functools
from eventlet import greenthread
import nova.context
+from nova import block_device
from nova import exception
from nova import flags
import nova.image
@@ -260,6 +261,8 @@ class ComputeManager(manager.SchedulerDependentManager):
volume_api = volume.API()
block_device_mapping = []
+ swap = None
+ ephemerals = []
for bdm in self.db.block_device_mapping_get_all_by_instance(
context, instance_id):
LOG.debug(_("setting up bdm %s"), bdm)
@@ -267,11 +270,18 @@ class ComputeManager(manager.SchedulerDependentManager):
if bdm['no_device']:
continue
if bdm['virtual_name']:
- # TODO(yamahata):
- # block devices for swap and ephemeralN will be
- # created by virt driver locally in compute node.
- assert (bdm['virtual_name'] == 'swap' or
- bdm['virtual_name'].startswith('ephemeral'))
+ virtual_name = bdm['virtual_name']
+ device_name = bdm['device_name']
+ assert block_device.is_swap_or_ephemeral(virtual_name)
+ if virtual_name == 'swap':
+ swap = {'device_name': device_name,
+ 'swap_size': bdm['volume_size']}
+ elif block_device.is_ephemeral(virtual_name):
+ eph = {'num': block_device.ephemeral_num(virtual_name),
+ 'virtual_name': virtual_name,
+ 'device_name': device_name,
+ 'size': bdm['volume_size']}
+ ephemerals.append(eph)
continue
if ((bdm['snapshot_id'] is not None) and
@@ -307,7 +317,7 @@ class ComputeManager(manager.SchedulerDependentManager):
'mount_device':
bdm['device_name']})
- return block_device_mapping
+ return (swap, ephemerals, block_device_mapping)
def _run_instance(self, context, instance_id, **kwargs):
"""Launch a new instance with specified options."""
@@ -348,13 +358,21 @@ class ComputeManager(manager.SchedulerDependentManager):
# all vif creation and network injection, maybe this is correct
network_info = []
- bd_mapping = self._setup_block_device_mapping(context, instance_id)
+ (swap, ephemerals,
+ block_device_mapping) = self._setup_block_device_mapping(
+ context, instance_id)
+ block_device_info = {
+ 'root_device_name': instance['root_device_name'],
+ 'swap': swap,
+ 'ephemerals': ephemerals,
+ 'block_device_mapping': block_device_mapping}
# TODO(vish) check to make sure the availability zone matches
self._update_state(context, instance_id, power_state.BUILDING)
try:
- self.driver.spawn(context, instance, network_info, bd_mapping)
+ self.driver.spawn(context, instance,
+ network_info, block_device_info)
except Exception as ex: # pylint: disable=W0702
msg = _("Instance '%(instance_id)s' failed to spawn. Is "
"virtualization enabled in the BIOS? Details: "