Exemplo n.º 1
0
    def _transaction(self):
        req = self._txn_q.popleft()
        txn = idl.Transaction(self._idl)

        uuids = req.func(self._idl.tables, txn.insert)
        status = txn.commit_block()

        insert_uuids = {}
        err_msg = None

        if status in (idl.Transaction.SUCCESS,
                      idl.Transaction.UNCHANGED):
            if uuids:
                if isinstance(uuids, uuid.UUID):
                    insert_uuids[uuids] = txn.get_insert_uuid(uuids)

                else:
                    insert_uuids = dict((uuid, txn.get_insert_uuid(uuid))
                                        for uuid in uuids)
        else:
            err_msg = txn.get_error()

        rep = event.EventModifyReply(self.system_id, status, insert_uuids,
                                     err_msg)
        self.reply_to_request(req, rep)
Exemplo n.º 2
0
        def commit_f():
            operation = None
            while True:
                txn = idl.Transaction(self.idl)
                if bgp_path['is_withdraw']:
                    operation = 'del'
                    rows = self.idl.tables['BGP_Route'].rows.values()
                    for row in rows:
                        if utils.get_column_value(
                                row, 'prefix') == bgp_path['prefix']:
                            operation = 'del'
                            prefix_uuid = utils.get_column_value(row, '_uuid')
                            self.idl.tables['BGP_Route'].rows[
                                prefix_uuid].delete()

                else:
                    operation = 'add'
                    row_nh = utils.row_by_value(self.idl, 'BGP_Nexthop',
                                                'ip_address',
                                                bgp_path['nexthop'])
                    if not row_nh:
                        row_nh = txn.insert(self.idl.tables['BGP_Nexthop'])
                        row_nh.ip_address = bgp_path['nexthop']
                        row_nh.type = 'unicast'

                    row_path = txn.insert(self.idl.tables['BGP_Route'])
                    row_path.address_family = 'ipv4'
                    row_path.bgp_nexthops = row_nh
                    row_path.distance = []
                    row_path.metric = 0
                    row_path.path_attributes = bgp_path['bgp_pathattr']
                    row_path.peer = 'Remote announcement'
                    row_path.prefix = bgp_path['prefix']
                    row_path.sub_address_family = 'unicast'
                    row_path.vrf = self.idl.tables['VRF'].rows.values()[0]

                status = txn.commit_block()
                seqno = self.idl.change_seqno
                if status == txn.TRY_AGAIN:
                    log.error("OVSDB transaction returned TRY_AGAIN, retrying")
                    utils.wait_for_change(self.idl, self.timeout, seqno)
                    continue
                elif status == txn.ERROR:
                    log.error("OVSDB transaction returned ERROR: {0}".format(
                        txn.get_error()))
                elif status == txn.ABORTED:
                    log.error("Transaction aborted")
                    return
                elif status == txn.UNCHANGED:
                    log.error("Transaction caused no change")

                break

            if operation is None:
                log.warn('route is not exist in ops: prefix={0}'.format(
                    bgp_path['prefix']))
            else:
                log.debug('Send bgp route to ops: type={0}, prefix={1}'.format(
                    operation, bgp_path['prefix']))
Exemplo n.º 3
0
    def do_commit(self):
        self.start_time = time.time()
        attempts = 0
        if not self.commands:
            LOG.debug("There are no commands to commit")
            return []
        while True:
            if attempts > 0 and self.timeout_exceeded():
                raise RuntimeError("OVS transaction timed out")
            attempts += 1
            # TODO(twilson) Make sure we don't loop longer than vsctl_timeout
            txn = idl.Transaction(self.api.idl)
            self.pre_commit(txn)
            for i, command in enumerate(self.commands):
                LOG.debug("Running txn n=%(n)d command(idx=%(idx)s): %(cmd)s",
                          {'idx': i, 'cmd': command, 'n': attempts})
                try:
                    command.run_idl(txn)
                except Exception:
                    txn.abort()
                    if self.check_error:
                        raise
            status = txn.commit_block()
            if status == txn.TRY_AGAIN:
                LOG.debug("OVSDB transaction returned TRY_AGAIN, retrying")
                # In the case that there is a reconnection after
                # Connection.run() calls self.idl.run() but before do_commit()
                # is called, commit_block() can loop w/o calling idl.run()
                # which does the reconnect logic. It will then always return
                # TRY_AGAIN until we time out and Connection.run() calls
                # idl.run() again. So, call idl.run() here just in case.
                self.api.idl.run()
                continue
            elif status in (txn.ERROR, txn.NOT_LOCKED):
                msg = 'OVSDB Error: '
                if status == txn.NOT_LOCKED:
                    msg += ("The transaction failed because the IDL has "
                            "been configured to require a database lock "
                            "but didn't get it yet or has already lost it")
                else:
                    msg += txn.get_error()

                if self.log_errors:
                    LOG.error(msg)
                if self.check_error:
                    # For now, raise similar error to vsctl/utils.execute()
                    raise RuntimeError(msg)
                return
            elif status == txn.ABORTED:
                LOG.debug("Transaction aborted")
                return
            elif status == txn.UNCHANGED:
                LOG.debug("Transaction caused no change")
            elif status == txn.SUCCESS:
                self.post_commit(txn)
            else:
                LOG.debug("Transaction returned an unknown status: %s", status)

            return [cmd.result for cmd in self.commands]
