Esempio n. 1
0
 def test_agent_resource_provider_uuid(self):
     try:
         # assertNotRaises
         place_utils.agent_resource_provider_uuid(
             namespace=self._uuid_ns,
             host='some host')
     except Exception:
         self.fail('could not generate agent resource provider uuid')
Esempio n. 2
0
 def test_agent_resource_provider_uuid_stable(self):
     uuid_a = place_utils.agent_resource_provider_uuid(
         namespace=self._uuid_ns,
         host='somehost')
     uuid_b = place_utils.agent_resource_provider_uuid(
         namespace=self._uuid_ns,
         host='somehost')
     self.assertEqual(uuid_a, uuid_b)
Esempio n. 3
0
    def _deferred_update_rp_pp_inventory(self):
        agent_rp_inventories = []

        for hypervisor, pp_values in self._rp_pp.items():
            agent_rp_uuid = place_utils.agent_resource_provider_uuid(
                self._driver_uuid_namespace, hypervisor)

            inventories = {}
            for direction, rp_class in (
                (nlib_const.EGRESS_DIRECTION,
                 orc.NET_PACKET_RATE_EGR_KILOPACKET_PER_SEC),
                (nlib_const.INGRESS_DIRECTION,
                 orc.NET_PACKET_RATE_IGR_KILOPACKET_PER_SEC),
                (nlib_const.ANY_DIRECTION,
                 orc.NET_PACKET_RATE_KILOPACKET_PER_SEC)):
                if pp_values.get(direction):
                    inventory = dict(self._rp_pp_inventory_defaults)
                    inventory['total'] = pp_values[direction]
                    inventories[rp_class] = inventory

            if inventories:
                agent_rp_inventories.append(
                    DeferredCall(
                        self._client.update_resource_provider_inventories,
                        resource_provider_uuid=agent_rp_uuid,
                        inventories=inventories))

        return agent_rp_inventories
Esempio n. 4
0
 def _deferred_create_agent_rp(self):
     agent_rp_name = '%s:%s' % (self._agent_host, self._agent_type)
     agent_rp_uuid = place_utils.agent_resource_provider_uuid(
         self._driver_uuid_namespace, self._agent_host)
     agent_rp = DeferredCall(
         self._client.ensure_resource_provider,
         resource_provider={
             'name': agent_rp_name,
             'uuid': agent_rp_uuid,
             'parent_provider_uuid': self._agent_host_rp_uuid})
     return agent_rp
Esempio n. 5
0
 def _deferred_create_agent_rp(self):
     agent_rp_name = '%s:%s' % (self._agent_host, self._agent_type)
     agent_rp_uuid = place_utils.agent_resource_provider_uuid(
         self._driver_uuid_namespace, self._agent_host)
     agent_rp = DeferredCall(self._client.ensure_resource_provider,
                             resource_provider={
                                 'name':
                                 agent_rp_name,
                                 'uuid':
                                 agent_rp_uuid,
                                 'parent_provider_uuid':
                                 self._agent_host_rp_uuid
                             })
     return agent_rp
Esempio n. 6
0
 def _deferred_create_device_rps(self):
     rps = []
     for device in self._rp_bandwidths:
         hypervisor = self._hypervisor_rps[device]
         rp_name = '%s:%s:%s' % (hypervisor['name'], self._agent_type,
                                 device)
         rp_uuid = place_utils.device_resource_provider_uuid(
             self._driver_uuid_namespace, hypervisor['name'], device)
         agent_rp_uuid = place_utils.agent_resource_provider_uuid(
             self._driver_uuid_namespace, hypervisor['name'])
         rps.append(
             DeferredCall(
                 self._client.ensure_resource_provider, {
                     'name': rp_name,
                     'uuid': rp_uuid,
                     'parent_provider_uuid': agent_rp_uuid
                 }))
     return rps
