Example #1
0
    def test_refresh_from_db_add_and_delete(self):
        zm = zone_manager.ZoneManager()
        zone_state = zone_manager.ZoneState()
        zone_state.update_credentials(
            FakeZone(id=1,
                     api_url='http://foo.com',
                     username='******',
                     password='******'))
        zm.zone_states[1] = zone_state

        self.mox.StubOutWithMock(db, 'zone_get_all')

        db.zone_get_all(mox.IgnoreArg()).AndReturn([
            FakeZone(id=2,
                     api_url='http://foo.com',
                     username='******',
                     password='******'),
        ])
        self.assertEquals(len(zm.zone_states), 1)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertEquals(zm.zone_states[2].username, 'user2')
Example #2
0
    def test_refresh_from_db_replace_existing(self):
        zm = zone_manager.ZoneManager()
        zone_state = zone_manager.ZoneState()
        zone_state.update_credentials(
            FakeZone(id=1,
                     api_url='http://foo.com',
                     username='******',
                     password='******',
                     name='child',
                     weight_offset=0.0,
                     weight_scale=1.0))
        zm.zone_states[1] = zone_state

        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([
            FakeZone(id=1,
                     api_url='http://foo.com',
                     username='******',
                     password='******',
                     name='child',
                     weight_offset=0.0,
                     weight_scale=1.0),
        ])

        self.assertEquals(len(zm.zone_states), 1)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertEquals(zm.zone_states[1].username, 'user2')
Example #3
0
    def test_refresh_from_db_missing(self):
        zone_state = self._create_zone_state(zone_id=1, username='******')
        zm = self.zone_manager
        zm.zone_states[1] = zone_state

        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([])

        self.assertEquals(len(zm.zone_states), 1)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 0)
Example #4
0
    def test_refresh_from_db_new(self):
        zone = _create_zone(zone_id=1, username='******')
        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([zone])

        zm = self.zone_manager
        self.assertEquals(len(zm.zone_states), 0)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertIn(1, zm.zone_states)
        self.assertEquals(zm.zone_states[1].zone_info['username'], 'user1')
Example #5
0
    def test_refresh_from_db_new(self):
        zone = _create_zone(zone_id=1, username='******')
        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([zone])

        zm = self.zone_manager
        self.assertEquals(len(zm.zone_states), 0)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertIn(1, zm.zone_states)
        self.assertEquals(zm.zone_states[1].zone_info['username'], 'user1')
Example #6
0
    def test_refresh_from_db_missing(self):
        zone_state = self._create_zone_state(zone_id=1, username='******')
        zm = self.zone_manager
        zm.zone_states[1] = zone_state

        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([])

        self.assertEquals(len(zm.zone_states), 1)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 0)
Example #7
0
    def test_refresh_from_db_add_and_delete(self):
        zone_state = self._create_zone_state(zone_id=1, username='******')
        zm = self.zone_manager
        zm.zone_states[1] = zone_state

        zone2 = _create_zone(zone_id=2, username='******')
        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([zone2])

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertIn(2, zm.zone_states)
        self.assertEquals(zm.zone_states[2].zone_info['username'], 'user2')
Example #8
0
        def wrapped_f(*args, **kwargs):
            collection, context, item_id = \
                            self.get_collection_context_and_id(args, kwargs)
            try:
                # Call the original function ...
                return f(*args, **kwargs)
            except exception.InstanceNotFound, e:
                LOG.debug(
                    _("Instance %(item_id)s not found "
                      "locally: '%(e)s'" % locals()))

                if not FLAGS.enable_zone_routing:
                    raise

                zones = db.zone_get_all(context)
                if not zones:
                    raise

                # Ask the children to provide an answer ...
                LOG.debug(_("Asking child zones ..."))
                result = self._call_child_zones(
                    zones,
                    wrap_novaclient_function(_issue_novaclient_command,
                                             collection, self.method_name,
                                             item_id))
                # Scrub the results and raise another exception
                # so the API layers can bail out gracefully ...
                raise RedirectResult(self.unmarshall_result(result))
