Esempio n. 1
0
    def create_ha_port_and_bind(self, plugin, context, router_id,
                                tenant_id, agent, is_manual_scheduling=False):
        """Creates and binds a new HA port for this agent."""
        ctxt = context.elevated()
        router_db = plugin._get_router(ctxt, router_id)
        creator = functools.partial(self._add_port_from_net_and_ensure_vr_id,
                                    plugin, ctxt, router_db, tenant_id)
        dep_getter = functools.partial(plugin.get_ha_network, ctxt, tenant_id)
        dep_creator = functools.partial(plugin._create_ha_network,
                                        ctxt, tenant_id)
        dep_deleter = functools.partial(plugin._delete_ha_network, ctxt)
        dep_id_attr = 'network_id'

        # This might fail in case of concurrent calls, which is good for us
        # as we can skip the rest of this function.
        binding = self.bind_router(
            plugin, context, router_id, agent['id'],
            is_manual_scheduling=is_manual_scheduling, is_ha=True)
        if not binding:
            return

        try:
            port_binding = utils.create_object_with_dependency(
                creator, dep_getter, dep_creator,
                dep_id_attr, dep_deleter)[0]
            with db_api.autonested_transaction(context.session):
                port_binding.l3_agent_id = agent['id']
        except db_exc.DBDuplicateEntry:
            LOG.debug("Router %(router)s already scheduled for agent "
                      "%(agent)s", {'router': router_id,
                                    'agent': agent['id']})
        except l3.RouterNotFound:
            LOG.debug('Router %s has already been removed '
                      'by concurrent operation', router_id)
Esempio n. 2
0
    def create_ha_port_and_bind(self, plugin, context, router_id,
                                tenant_id, agent):
        """Creates and binds a new HA port for this agent."""
        ctxt = context.elevated()
        creator = functools.partial(self._add_port_from_net,
                                    plugin, ctxt, router_id, tenant_id)
        dep_getter = functools.partial(plugin.get_ha_network, ctxt, tenant_id)
        dep_creator = functools.partial(plugin._create_ha_network,
                                        ctxt, tenant_id)
        dep_deleter = functools.partial(plugin._delete_ha_network, ctxt)
        dep_id_attr = 'network_id'
        try:
            port_binding = utils.create_object_with_dependency(
                creator, dep_getter, dep_creator, dep_id_attr, dep_deleter)[0]
            with db_api.autonested_transaction(context.session):
                port_binding.l3_agent_id = agent['id']
        except db_exc.DBDuplicateEntry:
            LOG.debug("Router %(router)s already scheduled for agent "
                      "%(agent)s", {'router': router_id, 'agent': agent['id']})
        except l3.RouterNotFound:
            LOG.debug('Router %s has already been removed '
                      'by concurrent operation', router_id)
            return

        self.bind_router(context, router_id, agent)
Esempio n. 3
0
 def _create_ha_interfaces_and_ensure_network(self, context, router_db):
     """Attach interfaces to a network while tolerating network deletes."""
     creator = functools.partial(self._create_ha_interfaces, context, router_db)
     dep_getter = functools.partial(self.get_ha_network, context, router_db.tenant_id)
     dep_creator = functools.partial(self._create_ha_network, context, router_db.tenant_id)
     dep_id_attr = "network_id"
     return n_utils.create_object_with_dependency(creator, dep_getter, dep_creator, dep_id_attr)
Esempio n. 4
0
 def _ensure_vr_id_and_network(self, context, router_db):
     """Attach vr_id to router while tolerating network deletes."""
     creator = functools.partial(self._ensure_vr_id,
                                 context, router_db)
     dep_getter = functools.partial(self.get_ha_network,
                                    context, router_db.tenant_id)
     dep_creator = functools.partial(self._create_ha_network,
                                     context, router_db.tenant_id)
     dep_deleter = functools.partial(self._delete_ha_network, context)
     dep_id_attr = 'network_id'
     return n_utils.create_object_with_dependency(
         creator, dep_getter, dep_creator, dep_id_attr, dep_deleter)[1]
Esempio n. 5
0
 def _ensure_vr_id_and_network(self, context, router_db):
     """Attach vr_id to router while tolerating network deletes."""
     creator = functools.partial(self._ensure_vr_id, context, router_db)
     dep_getter = functools.partial(self.get_ha_network, context,
                                    router_db.tenant_id)
     dep_creator = functools.partial(self._create_ha_network, context,
                                     router_db.tenant_id)
     dep_deleter = functools.partial(self._delete_ha_network, context)
     dep_id_attr = 'network_id'
     return n_utils.create_object_with_dependency(creator, dep_getter,
                                                  dep_creator, dep_id_attr,
                                                  dep_deleter)[1]
