示例#1
0
    def _find_destination(self):
        # TODO(johngarbutt) this retry loop should be shared
        attempted_hosts = [self.source]
        request_spec = self._get_request_spec_for_select_destinations(
            attempted_hosts)

        host = None
        while host is None:
            self._check_not_over_max_retries(attempted_hosts)
            request_spec.ignore_hosts = attempted_hosts
            try:
                selection_lists = self.query_client.select_destinations(
                    self.context,
                    request_spec, [self.instance.uuid],
                    return_objects=True,
                    return_alternates=False)
                # We only need the first item in the first list, as there is
                # only one instance, and we don't care about any alternates.
                selection = selection_lists[0][0]
                host = selection.service_host
            except messaging.RemoteError as ex:
                # TODO(ShaoHe Feng) There maybe multi-scheduler, and the
                # scheduling algorithm is R-R, we can let other scheduler try.
                # Note(ShaoHe Feng) There are types of RemoteError, such as
                # NoSuchMethod, UnsupportedVersion, we can distinguish it by
                # ex.exc_type.
                raise exception.MigrationSchedulerRPCError(
                    reason=six.text_type(ex))

            scheduler_utils.fill_provider_mapping(request_spec, selection)

            provider_mapping = request_spec.get_request_group_mapping()

            if provider_mapping:
                # NOTE(gibi): this call might update the pci_requests of the
                # instance based on the destination host if so then such change
                # will be persisted when post_live_migration_at_destination
                # runs.
                compute_utils.\
                    update_pci_request_spec_with_allocated_interface_name(
                        self.context, self.report_client, self.instance,
                        provider_mapping)
            try:
                self._check_compatible_with_source_hypervisor(host)
                self._call_livem_checks_on_host(host, provider_mapping)
            except (exception.Invalid, exception.MigrationPreCheckError) as e:
                LOG.debug("Skipping host: %(host)s because: %(e)s", {
                    "host": host,
                    "e": e
                })
                attempted_hosts.append(host)
                # The scheduler would have created allocations against the
                # selected destination host in Placement, so we need to remove
                # those before moving on.
                self._remove_host_allocations(selection.compute_node_uuid)
                host = None
        # TODO(artom) We should probably just return the whole selection object
        # at this point.
        return (selection.service_host, selection.nodename, selection.limits)
示例#2
0
 def _reschedule(self):
     # Since the resources on these alternates may have been consumed and
     # might not be able to support the migrated instance, we need to first
     # claim the resources to verify the host still has sufficient
     # available resources.
     elevated = self.context.elevated()
     host_available = False
     selection = None
     while self.host_list and not host_available:
         selection = self.host_list.pop(0)
         if (self.request_spec.requested_resources
                 and not self._support_resource_request(selection)):
             LOG.debug(
                 'Scheduler returned alternate host %(host)s as a possible '
                 'migration target for re-schedule but that host is not '
                 'new enough to support the migration with resource '
                 'request %(request)s. Trying another alternate.', {
                     'host': selection.service_host,
                     'request': self.request_spec.requested_resources
                 },
                 instance=self.instance)
             continue
         if selection.allocation_request:
             alloc_req = jsonutils.loads(selection.allocation_request)
         else:
             alloc_req = None
         if alloc_req:
             # If this call succeeds, the resources on the destination
             # host will be claimed by the instance.
             host_available = scheduler_utils.claim_resources(
                 elevated, self.reportclient, self.request_spec,
                 self.instance.uuid, alloc_req,
                 selection.allocation_request_version)
             if host_available:
                 scheduler_utils.fill_provider_mapping(
                     self.context, self.reportclient, self.request_spec,
                     selection)
         else:
             # Some deployments use different schedulers that do not
             # use Placement, so they will not have an
             # allocation_request to claim with. For those cases,
             # there is no concept of claiming, so just assume that
             # the host is valid.
             host_available = True
     # There are no more available hosts. Raise a MaxRetriesExceeded
     # exception in that case.
     if not host_available:
         reason = ("Exhausted all hosts available for retrying build "
                   "failures for instance %(instance_uuid)s." % {
                       "instance_uuid": self.instance.uuid
                   })
         raise exception.MaxRetriesExceeded(reason=reason)
     return selection
示例#3
0
    def _schedule(self):
        selection_lists = self.query_client.select_destinations(
            self.context, self.request_spec, [self.instance.uuid],
            return_objects=True, return_alternates=True)
        # Since there is only ever one instance to migrate per call, we
        # just need the first returned element.
        selection_list = selection_lists[0]

        selection, self.host_list = self._get_host_supporting_request(
            selection_list)

        scheduler_utils.fill_provider_mapping(
            self.context, self.reportclient, self.request_spec, selection)
        return selection
示例#4
0
文件: migrate.py 项目: zoirboy/nova
    def _schedule(self):
        selection_lists = self.query_client.select_destinations(
            self.context, self.request_spec, [self.instance.uuid],
            return_objects=True, return_alternates=True)
        # Since there is only ever one instance to migrate per call, we
        # just need the first returned element.
        selection_list = selection_lists[0]
        # The selected host is the first item in the list, with the
        # alternates being the remainder of the list.
        selection, self.host_list = selection_list[0], selection_list[1:]

        scheduler_utils.fill_provider_mapping(
            self.context, self.reportclient, self.request_spec, selection)
        return selection
示例#5
0
    def _schedule(self):
        selection_lists = self.query_client.select_destinations(
            self.context,
            self.request_spec, [self.instance.uuid],
            return_objects=True,
            return_alternates=True)
        # Since there is only ever one instance to migrate per call, we
        # just need the first returned element.
        selection_list = selection_lists[0]

        # Scheduler allocated resources on the first host so try that first
        selection, self.host_list = selection_list[0], selection_list[1:]

        scheduler_utils.fill_provider_mapping(self.request_spec, selection)
        return selection