Example #9
0
        def wrapped_f(*args, **kwargs):
            collection, context, item_id = \
                            self.get_collection_context_and_id(args, kwargs)
            try:
                # Call the original function ...
                return f(*args, **kwargs)
            except exception.InstanceNotFound, e:
                LOG.debug(_("Instance %(item_id)s not found "
                                    "locally: '%(e)s'" % locals()))

                if not FLAGS.enable_zone_routing:
                    raise

                zones = db.zone_get_all(context)
                if not zones:
                    raise

                # Ask the children to provide an answer ...
                LOG.debug(_("Asking child zones ..."))
                result = self._call_child_zones(zones,
                            wrap_novaclient_function(_issue_novaclient_command,
                                   collection, self.method_name, item_id))
                # Scrub the results and raise another exception
                # so the API layers can bail out gracefully ...
                raise RedirectResult(self.unmarshall_result(result))
    def _schedule(self, context, topic, request_spec, *args, **kwargs):
        """Returns a list of hosts that meet the required specs,
        ordered by their fitness.
        """
        if topic != "compute":
            msg = _("Scheduler only understands Compute nodes (for now)")
            raise NotImplementedError(msg)

        # Get all available hosts.
        all_hosts = self.zone_manager.service_states.iteritems()
        unfiltered_hosts = [(host, services[topic]) for host, services in all_hosts if topic in services]

        # Filter local hosts based on requirements ...
        filtered_hosts = self.filter_hosts(topic, request_spec, unfiltered_hosts)

        # weigh the selected hosts.
        # weighted_hosts = [{weight=weight, hostname=hostname,
        #         capabilities=capabs}, ...]
        weighted_hosts = self.weigh_hosts(topic, request_spec, filtered_hosts)
        # Next, tack on the host weights from the child zones
        json_spec = json.dumps(request_spec)
        all_zones = db.zone_get_all(context)
        child_results = self._call_zone_method(context, "select", specs=json_spec, zones=all_zones)
        self._adjust_child_weights(child_results, all_zones)
        for child_zone, result in child_results:
            for weighting in result:
                # Remember the child_zone so we can get back to
                # it later if needed. This implicitly builds a zone
                # path structure.
                host_dict = {"weight": weighting["weight"], "child_zone": child_zone, "child_blob": weighting["blob"]}
                weighted_hosts.append(host_dict)
        weighted_hosts.sort(key=operator.itemgetter("weight"))
        return weighted_hosts
Example #11
0
def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs):
    """Returns a list of (zone, call_result) objects."""
    if not isinstance(errors_to_ignore, (list, tuple)):
        # This will also handle the default None
        errors_to_ignore = [errors_to_ignore]

    pool = greenpool.GreenPool()
    results = []
    for zone in db.zone_get_all(context):
        try:
            nova = novaclient.OpenStack(zone.username, zone.password,
                    zone.api_url)
            nova.authenticate()
        except novaclient.exceptions.BadRequest, e:
            url = zone.api_url
            LOG.warn(_("Failed request to zone; URL=%(url)s: %(e)s")
                    % locals())
            #TODO (dabo) - add logic for failure counts per zone,
            # with escalation after a given number of failures.
            continue
        zone_method = getattr(nova.zones, method)

        def _error_trap(*args, **kwargs):
            try:
                return zone_method(*args, **kwargs)
            except Exception as e:
                if type(e) in errors_to_ignore:
                    return None
                # TODO (dabo) - want to be able to re-raise here.
                # Returning a string now; raising was causing issues.
                # raise e
                return "ERROR", "%s" % e

        res = pool.spawn(_error_trap, *args, **kwargs)
        results.append((zone, res))
