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 _select_hosts(self, request_spec, all_hosts, selected_hosts=None): if selected_hosts is None: selected_hosts = [] host = None if len(selected_hosts) >= FLAGS.vsa_unique_hosts_per_alloc: # try to select from already selected hosts only LOG.debug(_("Maximum number of hosts selected (%d)"), len(selected_hosts)) unique = False (host, qos_cap) = self.host_selection_algorithm(request_spec, selected_hosts, selected_hosts, unique) LOG.debug(_("Selected excessive host %(host)s"), locals()) else: unique = FLAGS.vsa_select_unique_drives if host is None: # if we've not tried yet (# of sel hosts < max) - unique=True # or failed to select from selected_hosts - unique=False # select from all hosts (host, qos_cap) = self.host_selection_algorithm(request_spec, all_hosts, selected_hosts, unique) if host is None: raise exception.NoValidHost(reason=_("")) return (host, qos_cap)
def schedule_set_network_host(self, context, *_args, **_kwargs): """Picks a host that is up and has the fewest networks.""" elevated = context.elevated() results = db.service_get_all_network_sorted(elevated) for result in results: (service, instance_count) = result if instance_count >= FLAGS.max_networks: msg = _("Not enough allocatable networks remaining") raise exception.NoValidHost(reason=msg) if self.service_is_up(service): driver.cast_to_network_host(context, service['host'], 'set_network_host', **_kwargs) return None msg = _("Is the appropriate service running?") raise exception.NoValidHost(reason=msg)
def schedule_prep_resize(self, context, request_spec, *args, **kwargs): """Select a target for resize. Selects a target host for the instance, post-resize, and casts the prep_resize operation to it. """ # We need the new instance type ID... instance_type_id = kwargs['instance_type_id'] elevated = context.elevated() LOG.debug( _("Attempting to determine target host for resize to " "instance type %(instance_type_id)s") % locals()) # Convert it to an actual instance type instance_type = db.instance_type_get(elevated, instance_type_id) # Now let's grab a possibility hosts = self._schedule(elevated, 'compute', request_spec, *args, **kwargs) if not hosts: raise exception.NoValidHost(reason=_("")) host = hosts.pop(0) # Forward off to the host driver.cast_to_host(context, 'compute', host.host, 'prep_resize', **kwargs)
def schedule(self, context, topic, method, *args, **kwargs): """The schedule() contract requires we return the one best-suited host for this request. NOTE: We're only focused on compute instances right now, so this method will always raise NoValidHost().""" msg = _("No host selection for %s defined." % topic) raise exception.NoValidHost(reason=msg)
def schedule_create_volume(self, context, volume_id, *_args, **_kwargs): """Picks a host that is up and has the fewest volumes.""" elevated = context.elevated() volume_ref = db.volume_get(context, volume_id) 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(elevated, host, 'engine-volume') if not self.service_is_up(service): raise exception.WillNotSchedule(host=host) driver.cast_to_volume_host(context, host, 'create_volume', volume_id=volume_id, **_kwargs) return None results = db.service_get_all_volume_sorted(elevated) 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: msg = _("Not enough allocatable volume gigabytes remaining") raise exception.NoValidHost(reason=msg) if self.service_is_up(service): driver.cast_to_volume_host(context, service['host'], 'create_volume', volume_id=volume_id, **_kwargs) return None msg = _("Is the appropriate service running?") raise exception.NoValidHost(reason=msg)
def _schedule_instance(self, context, instance_opts, *_args, **_kwargs): """Picks a host that is up and has the fewest running instances.""" elevated = context.elevated() availability_zone = instance_opts.get('availability_zone') zone, host = FLAGS.default_schedule_zone, None if availability_zone: zone, _x, host = availability_zone.partition(':') if host and context.is_admin: service = db.service_get_by_args(elevated, host, 'engine-compute') if not self.service_is_up(service): raise exception.WillNotSchedule(host=host) return host results = db.service_get_all_compute_sorted(elevated) in_isolation = instance_opts['image_ref'] in FLAGS.isolated_images check_cores = not in_isolation or not FLAGS.skip_isolated_core_check if zone: results = [(service, cores) for (service, cores) in results if service['availability_zone'] == zone] for result in results: (service, instance_cores) = result if in_isolation and service['host'] not in FLAGS.isolated_hosts: # isloated images run on isolated hosts continue if service['host'] in FLAGS.isolated_hosts and not in_isolation: # images that aren't isolated only run on general hosts continue if check_cores and \ instance_cores + instance_opts['vcpus'] > FLAGS.max_cores: msg = _("Not enough allocatable CPU cores remaining") raise exception.NoValidHost(reason=msg) if self.service_is_up(service): return service['host'] msg = _("Is the appropriate service running?") raise exception.NoValidHost(reason=msg)
def schedule_run_instance(self, context, request_spec, *args, **kwargs): """This method is called from engine.compute.api to provision an instance. However we need to look at the parameters being passed in to see if this is a request to: 1. Create build plan (a list of WeightedHosts) and then provision, or 2. Use the WeightedHost information in the request parameters to simply create the instance (either in this zone or a child zone). returns a list of the instances created. """ elevated = context.elevated() num_instances = request_spec.get('num_instances', 1) LOG.debug( _("Attempting to build %(num_instances)d instance(s)") % locals()) weighted_hosts = [] # Having a 'blob' hint means we've already provided a build plan. # We need to turn this back into a WeightedHost object. blob = request_spec.get('blob', None) if blob: weighted_hosts.append(self._make_weighted_host_from_blob(blob)) else: # No plan ... better make one. weighted_hosts = self._schedule(elevated, "compute", request_spec, *args, **kwargs) if not weighted_hosts: raise exception.NoValidHost(reason=_("")) instances = [] for num in xrange(num_instances): if not weighted_hosts: break weighted_host = weighted_hosts.pop(0) instance = None if weighted_host.host: instance = self._provision_resource_locally( elevated, weighted_host, request_spec, kwargs) else: instance = self._ask_child_zone_to_create_instance( elevated, weighted_host, request_spec, kwargs) if instance: instances.append(instance) return instances