summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSandy Walsh <sandy.walsh@rackspace.com>2011-06-20 16:56:59 -0700
committerSandy Walsh <sandy.walsh@rackspace.com>2011-06-20 16:56:59 -0700
commit0d426ae8d0fe4e697648e58d1791e1c40b78deab (patch)
treeae92112358341b1d0826d83736b5d5f9b60272b4
parent83fd1983072246989a9c37d5cf1682068009e3cf (diff)
downloadnova-0d426ae8d0fe4e697648e58d1791e1c40b78deab.tar.gz
nova-0d426ae8d0fe4e697648e58d1791e1c40b78deab.tar.xz
nova-0d426ae8d0fe4e697648e58d1791e1c40b78deab.zip
fix lp 798361
-rw-r--r--nova/compute/api.py55
-rw-r--r--nova/scheduler/zone_aware_scheduler.py49
-rw-r--r--nova/tests/scheduler/test_zone_aware_scheduler.py2
3 files changed, 59 insertions, 47 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index e6cffb6b3..cb73af94c 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -200,18 +200,7 @@ class API(base.Base):
if ramdisk_id:
image_service.show(context, ramdisk_id)
- if security_group is None:
- security_group = ['default']
- if not type(security_group) is list:
- security_group = [security_group]
-
- security_groups = []
self.ensure_default_security_group(context)
- for security_group_name in security_group:
- group = db.security_group_get_by_name(context,
- context.project_id,
- security_group_name)
- security_groups.append(group['id'])
if key_data is None and key_name:
key_pair = db.key_pair_get(context, context.user_id, key_name)
@@ -245,15 +234,19 @@ class API(base.Base):
'os_type': os_type,
'vm_mode': vm_mode}
- return (num_instances, base_options, security_groups)
+ return (num_instances, base_options)
def create_db_entry_for_new_instance(self, context, base_options,
- security_groups, block_device_mapping, num=1):
+ 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
- groups, MAC address, etc). This will called by create()
- in the majority of situations, but all-at-once style
- Schedulers may initiate the call."""
+ including any related table updates (such as security group,
+ MAC address, etc).
+
+ This will called by create() in the majority of situations,
+ but create_all_at_once() style Schedulers may initiate the call.
+ If you are changing this method, be sure to update both
+ call paths.
+ """
instance = dict(mac_address=utils.generate_mac(),
launch_index=num,
**base_options)
@@ -261,13 +254,24 @@ class API(base.Base):
instance_id = instance['id']
elevated = context.elevated()
- if not security_groups:
- security_groups = []
+ if security_group is None:
+ security_group = ['default']
+ if not type(security_group) is list:
+ security_group = [security_group]
+
+ security_groups = []
+ for security_group_name in security_group:
+ group = db.security_group_get_by_name(context,
+ context.project_id,
+ security_group_name)
+ security_groups.append(group['id'])
+
for security_group_id in security_groups:
self.db.instance_add_security_group(elevated,
instance_id,
security_group_id)
-
+
+ block_device_mapping = block_device_mapping or []
# NOTE(yamahata)
# tell vm driver to attach volume at boot time by updating
# BlockDeviceMapping
@@ -339,12 +343,11 @@ class API(base.Base):
key_name=None, key_data=None, security_group='default',
availability_zone=None, user_data=None, metadata={},
injected_files=None, admin_password=None, zone_blob=None,
- reservation_id=None):
+ reservation_id=None, block_device_mapping=None):
"""Provision the instances by passing the whole request to
the Scheduler for execution. Returns a Reservation ID
related to the creation of all of these instances."""
- num_instances, base_options, security_groups = \
- self._check_create_parameters(
+ num_instances, base_options = self._check_create_parameters(
context, instance_type,
image_href, kernel_id, ramdisk_id,
min_count, max_count,
@@ -379,8 +382,7 @@ class API(base.Base):
Returns a list of instance dicts.
"""
- num_instances, base_options, security_groups = \
- self._check_create_parameters(
+ num_instances, base_options = self._check_create_parameters(
context, instance_type,
image_href, kernel_id, ramdisk_id,
min_count, max_count,
@@ -390,12 +392,11 @@ class API(base.Base):
injected_files, admin_password, zone_blob,
reservation_id)
- block_device_mapping = block_device_mapping or []
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,
- base_options, security_groups,
+ base_options, security_group,
block_device_mapping, num=num)
instances.append(instance)
instance_id = instance['id']
diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py
index dfee6cc2d..364d1e172 100644
--- a/nova/scheduler/zone_aware_scheduler.py
+++ b/nova/scheduler/zone_aware_scheduler.py
@@ -33,6 +33,7 @@ from nova import flags
from nova import log as logging
from nova import rpc
+from nova.compute import api as compute_api
from nova.scheduler import api
from nova.scheduler import driver
@@ -52,10 +53,21 @@ class ZoneAwareScheduler(driver.Scheduler):
"""Call novaclient zone method. Broken out for testing."""
return api.call_zone_method(context, method, specs=specs, zones=zones)
- def _provision_resource_locally(self, context, item, instance_id, kwargs):
+ def _provision_resource_locally(self, context, build_plan_item,
+ request_spec):
"""Create the requested resource in this Zone."""
- host = item['hostname']
+ host = build_plan_item['hostname']
+ base_options = request_spec['instance_properties']
+
+ # TODO(sandy): I guess someone needs to add block_device_mapping
+ # support at some point? Also, OS API has no concept of security
+ # groups.
+ instance = compute_api.create_db_entry_for_new_instance(context,
+ base_options, None, [])
+
+ instance_id = instance['instance_id']
kwargs['instance_id'] = instance_id
+
rpc.cast(context,
db.queue_get_for(context, "compute", host),
{"method": "run_instance",
@@ -115,8 +127,8 @@ class ZoneAwareScheduler(driver.Scheduler):
nova.servers.create(name, image_ref, flavor_id, ipgroup, meta, files,
child_blob, reservation_id=reservation_id)
- def _provision_resource_from_blob(self, context, item, instance_id,
- request_spec, kwargs):
+ def _provision_resource_from_blob(self, context, build_plan_item,
+ instance_id, request_spec, kwargs):
"""Create the requested resource locally or in a child zone
based on what is stored in the zone blob info.
@@ -132,12 +144,12 @@ class ZoneAwareScheduler(driver.Scheduler):
request."""
host_info = None
- if "blob" in item:
+ if "blob" in build_plan_item:
# Request was passed in from above. Is it for us?
- host_info = self._decrypt_blob(item['blob'])
- elif "child_blob" in item:
+ host_info = self._decrypt_blob(build_plan_item['blob'])
+ elif "child_blob" in build_plan_item:
# Our immediate child zone provided this info ...
- host_info = item
+ host_info = build_plan_item
if not host_info:
raise InvalidBlob()
@@ -147,19 +159,18 @@ class ZoneAwareScheduler(driver.Scheduler):
self._ask_child_zone_to_create_instance(context, host_info,
request_spec, kwargs)
else:
- self._provision_resource_locally(context, host_info,
- instance_id, kwargs)
+ self._provision_resource_locally(context, host_info, request_spec)
- def _provision_resource(self, context, item, instance_id, request_spec,
- kwargs):
+ def _provision_resource(self, context, build_plan_item, instance_id,
+ request_spec, kwargs):
"""Create the requested resource in this Zone or a child zone."""
- if "hostname" in item:
- self._provision_resource_locally(context, item, instance_id,
- kwargs)
+ if "hostname" in build_plan_item:
+ self._provision_resource_locally(context, build_plan_item,
+ request_spec)
return
- self._provision_resource_from_blob(context, item, instance_id,
- request_spec, kwargs)
+ self._provision_resource_from_blob(context, build_plan_item,
+ instance_id, request_spec, kwargs)
def _adjust_child_weights(self, child_results, zones):
"""Apply the Scale and Offset values from the Zone definition
@@ -215,8 +226,8 @@ class ZoneAwareScheduler(driver.Scheduler):
break
item = build_plan.pop(0)
- self._provision_resource(context, item, instance_id, request_spec,
- kwargs)
+ self._provision_resource(context, build_plan_item, instance_id,
+ request_spec, kwargs)
# Returning None short-circuits the routing to Compute (since
# we've already done it here)
diff --git a/nova/tests/scheduler/test_zone_aware_scheduler.py b/nova/tests/scheduler/test_zone_aware_scheduler.py
index ef6a6a469..57fddb041 100644
--- a/nova/tests/scheduler/test_zone_aware_scheduler.py
+++ b/nova/tests/scheduler/test_zone_aware_scheduler.py
@@ -110,7 +110,7 @@ def fake_ask_child_zone_to_create_instance(context, zone_info,
was_called = True
-def fake_provision_resource_locally(context, item, instance_id, kwargs):
+def fake_provision_resource_locally(context, build_plan, request_spec):
global was_called
was_called = True