Example #12
0
    def test_refresh_from_db_add_and_delete(self):
        zone_state = self._create_zone_state(zone_id=1, username='******')
        zm = self.zone_manager
        zm.zone_states[1] = zone_state

        zone2 = _create_zone(zone_id=2, username='******')
        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([zone2])

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertIn(2, zm.zone_states)
        self.assertEquals(zm.zone_states[2].zone_info['username'], 'user2')
Example #13
0
    def test_refresh_from_db_new(self):
        zm = zone_manager.ZoneManager()

        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([
               FakeZone(id=1, api_url='http://foo.com', username='******',
                    password='******'),
            ])

        self.assertEquals(len(zm.zone_states), 0)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertEquals(zm.zone_states[1].username, 'user1')
Example #14
0
File: api.py Project: Willtech/nova
def get_zone_list(context):
    """Return a list of zones associated with this zone."""
    items = _call_scheduler('get_zone_list', context)
    for item in items:
        item['api_url'] = item['api_url'].replace('\\/', '/')
    if not items:
        items = db.zone_get_all(context.elevated())
    return items
Example #15
0
def get_zone_list(context):
    """Return a list of zones associated with this zone."""
    items = _call_scheduler('get_zone_list', context)
    for item in items:
        item['api_url'] = item['api_url'].replace('\\/', '/')
    if not items:
        items = db.zone_get_all(context.elevated())
    return items
Example #16
0
    def test_refresh_from_db_new(self):
        zm = zone_manager.ZoneManager()

        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([
               FakeZone(id=1, api_url='http://foo.com', username='******',
                    password='******'),
            ])

        self.assertEquals(len(zm.zone_states), 0)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertEquals(zm.zone_states[1].username, 'user1')
Example #17
0
    def _schedule(self, context, topic, request_spec, *args, **kwargs):
        """Returns a list of hosts that meet the required specs,
        ordered by their fitness.
        """

        if topic != "compute":
            raise NotImplemented(_("Zone Aware Scheduler only understands "
                                   "Compute nodes (for now)"))

        num_instances = request_spec.get('num_instances', 1)
        instance_type = request_spec['instance_type']

        weighted = []
        host_list = None

        for i in xrange(num_instances):
            # Filter local hosts based on requirements ...
            #
            # The first pass through here will pass 'None' as the
            # host_list.. which tells the filter to build the full
            # list of hosts.
            # On a 2nd pass, the filter can modify the host_list with
            # any updates it needs to make based on resources that
            # may have been consumed from a previous build..
            host_list = self.filter_hosts(topic, request_spec, host_list)
            if not host_list:
                LOG.warn(_("Filter returned no hosts after processing "
                        "%(i)d of %(num_instances)d instances") % locals())
                break

            # then weigh the selected hosts.
            # weighted = [{weight=weight, hostname=hostname,
            #              capabilities=capabs}, ...]
            weights = self.weigh_hosts(topic, request_spec, host_list)
            weights.sort(key=operator.itemgetter('weight'))
            best_weight = weights[0]
            weighted.append(best_weight)
            self.consume_resources(topic, best_weight['capabilities'],
                    instance_type)

        # Next, tack on the best weights from the child zones ...
        json_spec = json.dumps(request_spec)
        all_zones = db.zone_get_all(context)
        child_results = self._call_zone_method(context, "select",
                specs=json_spec, zones=all_zones)
        self._adjust_child_weights(child_results, all_zones)
        for child_zone, result in child_results:
            for weighting in result:
                # Remember the child_zone so we can get back to
                # it later if needed. This implicitly builds a zone
                # path structure.
                host_dict = {"weight": weighting["weight"],
                             "child_zone": child_zone,
                             "child_blob": weighting["blob"]}
                weighted.append(host_dict)

        weighted.sort(key=operator.itemgetter('weight'))
        return weighted
