Example #1
0
    def _ensure_vr_id(self, context, router_db, ha_network):
        router_id = router_db.id
        network_id = ha_network.network_id

        # TODO(kevinbenton): let decorator handle duplicate retry
        # like in review.openstack.org/#/c/367179/1/neutron/db/l3_hamode_db.py
        for count in range(MAX_ALLOCATION_TRIES):
            try:
                # NOTE(kevinbenton): we disallow subtransactions because the
                # retry logic will bust any parent transactions
                with context.session.begin():
                    if router_db.extra_attributes.ha_vr_id:
                        LOG.debug(
                            "Router %(router_id)s has already been "
                            "allocated a ha_vr_id %(ha_vr_id)d!",
                            {'router_id': router_id,
                             'ha_vr_id': router_db.extra_attributes.ha_vr_id})
                        return

                    old_router = self._make_router_dict(router_db)
                    allocated_vr_ids = self._get_allocated_vr_id(context,
                                                                 network_id)
                    available_vr_ids = VR_ID_RANGE - allocated_vr_ids

                    if not available_vr_ids:
                        raise l3ha_exc.NoVRIDAvailable(router_id=router_id)

                    allocation = l3_hamode.L3HARouterVRIdAllocation(
                        context, network_id=network_id,
                        vr_id=available_vr_ids.pop())
                    allocation.create()

                    router_db.extra_attributes.ha_vr_id = allocation.vr_id
                    LOG.debug(
                        "Router %(router_id)s has been allocated a ha_vr_id "
                        "%(ha_vr_id)d.",
                        {'router_id': router_id, 'ha_vr_id': allocation.vr_id})
                    router_body = {l3_apidef.ROUTER:
                            {l3_ext_ha_apidef.HA_INFO: True,
                             'ha_vr_id': allocation.vr_id}}
                    registry.publish(resources.ROUTER, events.PRECOMMIT_UPDATE,
                                     self, payload=events.DBEventPayload(
                                         context, request_body=router_body,
                                         states=(old_router,),
                                         resource_id=router_id,
                                         desired_state=router_db))

                    return allocation.vr_id

            except obj_base.NeutronDbObjectDuplicateEntry:
                LOG.info("Attempt %(count)s to allocate a VRID in the "
                         "network %(network)s for the router %(router)s",
                         {'count': count, 'network': network_id,
                          'router': router_id})

        raise l3ha_exc.MaxVRIDAllocationTriesReached(
            network_id=network_id, router_id=router_id,
            max_tries=MAX_ALLOCATION_TRIES)
Example #2
0
    def _ensure_vr_id(self, context, router_db, ha_network):
        router_id = router_db.id
        network_id = ha_network.network_id

        # TODO(kevinbenton): let decorator handle duplicate retry
        # like in review.openstack.org/#/c/367179/1/neutron/db/l3_hamode_db.py
        for count in range(MAX_ALLOCATION_TRIES):
            try:
                # NOTE(kevinbenton): we disallow subtransactions because the
                # retry logic will bust any parent transactions
                with context.session.begin():
                    if router_db.extra_attributes.ha_vr_id:
                        LOG.debug(
                            "Router %(router_id)s has already been "
                            "allocated a ha_vr_id %(ha_vr_id)d!", {
                                'router_id': router_id,
                                'ha_vr_id': router_db.extra_attributes.ha_vr_id
                            })
                        return

                    allocated_vr_ids = self._get_allocated_vr_id(
                        context, network_id)
                    available_vr_ids = VR_ID_RANGE - allocated_vr_ids

                    if not available_vr_ids:
                        raise l3_ha.NoVRIDAvailable(router_id=router_id)

                    allocation = l3_hamode.L3HARouterVRIdAllocation(
                        context,
                        network_id=network_id,
                        vr_id=available_vr_ids.pop())
                    allocation.create()

                    router_db.extra_attributes.ha_vr_id = allocation.vr_id
                    LOG.debug(
                        "Router %(router_id)s has been allocated a ha_vr_id "
                        "%(ha_vr_id)d.", {
                            'router_id': router_id,
                            'ha_vr_id': allocation.vr_id
                        })

                    return allocation.vr_id

            except obj_base.NeutronDbObjectDuplicateEntry:
                LOG.info(
                    "Attempt %(count)s to allocate a VRID in the "
                    "network %(network)s for the router %(router)s", {
                        'count': count,
                        'network': network_id,
                        'router': router_id
                    })

        raise l3_ha.MaxVRIDAllocationTriesReached(
            network_id=network_id,
            router_id=router_id,
            max_tries=MAX_ALLOCATION_TRIES)