Esempio n. 7
0
 def _deferred_create_agent_rps(self):
     # While an instance of this class represents a single agent,
     # that agent is allowed to handle devices of multiple hypervisors.
     # Since each hypervisor has its own root resource provider
     # we must create an agent RP under each hypervisor RP.
     rps = []
     for hypervisor in self._hypervisor_rps.values():
         agent_rp_name = '%s:%s' % (hypervisor['name'], self._agent_type)
         agent_rp_uuid = place_utils.agent_resource_provider_uuid(
             self._driver_uuid_namespace, hypervisor['name'])
         rps.append(
             DeferredCall(self._client.ensure_resource_provider,
                          resource_provider={
                              'name': agent_rp_name,
                              'uuid': agent_rp_uuid,
                              'parent_provider_uuid': hypervisor['uuid']
                          }))
     return rps
Esempio n. 8
0
    def _deferred_update_agent_rp_traits(self, traits_):
        agent_rp_traits = []

        if not traits_:
            return agent_rp_traits

        # Remove hypervisor duplicates to avoid calling placement API multiple
        # times for the same hypervisor.
        hypervisors = set(h['name'] for h in self._hypervisor_rps.values())
        for hypervisor in hypervisors:
            agent_rp_uuid = place_utils.agent_resource_provider_uuid(
                self._driver_uuid_namespace, hypervisor)
            agent_rp_traits.append(
                DeferredCall(self._client.update_resource_provider_traits,
                             resource_provider_uuid=agent_rp_uuid,
                             traits=traits_))

        return agent_rp_traits
Esempio n. 9
0
    def responsible_for_ports_allocation(self, context):
        """Report if an agent is responsible for a resource provider.

        :param context: PortContext instance describing the port
        :returns: True for responsible, False for not responsible

        An agent based mechanism driver is reponsible for a resource provider
        if an agent of it is responsible for that resource provider. An agent
        reports responsibility by including the resource provider in the
        configurations field of the agent heartbeat.
        """
        uuid_ns = self.resource_provider_uuid5_namespace
        if uuid_ns is None:
            return False
        if 'allocation' not in context.current['binding:profile']:
            return False

        allocation = context.current['binding:profile']['allocation']
        host_agents = self._possible_agents_for_port(context)

        reported = {}
        for agent in host_agents:
            if const.RP_BANDWIDTHS in agent['configurations']:
                for device in agent['configurations'][
                        const.RP_BANDWIDTHS].keys():
                    device_rp_uuid = place_utils.device_resource_provider_uuid(
                        namespace=uuid_ns, host=agent['host'], device=device)
                    for group, rp in allocation.items():
                        if device_rp_uuid == uuid.UUID(rp):
                            reported[group] = reported.get(group, []) + [agent]
            if (const.RP_PP_WITHOUT_DIRECTION in agent['configurations']
                    or const.RP_PP_WITH_DIRECTION in agent['configurations']):
                for group, rp in allocation.items():
                    agent_rp_uuid = place_utils.agent_resource_provider_uuid(
                        namespace=uuid_ns, host=agent['host'])
                    if agent_rp_uuid == uuid.UUID(rp):
                        reported[group] = reported.get(group, []) + [agent]

        for group, agents in reported.items():
            if len(agents) == 1:
                agent = agents[0]
                LOG.debug(
                    "Agent %(agent)s of type %(agent_type)s reports to be "
                    "responsible for resource provider %(rsc_provider)s", {
                        'agent': agent['id'],
                        'agent_type': agent['agent_type'],
                        'rsc_provider': allocation[group]
                    })
            elif len(agents) > 1:
                LOG.error(
                    "Agent misconfiguration, multiple agents on the same "
                    "host %(host)s reports being responsible for resource "
                    "provider %(rsc_provider)s: %(agents)s", {
                        'host': context.current['binding:host_id'],
                        'rsc_provider': allocation[group],
                        'agents': [agent['id'] for agent in agents]
                    })
                return False
            else:
                # not responsible, must be somebody else
                return False

        return (len(reported) >= 1 and (len(reported) == len(allocation)))