Example #18
0
    def test_refresh_from_db_missing(self):
        zm = zone_manager.ZoneManager()
        zone_state = zone_manager.ZoneState()
        zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com',
                        username='******', password='******', name='child',
                        weight_offset=0.0, weight_scale=1.0))
        zm.zone_states[1] = zone_state

        self.mox.StubOutWithMock(db, 'zone_get_all')
        db.zone_get_all(mox.IgnoreArg()).AndReturn([])

        self.assertEquals(len(zm.zone_states), 1)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 0)
Example #19
0
    def test_refresh_from_db_add_and_delete(self):
        zm = zone_manager.ZoneManager()
        zone_state = zone_manager.ZoneState()
        zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com',
                        username='******', password='******'))
        zm.zone_states[1] = zone_state

        self.mox.StubOutWithMock(db, 'zone_get_all')

        db.zone_get_all(mox.IgnoreArg()).AndReturn([
               FakeZone(id=2, api_url='http://foo.com', username='******',
                    password='******'),
            ])
        self.assertEquals(len(zm.zone_states), 1)

        self.mox.ReplayAll()
        zm._refresh_from_db(None)
        self.mox.VerifyAll()

        self.assertEquals(len(zm.zone_states), 1)
        self.assertEquals(zm.zone_states[2].username, 'user2')
Example #20
0
    def index(self, req):
        """Return all zones in brief"""
        # Ask the ZoneManager in the Scheduler for most recent data,
        # or fall-back to the database ...
        items = api.API().get_zone_list(req.environ['nova.context'])
        if not items:
            items = db.zone_get_all(req.environ['nova.context'])

        items = common.limited(items, req)
        items = [_exclude_keys(item, ['username', 'password'])
                      for item in items]
        return dict(zones=items)
Example #21
0
def call_zone_method(context,
                     method_name,
                     errors_to_ignore=None,
                     novaclient_collection_name='zones',
                     zones=None,
                     *args,
                     **kwargs):
    """Returns a list of (zone, call_result) objects."""
    if not isinstance(errors_to_ignore, (list, tuple)):
        # This will also handle the default None
        errors_to_ignore = [errors_to_ignore]

    pool = greenpool.GreenPool()
    results = []
    if zones is None:
        zones = db.zone_get_all(context.elevated())
    for zone in zones:
        try:
            # Do this on behalf of the user ...
            nova = novaclient.Client(zone.username,
                                     zone.password,
                                     None,
                                     zone.api_url,
                                     region_name=zone.name,
                                     token=context.auth_token)
            nova.authenticate()
        except novaclient_exceptions.BadRequest, e:
            url = zone.api_url
            name = zone.name
            LOG.warn(
                _("Authentication failed to zone "
                  "'%(name)s' URL=%(url)s: %(e)s") % locals())
            #TODO (dabo) - add logic for failure counts per zone,
            # with escalation after a given number of failures.
            continue
        novaclient_collection = getattr(nova, novaclient_collection_name)
        collection_method = getattr(novaclient_collection, method_name)

        def _error_trap(*args, **kwargs):
            try:
                return collection_method(*args, **kwargs)
            except Exception as e:
                if type(e) in errors_to_ignore:
                    return None
                raise

        res = pool.spawn(_error_trap, *args, **kwargs)
        results.append((zone, res))
Example #22
0
File: api.py Project: YouthSun/nova
    def _route_to_child_zones(self, context, collection, item_uuid):
        if not FLAGS.enable_zone_routing:
            raise exception.InstanceNotFound(instance_id=item_uuid)

        zones = db.zone_get_all(context)
        if not zones:
            raise exception.InstanceNotFound(instance_id=item_uuid)

        # Ask the children to provide an answer ...
        LOG.debug(_("Asking child zones ..."))
        result = self._call_child_zones(zones,
                    wrap_novaclient_function(_issue_novaclient_command,
                           collection, self.method_name, item_uuid))
        # Scrub the results and raise another exception
        # so the API layers can bail out gracefully ...
        raise RedirectResult(self.unmarshall_result(result))