Exemplo n.º 4
0
    def add_chassis(self, name, ip, tunnel_type):
        txn = idl.Transaction(self.idl)

        encap_row = txn.insert(self.idl.tables['Encap'])
        encap_row.ip = ip
        encap_row.type = tunnel_type

        chassis_row = txn.insert(self.idl.tables['Chassis'])
        chassis_row.encaps = encap_row
        chassis_row.name = name
        status = txn.commit_block()
        return status
Exemplo n.º 5
0
 def run(self):
     # For demo, txn is single command, this would go on Tranaction obj
     # and the loop would iterate through commands on the txn
     if not self.txn:
         self.has_run = False
         self.txn = idl.Transaction(i)
     if self.has_run:
         return
     row = self.txn.insert(self.idl.tables['Bridge'])
     row.name = "testbr%d" % self.val
     next(iter(self.idl.tables['Open_vSwitch'].rows.values())).addvalue(
         'bridges', row)
     self.has_run = True
Exemplo n.º 6
0
    def do_commit(self):
        start_time = time.time()
        attempts = 0
        while True:
            elapsed_time = time.time() - start_time
            if attempts > 0 and elapsed_time > self.context.vsctl_timeout:
                raise RuntimeError("OVS transaction timed out")
            attempts += 1
            # TODO(twilson) Make sure we don't loop longer than vsctl_timeout
            txn = idl.Transaction(self.api.idl)
            for i, command in enumerate(self.commands):
                LOG.debug("Running txn command(idx=%(idx)s): %(cmd)s", {
                    'idx': i,
                    'cmd': command
                })
                try:
                    command.run_idl(txn)
                except Exception:
                    with excutils.save_and_reraise_exception() as ctx:
                        txn.abort()
                        if not self.check_error:
                            ctx.reraise = False
            seqno = self.api.idl.change_seqno
            status = txn.commit_block()
            if status == txn.TRY_AGAIN:
                LOG.debug("OVSDB transaction returned TRY_AGAIN, retrying")
                if self.api.idl._session.rpc.status != 0:
                    LOG.debug("Lost connection to OVSDB, reconnecting!")
                    self.api.idl.force_reconnect()
                idlutils.wait_for_change(
                    self.api.idl, self.context.vsctl_timeout - elapsed_time,
                    seqno)
                continue
            elif status == txn.ERROR:
                msg = _LE("OVSDB Error: %s") % txn.get_error()
                if self.log_errors:
                    LOG.error(msg)
                if self.check_error:
                    # For now, raise similar error to vsctl/utils.execute()
                    raise RuntimeError(msg)
                return
            elif status == txn.ABORTED:
                LOG.debug("Transaction aborted")
                return
            elif status == txn.UNCHANGED:
                LOG.debug("Transaction caused no change")

            return [cmd.result for cmd in self.commands]
Exemplo n.º 7
0
    def register_local_ports(self, chassis_name, local_ports_ids):
        txn = idl.Transaction(self.idl)

        chassis = idlutils.row_by_value(self.idl,
                                        'Chassis',
                                        'name', chassis_name)

        for binding in self.idl.tables['Binding'].rows.values():
            if binding.logical_port in local_ports_ids:
                if binding.chassis == chassis_name:
                    continue
                # Bind this port to this chassis
                binding.chassis = chassis
            elif binding.chassis == chassis_name:
                binding.chassis = []

        status = txn.commit_block()
        return status
Exemplo n.º 8
0
    def do_commit(self):
        self.start_time = time.time()
        attempts = 0
        while True:
            if attempts > 0 and self.timeout_exceeded():
                raise RuntimeError(_("OVS transaction timed out"))
            attempts += 1
            # TODO(twilson) Make sure we don't loop longer than vsctl_timeout
            txn = idl.Transaction(self.api.idl)
            self.pre_commit(txn)
            for i, command in enumerate(self.commands):
                LOG.debug("Running txn command(idx=%(idx)s): %(cmd)s",
                          {'idx': i, 'cmd': command})
                try:
                    command.run_idl(txn)
                except Exception:
                    with excutils.save_and_reraise_exception() as ctx:
                        txn.abort()
                        if not self.check_error:
                            ctx.reraise = False
            status = txn.commit_block()
            if status == txn.TRY_AGAIN:
                LOG.debug("OVSDB transaction returned TRY_AGAIN, retrying")
                continue
            elif status == txn.ERROR:
                msg = _("OVSDB Error: %s") % txn.get_error()
                if self.log_errors:
                    LOG.error(msg)
                if self.check_error:
                    # For now, raise similar error to vsctl/utils.execute()
                    raise RuntimeError(msg)
                return
            elif status == txn.ABORTED:
                LOG.debug("Transaction aborted")
                return
            elif status == txn.UNCHANGED:
                LOG.debug("Transaction caused no change")
            elif status == txn.SUCCESS:
                self.post_commit(txn)

            return [cmd.result for cmd in self.commands]