From 983698561ee3a693a7a8a1f91695378e822cb6e6 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 20 Oct 2011 15:21:42 -0700 Subject: [PATCH] Moves a-zone scheduling into simple scheduler * removes zone scheduler * adds logic to simple scheduler to handle availability zones * adds tests to verify availability zone is respected Change-Id: I69fd0d411d2e1b64914b073ae7a967a188f09d48 --- nova/scheduler/simple.py | 28 ++++++++++----- nova/scheduler/zone.py | 77 ---------------------------------------- 2 files changed, 19 insertions(+), 86 deletions(-) delete mode 100644 nova/scheduler/zone.py diff --git a/nova/scheduler/simple.py b/nova/scheduler/simple.py index cce1509b..6768205a 100644 --- a/nova/scheduler/simple.py +++ b/nova/scheduler/simple.py @@ -23,7 +23,6 @@ Simple Scheduler from nova import db from nova import flags -from nova import utils from nova.scheduler import driver from nova.scheduler import chance @@ -44,9 +43,11 @@ class SimpleScheduler(chance.ChanceScheduler): availability_zone = instance_opts.get('availability_zone') - if availability_zone and context.is_admin and \ - (':' in availability_zone): - zone, host = availability_zone.split(':', 1) + zone, host = None, None + if availability_zone: + zone, _x, host = availability_zone.partition(':') + + if host and context.is_admin: service = db.service_get_by_args(context.elevated(), host, 'nova-compute') if not self.service_is_up(service): @@ -54,6 +55,9 @@ class SimpleScheduler(chance.ChanceScheduler): return host results = db.service_get_all_compute_sorted(context) + if zone: + results = [(service, cores) for (service, cores) in results + if service['availability_zone'] == zone] for result in results: (service, instance_cores) = result if instance_cores + instance_opts['vcpus'] > FLAGS.max_cores: @@ -82,15 +86,17 @@ class SimpleScheduler(chance.ChanceScheduler): host = self._schedule_instance(context, instance_ref, *_args, **_kwargs) driver.cast_to_compute_host(context, host, 'start_instance', - instance_id=intance_id, **_kwargs) + instance_id=instance_id, **_kwargs) def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" volume_ref = db.volume_get(context, volume_id) - if (volume_ref['availability_zone'] - and ':' in volume_ref['availability_zone'] - and context.is_admin): - zone, _x, host = volume_ref['availability_zone'].partition(':') + availability_zone = volume_ref.get('availability_zone') + + zone, host = None, None + if availability_zone: + zone, _x, host = availability_zone.partition(':') + if host and context.is_admin: service = db.service_get_by_args(context.elevated(), host, 'nova-volume') if not self.service_is_up(service): @@ -98,7 +104,11 @@ class SimpleScheduler(chance.ChanceScheduler): driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs) return None + results = db.service_get_all_volume_sorted(context) + if zone: + results = [(service, gigs) for (service, gigs) in results + if service['availability_zone'] == zone] for result in results: (service, volume_gigabytes) = result if volume_gigabytes + volume_ref['size'] > FLAGS.max_gigabytes: diff --git a/nova/scheduler/zone.py b/nova/scheduler/zone.py deleted file mode 100644 index c369477f..00000000 --- a/nova/scheduler/zone.py +++ /dev/null @@ -1,77 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright (c) 2010 Openstack, LLC. -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Availability Zone Scheduler implementation -""" - -import random - -from nova.scheduler import driver -from nova import db - - -class ZoneScheduler(driver.Scheduler): - """Implements Scheduler as a random node selector.""" - - def hosts_up_with_zone(self, context, topic, zone): - """Return the list of hosts that have a running service - for topic and availability zone (if defined). - """ - - if not zone: - return self.hosts_up(context, topic) - - services = db.service_get_all_by_topic(context, topic) - return [service.host - for service in services - if self.service_is_up(service) - and service.availability_zone == zone] - - def _schedule(self, context, topic, request_spec, **kwargs): - """Picks a host that is up at random in selected - availability zone (if defined). - """ - - zone = kwargs.get('availability_zone') - if not zone and request_spec: - zone = request_spec['instance_properties'].get( - 'availability_zone') - hosts = self.hosts_up_with_zone(context.elevated(), topic, zone) - if not hosts: - raise driver.NoValidHost(_("Scheduler was unable to locate a host" - " for this request. Is the appropriate" - " service running?")) - return hosts[int(random.random() * len(hosts))] - - def schedule(self, context, topic, method, *_args, **kwargs): - host = self._schedule(context, topic, None, **kwargs) - driver.cast_to_host(context, topic, host, method, **kwargs) - - def schedule_run_instance(self, context, request_spec, *_args, **kwargs): - """Builds and starts instances on selected hosts""" - num_instances = request_spec.get('num_instances', 1) - instances = [] - for num in xrange(num_instances): - host = self._schedule(context, 'compute', request_spec, **kwargs) - instance = self.create_instance_db_entry(context, request_spec) - driver.cast_to_compute_host(context, host, - 'run_instance', instance_id=instance['id'], **kwargs) - instances.append(driver.encode_instance(instance)) - return instances