Example #23
0
    def _refresh_from_db(self, context):
        """Make our zone state map match the db."""
        # Add/update existing zones ...
        zones = db.zone_get_all(context)
        existing = self.zone_states.keys()
        db_keys = []
        for zone in zones:
            db_keys.append(zone.id)
            if zone.id not in existing:
                self.zone_states[zone.id] = ZoneState()
            self.zone_states[zone.id].update_credentials(zone)

        # Cleanup zones removed from db ...
        keys = self.zone_states.keys()  # since we're deleting
        for zone_id in keys:
            if zone_id not in db_keys:
                del self.zone_states[zone_id]
Example #24
0
    def _route_to_child_zones(self, context, collection, item_uuid):
        if not FLAGS.enable_zone_routing:
            raise exception.InstanceNotFound(instance_id=item_uuid)

        zones = db.zone_get_all(context)
        if not zones:
            raise exception.InstanceNotFound(instance_id=item_uuid)

        # Ask the children to provide an answer ...
        LOG.debug(_("Asking child zones ..."))
        result = self._call_child_zones(
            zones,
            wrap_novaclient_function(_issue_novaclient_command, collection,
                                     self.method_name, item_uuid))
        # Scrub the results and raise another exception
        # so the API layers can bail out gracefully ...
        raise RedirectResult(self.unmarshall_result(result))
Example #25
0
    def _refresh_from_db(self, context):
        """Make our zone state map match the db."""
        # Add/update existing zones ...
        zones = db.zone_get_all(context)
        existing = self.zone_states.keys()
        db_keys = []
        for zone in zones:
            db_keys.append(zone.id)
            if zone.id not in existing:
                self.zone_states[zone.id] = ZoneState()
            self.zone_states[zone.id].update_credentials(zone)

        # Cleanup zones removed from db ...
        keys = self.zone_states.keys()  # since we're deleting
        for zone_id in keys:
            if zone_id not in db_keys:
                del self.zone_states[zone_id]
Example #26
0
    def _schedule(self, context, topic, request_spec, *args, **kwargs):
        """Returns a list of hosts that meet the required specs,
        ordered by their fitness.
        """
        if topic != "compute":
            msg = _("Scheduler only understands Compute nodes (for now)")
            raise NotImplementedError(msg)

        # Get all available hosts.
        all_hosts = self.zone_manager.service_states.iteritems()
        unfiltered_hosts = [(host, services[topic])
                            for host, services in all_hosts
                            if topic in services]

        # Filter local hosts based on requirements ...
        filtered_hosts = self.filter_hosts(topic, request_spec,
                                           unfiltered_hosts)

        # weigh the selected hosts.
        # weighted_hosts = [{weight=weight, hostname=hostname,
        #         capabilities=capabs}, ...]
        weighted_hosts = self.weigh_hosts(topic, request_spec, filtered_hosts)
        # Next, tack on the host weights from the child zones
        json_spec = json.dumps(request_spec)
        all_zones = db.zone_get_all(context)
        child_results = self._call_zone_method(context,
                                               "select",
                                               specs=json_spec,
                                               zones=all_zones)
        self._adjust_child_weights(child_results, all_zones)
        for child_zone, result in child_results:
            for weighting in result:
                # Remember the child_zone so we can get back to
                # it later if needed. This implicitly builds a zone
                # path structure.
                host_dict = {
                    "weight": weighting["weight"],
                    "child_zone": child_zone,
                    "child_blob": weighting["blob"]
                }
                weighted_hosts.append(host_dict)
        weighted_hosts.sort(key=operator.itemgetter('weight'))
        return weighted_hosts
