 e9b3533f27
			
		
	
	e9b3533f27
	
	
	
		
			
			Fixes bug 904971 Scheduler error handler was looking for instance_id when it may or may not exist. Added the proper code for it to determine whether the instance was actually created in the DB or not and how to find its ID. Note: there's some pretty nasty stuff in here, but unavoidable without larger changes. I'd like to hold off on these larger changes, because the problem should be solved with some of the scalability work coming. Tests included. Change-Id: Ief5fde8128437c9dc257af9c4d0c2950d0962ce5
		
			
				
	
	
		
			87 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # 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.
 | |
| 
 | |
| """
 | |
| Chance (Random) Scheduler implementation
 | |
| """
 | |
| 
 | |
| import random
 | |
| 
 | |
| from nova import exception
 | |
| from nova.scheduler import driver
 | |
| 
 | |
| 
 | |
| class ChanceScheduler(driver.Scheduler):
 | |
|     """Implements Scheduler as a random node selector."""
 | |
| 
 | |
|     def _filter_hosts(self, request_spec, hosts):
 | |
|         """Filter a list of hosts based on request_spec."""
 | |
| 
 | |
|         # Filter out excluded host
 | |
|         if (request_spec and 'original_host' in request_spec and
 | |
|             request_spec.get('avoid_original_host', True)):
 | |
|             hosts = [host for host in hosts
 | |
|                      if host != request_spec['original_host']]
 | |
| 
 | |
|         return hosts
 | |
| 
 | |
|     def _schedule(self, context, topic, request_spec, **kwargs):
 | |
|         """Picks a host that is up at random."""
 | |
| 
 | |
|         elevated = context.elevated()
 | |
|         hosts = self.hosts_up(elevated, topic)
 | |
|         if not hosts:
 | |
|             msg = _("Is the appropriate service running?")
 | |
|             raise exception.NoValidHost(reason=msg)
 | |
| 
 | |
|         hosts = self._filter_hosts(request_spec, hosts)
 | |
|         if not hosts:
 | |
|             msg = _("Could not find another compute")
 | |
|             raise exception.NoValidHost(reason=msg)
 | |
| 
 | |
|         return hosts[int(random.random() * len(hosts))]
 | |
| 
 | |
|     def schedule(self, context, topic, method, *_args, **kwargs):
 | |
|         """Picks a host that is up at random."""
 | |
| 
 | |
|         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):
 | |
|         """Create and run an instance or instances"""
 | |
|         elevated = context.elevated()
 | |
|         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(elevated, request_spec)
 | |
|             driver.cast_to_compute_host(context, host,
 | |
|                     'run_instance', instance_uuid=instance['uuid'], **kwargs)
 | |
|             instances.append(driver.encode_instance(instance))
 | |
|             # So if we loop around, create_instance_db_entry will actually
 | |
|             # create a new entry, instead of assume it's been created
 | |
|             # already
 | |
|             del request_spec['instance_properties']['uuid']
 | |
|         return instances
 | |
| 
 | |
|     def schedule_prep_resize(self, context, request_spec, *args, **kwargs):
 | |
|         """Select a target for resize."""
 | |
|         host = self._schedule(context, 'compute', request_spec, **kwargs)
 | |
|         driver.cast_to_host(context, 'compute', host, 'prep_resize', **kwargs)
 |