Esempio n. 6
0
    def create_ha_port_and_bind(self,
                                plugin,
                                context,
                                router_id,
                                tenant_id,
                                agent,
                                is_manual_scheduling=False):
        """Creates and binds a new HA port for this agent."""
        ctxt = context.elevated()
        router_db = plugin._get_router(ctxt, router_id)
        creator = functools.partial(self._add_port_from_net_and_ensure_vr_id,
                                    plugin, ctxt, router_db, tenant_id)
        dep_getter = functools.partial(plugin.get_ha_network, ctxt, tenant_id)
        dep_creator = functools.partial(plugin._create_ha_network, ctxt,
                                        tenant_id)
        dep_deleter = functools.partial(plugin._delete_ha_network, ctxt)
        dep_id_attr = 'network_id'

        # This might fail in case of concurrent calls, which is good for us
        # as we can skip the rest of this function.
        binding = self.bind_router(plugin,
                                   context,
                                   router_id,
                                   agent['id'],
                                   is_manual_scheduling=is_manual_scheduling,
                                   is_ha=True)
        if not binding:
            return

        try:
            port_binding = utils.create_object_with_dependency(
                creator, dep_getter, dep_creator, dep_id_attr, dep_deleter)[0]
            with db_api.autonested_transaction(context.session):
                port_binding.l3_agent_id = agent['id']
        except db_exc.DBDuplicateEntry:
            LOG.debug(
                "Router %(router)s already scheduled for agent "
                "%(agent)s", {
                    'router': router_id,
                    'agent': agent['id']
                })
        except l3.RouterNotFound:
            LOG.debug(
                'Router %s has already been removed '
                'by concurrent operation', router_id)
            # we try to clear the HA network here in case the port we created
            # blocked the concurrent router delete operation from getting rid
            # of the HA network
            ha_net = plugin.get_ha_network(ctxt, tenant_id)
            if ha_net:
                plugin.safe_delete_ha_network(ctxt, ha_net, tenant_id)
Esempio n. 7
0
    def create_ha_port_and_bind(self,
                                plugin,
                                context,
                                router_id,
                                tenant_id,
                                agent,
                                is_manual_scheduling=False):
        """Creates and binds a new HA port for this agent."""
        ctxt = context.elevated()
        router_db = plugin._get_router(ctxt, router_id)
        creator = functools.partial(self._add_port_from_net_and_ensure_vr_id,
                                    plugin, ctxt, router_db, tenant_id)
        dep_getter = functools.partial(plugin.get_ha_network, ctxt, tenant_id)
        dep_creator = functools.partial(plugin._create_ha_network, ctxt,
                                        tenant_id)
        dep_deleter = functools.partial(plugin._delete_ha_network, ctxt)
        dep_id_attr = 'network_id'

        for attempts in range(1, db_api.MAX_RETRIES + 1):
            binding_index = plugin.get_vacant_binding_index(
                context, router_id, is_manual_scheduling)
            if binding_index == -1:
                LOG.debug("Couldn't find a vacant binding_index for router %s",
                          router_id)
                return

            # This might fail in case of concurrent calls, which is good for us
            # as we can skip the rest of this function.
            if not self.bind_router(context, router_id, agent, binding_index):
                return

            try:
                port_binding = utils.create_object_with_dependency(
                    creator, dep_getter, dep_creator, dep_id_attr,
                    dep_deleter)[0]
                with db_api.autonested_transaction(context.session):
                    port_binding.l3_agent_id = agent['id']
                return
            except db_exc.DBDuplicateEntry:
                LOG.debug(
                    "Router %(router)s already scheduled for agent "
                    "%(agent)s", {
                        'router': router_id,
                        'agent': agent['id']
                    })
                return
            except l3.RouterNotFound:
                LOG.debug(
                    'Router %s has already been removed '
                    'by concurrent operation', router_id)
                return
Esempio n. 8
0
    def create_ha_port_and_bind(self, plugin, context, router_id,
                                tenant_id, agent, is_manual_scheduling=False):
        """Creates and binds a new HA port for this agent."""
        ctxt = context.elevated()
        router_db = plugin._get_router(ctxt, router_id)
        creator = functools.partial(self._add_port_from_net_and_ensure_vr_id,
                                    plugin, ctxt, router_db, tenant_id)
        dep_getter = functools.partial(plugin.get_ha_network, ctxt, tenant_id)
        dep_creator = functools.partial(plugin._create_ha_network,
                                        ctxt, tenant_id)
        dep_deleter = functools.partial(plugin._delete_ha_network, ctxt)
        dep_id_attr = 'network_id'

        # This might fail in case of concurrent calls, which is good for us
        # as we can skip the rest of this function.
        binding = self.bind_router(
            plugin, context, router_id, agent['id'],
            is_manual_scheduling=is_manual_scheduling, is_ha=True)
        if not binding:
            return

        try:
            port_binding = utils.create_object_with_dependency(
                creator, dep_getter, dep_creator,
                dep_id_attr, dep_deleter)[0]
            with lib_db_api.CONTEXT_WRITER.using(context):
                port_binding = (
                    l3_hamode_obj.L3HARouterAgentPortBinding.get_object(
                        context, port_id=port_binding['port_id']))
                port_binding.l3_agent_id = agent['id']
                port_binding.update()
        except db_exc.DBDuplicateEntry:
            LOG.debug("Router %(router)s already scheduled for agent "
                      "%(agent)s", {'router': router_id,
                                    'agent': agent['id']})
            port_id = port_binding.port_id
            # Below call will also delete entry from L3HARouterAgentPortBinding
            # and RouterPort tables
            plugin._core_plugin.delete_port(context, port_id,
                                            l3_port_check=False)
        except l3_exc.RouterNotFound:
            LOG.debug('Router %s has already been removed '
                      'by concurrent operation', router_id)
            # we try to clear the HA network here in case the port we created
            # blocked the concurrent router delete operation from getting rid
            # of the HA network
            ha_net = plugin.get_ha_network(ctxt, tenant_id)
            if ha_net:
                plugin.safe_delete_ha_network(ctxt, ha_net, tenant_id)