Example #27
0
File: api.py Project: Willtech/nova
def call_zone_method(context, method_name, errors_to_ignore=None,
                     novaclient_collection_name='zones', zones=None,
                     *args, **kwargs):
    """Returns a list of (zone, call_result) objects."""
    if not isinstance(errors_to_ignore, (list, tuple)):
        # This will also handle the default None
        errors_to_ignore = [errors_to_ignore]

    pool = greenpool.GreenPool()
    results = []
    if zones is None:
        zones = db.zone_get_all(context.elevated())
    for zone in zones:
        try:
            # Do this on behalf of the user ...
            nova = novaclient.Client(zone.username, zone.password, None,
                    zone.api_url, region_name=zone.name,
                    token=context.auth_token)
            nova.authenticate()
        except novaclient_exceptions.BadRequest, e:
            url = zone.api_url
            name = zone.name
            LOG.warn(_("Authentication failed to zone "
                       "'%(name)s' URL=%(url)s: %(e)s") % locals())
            #TODO (dabo) - add logic for failure counts per zone,
            # with escalation after a given number of failures.
            continue
        novaclient_collection = getattr(nova, novaclient_collection_name)
        collection_method = getattr(novaclient_collection, method_name)

        def _error_trap(*args, **kwargs):
            try:
                return collection_method(*args, **kwargs)
            except Exception as e:
                if type(e) in errors_to_ignore:
                    return None
                raise

        res = pool.spawn(_error_trap, *args, **kwargs)
        results.append((zone, res))
Example #28
0
 def _zone_get_all(self, context):
     """Broken out for testing."""
     return db.zone_get_all(context)
Example #29
0
 def _zone_get_all(self, context):
     """Broken out for testing."""
     return db.zone_get_all(context)
Example #30
0
File: zones.py Project: yosh/nova
 def index(self, req):
     """Return all zones in brief"""
     items = db.zone_get_all(req.environ['nova.context'])
     items = common.limited(items, req)
     items = [_scrub_zone(item) for item in items]
     return dict(zones=items)
Example #31
0
    def _schedule(self, context, topic, request_spec, *args, **kwargs):
        """Returns a list of hosts that meet the required specs,
        ordered by their fitness.
        """

        if topic != "compute":
            raise NotImplementedError(
                _("Zone Aware Scheduler only understands"
                  " Compute nodes (for now)"))

        num_instances = request_spec.get('num_instances', 1)
        instance_type = request_spec['instance_type']

        weighted = []
        host_list = None

        for i in xrange(num_instances):
            # Filter local hosts based on requirements ...
            #
            # The first pass through here will pass 'None' as the
            # host_list.. which tells the filter to build the full
            # list of hosts.
            # On a 2nd pass, the filter can modify the host_list with
            # any updates it needs to make based on resources that
            # may have been consumed from a previous build..
            host_list = self.filter_hosts(topic, request_spec, host_list)
            if not host_list:
                LOG.warn(
                    _("Filter returned no hosts after processing "
                      "%(i)d of %(num_instances)d instances") % locals())
                break

            # then weigh the selected hosts.
            # weighted = [{weight=weight, hostname=hostname,
            #              capabilities=capabs}, ...]
            weights = self.weigh_hosts(topic, request_spec, host_list)
            weights.sort(key=operator.itemgetter('weight'))
            best_weight = weights[0]
            weighted.append(best_weight)
            self.consume_resources(topic, best_weight['capabilities'],
                                   instance_type)

        # Next, tack on the best weights from the child zones ...
        json_spec = json.dumps(request_spec)
        all_zones = db.zone_get_all(context)
        child_results = self._call_zone_method(context,
                                               "select",
                                               specs=json_spec,
                                               zones=all_zones)
        self._adjust_child_weights(child_results, all_zones)
        for child_zone, result in child_results:
            for weighting in result:
                # Remember the child_zone so we can get back to
                # it later if needed. This implicitly builds a zone
                # path structure.
                host_dict = {
                    "weight": weighting["weight"],
                    "child_zone": child_zone,
                    "child_blob": weighting["blob"]
                }
                weighted.append(host_dict)

        weighted.sort(key=operator.itemgetter('weight'))
        return weighted