Example #1
0
    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))]
Example #2
0
    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)
Example #3
0
    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)
Example #6
0
    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)
Example #7
0
    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