Esempio n. 9
0
    def create_ha_port_and_bind(self, plugin, context, router_id,
                                tenant_id, agent, is_manual_scheduling=False):
        """Creates and binds a new HA port for this agent."""
        ctxt = context.elevated()
        router_db = plugin._get_router(ctxt, router_id)
        creator = functools.partial(self._add_port_from_net_and_ensure_vr_id,
                                    plugin, ctxt, router_db, tenant_id)
        dep_getter = functools.partial(plugin.get_ha_network, ctxt, tenant_id)
        dep_creator = functools.partial(plugin._create_ha_network,
                                        ctxt, tenant_id)
        dep_deleter = functools.partial(plugin._delete_ha_network, ctxt)
        dep_id_attr = 'network_id'

        # This might fail in case of concurrent calls, which is good for us
        # as we can skip the rest of this function.
        binding = self.bind_router(
            plugin, context, router_id, agent['id'],
            is_manual_scheduling=is_manual_scheduling, is_ha=True)
        if not binding:
            return

        try:
            port_binding = utils.create_object_with_dependency(
                creator, dep_getter, dep_creator,
                dep_id_attr, dep_deleter)[0]
            with lib_db_api.autonested_transaction(context.session):
                port_binding.l3_agent_id = agent['id']
        except db_exc.DBDuplicateEntry:
            LOG.debug("Router %(router)s already scheduled for agent "
                      "%(agent)s", {'router': router_id,
                                    'agent': agent['id']})
            port_id = port_binding.port_id
            # Below call will also delete entry from L3HARouterAgentPortBinding
            # and RouterPort tables
            plugin._core_plugin.delete_port(context, port_id,
                                            l3_port_check=False)
        except l3_exc.RouterNotFound:
            LOG.debug('Router %s has already been removed '
                      'by concurrent operation', router_id)
            # we try to clear the HA network here in case the port we created
            # blocked the concurrent router delete operation from getting rid
            # of the HA network
            ha_net = plugin.get_ha_network(ctxt, tenant_id)
            if ha_net:
                plugin.safe_delete_ha_network(ctxt, ha_net, tenant_id)
Esempio n. 10
0
    def create_ha_port_and_bind(self, plugin, context, router_id,
                                tenant_id, agent, is_manual_scheduling=False):
        """Creates and binds a new HA port for this agent."""
        ctxt = context.elevated()
        creator = functools.partial(self._add_port_from_net,
                                    plugin, ctxt, router_id, tenant_id)
        dep_getter = functools.partial(plugin.get_ha_network, ctxt, tenant_id)
        dep_creator = functools.partial(plugin._create_ha_network,
                                        ctxt, tenant_id)
        dep_deleter = functools.partial(plugin._delete_ha_network, ctxt)
        dep_id_attr = 'network_id'

        for attempts in range(1, db_api.MAX_RETRIES + 1):
            binding_index = plugin.get_vacant_binding_index(
                context, router_id, is_manual_scheduling)
            if binding_index == -1:
                LOG.debug("Couldn't find a vacant binding_index for router %s",
                          router_id)
                return

            # This might fail in case of concurrent calls, which is good for us
            # as we can skip the rest of this function.
            if not self.bind_router(context, router_id, agent, binding_index):
                return

            try:
                port_binding = utils.create_object_with_dependency(
                    creator, dep_getter, dep_creator,
                    dep_id_attr, dep_deleter)[0]
                with db_api.autonested_transaction(context.session):
                    port_binding.l3_agent_id = agent['id']
                return
            except db_exc.DBDuplicateEntry:
                LOG.debug("Router %(router)s already scheduled for agent "
                          "%(agent)s", {'router': router_id,
                                        'agent': agent['id']})
                return
            except l3.RouterNotFound:
                LOG.debug('Router %s has already been removed '
                          'by concurrent operation', router_id)
                return