Beispiel #1
0
    def test_uuid32(self):
        uA = uuid32()
        uB = uuid32()

        prime = __builtins__.get('long', int)
        assert isinstance(uA, prime)
        assert isinstance(uB, prime)
        assert uA != uB
        assert uA < 0x100000000
        assert uB < 0x100000000
Beispiel #2
0
    def test_uuid32(self):
        uA = uuid32()
        uB = uuid32()

        prime = __builtins__.get('long', int)
        assert isinstance(uA, prime)
        assert isinstance(uB, prime)
        assert uA != uB
        assert uA < 0x100000000
        assert uB < 0x100000000
 def __init__(self, ipdb=None, mode=None, parent=None, uid=None):
     #
     if ipdb is not None:
         self.nl = ipdb.nl
         self.ipdb = ipdb
     else:
         self.nl = None
         self.ipdb = None
     #
     self._parent = None
     if parent is not None:
         self._mode = mode or parent._mode
         self._parent = parent
     elif ipdb is not None:
         self._mode = mode or ipdb.mode
     else:
         self._mode = mode or 'implicit'
     #
     self.nlmsg = None
     self.uid = uid or uuid32()
     self.last_error = None
     self._commit_hooks = []
     self._sids = []
     self._ts = threading.local()
     self._snapshots = {}
     self.global_tx = {}
     self._targets = {}
     self._local_targets = {}
     self._write_lock = threading.RLock()
     self._direct_state = State(self._write_lock)
     self._linked_sets = self._linked_sets or set()
     #
     for i in self._fields:
         TransactionalBase.__setitem__(self, i, None)
Beispiel #4
0
 def __init__(self, ipdb=None, mode=None, parent=None, uid=None):
     #
     if ipdb is not None:
         self.nl = ipdb.nl
         self.ipdb = ipdb
     else:
         self.nl = None
         self.ipdb = None
     #
     self._parent = None
     if parent is not None:
         self._mode = mode or parent._mode
         self._parent = parent
     elif ipdb is not None:
         self._mode = mode or ipdb.mode
     else:
         self._mode = mode or 'implicit'
     #
     self.nlmsg = None
     self.uid = uid or uuid32()
     self.last_error = None
     self._commit_hooks = []
     self._sids = []
     self._ts = threading.local()
     self._snapshots = {}
     self._targets = {}
     self._local_targets = {}
     self._write_lock = threading.RLock()
     self._direct_state = State(self._write_lock)
     self._linked_sets = self._linked_sets or set()
Beispiel #5
0
 def __init__(self, debug=False, timeout=3, do_connect=False,
              host=None, key=None, cert=None, ca=None,
              addr=None):
     addr = addr or uuid32()
     self._timeout = timeout
     self.iothread = IOBroker(addr=addr)
     self.default_broker = addr
     self.default_dport = 0
     self.uids = set()
     self.listeners = {}     # {nonce: Queue(), ...}
     self.callbacks = []     # [(predicate, callback, args), ...]
     self.debug = debug
     self.cid = None
     self._nonce = 0
     self.save = None
     self._nonce_lock = threading.Lock()
     if self.marshal is not None:
         self.marshal.debug = debug
         self.marshal = self.marshal()
     self.buffers = Queue.Queue()
     self._mirror = False
     self.host = host
     self._run_event = threading.Event()
     self._stop_event = threading.Event()
     self.start()
     self._run_event.wait()
     if do_connect:
         path = urlparse.urlparse(host).path
         (self.default_link,
          self.default_peer) = self.connect(self.host,
                                            key, cert, ca)
         self.default_dport = self.discover(self.default_target or path,
                                            self.default_peer)
 def __init__(self, url):
     if url.startswith('tcp://'):
         hostname = urlparse(url).netloc
         self.cmdch = SocketChannel(hostname, 4336)
         self.brdch = SocketChannel(hostname, 4336)
         self.uuid = uuid32()
         self.cmdch.send({'stage': 'init',
                          'domain': 'command',
                          'client': self.uuid})
         self.brdch.send({'stage': 'init',
                          'domain': 'broadcast',
                          'client': self.uuid})
     else:
         raise TypeError('remote connection type not supported')
     super(RemoteSocket, self).__init__()
     self.marshal = MarshalRtnl()
Beispiel #7
0
    def save_deps(self, ctxid, weak_ref, iclass):
        uuid = uuid32()
        obj = weak_ref()
        idx = self.indices[obj.table]
        conditions = []
        values = []
        for key in idx:
            conditions.append('f_%s = %s' % (key, self.plch))
            values.append(obj.get(iclass.nla2name(key)))
        #
        # save the old f_tflags value
        #
        tflags = (self.execute(
            '''
                           SELECT f_tflags FROM %s
                           WHERE %s
                           ''' % (obj.table, ' AND '.join(conditions)),
            values).fetchone()[0])
        #
        # mark tflags for obj
        #
        self.execute(
            '''
                     UPDATE %s SET
                         f_tflags = %s
                     WHERE %s
                     ''' % (obj.utable, self.plch, ' AND '.join(conditions)),
            [uuid] + values)
        #
        # t_flags is used in foreign keys ON UPDATE CASCADE, so all
        # related records will be marked, now just copy the marked data
        #
        for table in self.spec:
            #
            # create the snapshot table
            #
            self.execute('''
                         CREATE TABLE IF NOT EXISTS %s_%s
                         AS SELECT * FROM %s
                         WHERE
                             f_tflags IS NULL
                         ''' % (table, ctxid, table))
            #
            # copy the data -- is it possible to do it in one step?
            #
            self.execute(
                '''
                         INSERT INTO %s_%s
                         SELECT * FROM %s
                         WHERE
                             f_tflags = %s
                         ''' % (table, ctxid, table, self.plch), [uuid])

            if table.startswith('ifinfo_'):
                self.create_ifinfo_view(table, ctxid)
        #
        # unmark all the data
        #
        self.execute(
            '''
                     UPDATE %s SET
                         f_tflags = %s
                     WHERE %s
                     ''' % (obj.utable, self.plch, ' AND '.join(conditions)),
            [tflags] + values)
        for table in self.spec:
            self.execute(
                '''
                         UPDATE %s_%s SET f_tflags = %s
                         ''' % (table, ctxid, self.plch), [tflags])
            self.snapshots['%s_%s' % (table, ctxid)] = weak_ref
Beispiel #8
0
    def register_callback(self, callback, mode='post'):
        '''
        IPDB callbacks are routines executed on a RT netlink
        message arrival. There are two types of callbacks:
        "post" and "pre" callbacks.

        ...

        "Post" callbacks are executed after the message is
        processed by IPDB and all corresponding objects are
        created or deleted. Using ipdb reference in "post"
        callbacks you will access the most up-to-date state
        of the IP database.

        "Post" callbacks are executed asynchronously in
        separate threads. These threads can work as long
        as you want them to. Callback threads are joined
        occasionally, so for a short time there can exist
        stopped threads.

        ...

        "Pre" callbacks are synchronous routines, executed
        before the message gets processed by IPDB. It gives
        you the way to patch arriving messages, but also
        places a restriction: until the callback exits, the
        main event IPDB loop is blocked.

        Normally, only "post" callbacks are required. But in
        some specific cases "pre" also can be useful.

        ...

        The routine, `register_callback()`, takes two arguments:
            - callback function
            - mode (optional, default="post")

        The callback should be a routine, that accepts three
        arguments::

            cb(ipdb, msg, action)

        Arguments are:

            - **ipdb** is a reference to IPDB instance, that invokes
                the callback.
            - **msg** is a message arrived
            - **action** is just a msg['event'] field

        E.g., to work on a new interface, you should catch
        action == 'RTM_NEWLINK' and with the interface index
        (arrived in msg['index']) get it from IPDB::

            index = msg['index']
            interface = ipdb.interfaces[index]
        '''
        lock = threading.Lock()

        def safe(*argv, **kwarg):
            with lock:
                callback(*argv, **kwarg)

        safe.hook = callback
        safe.lock = lock
        safe.uuid = uuid32()

        if mode == 'post':
            self._post_callbacks[safe.uuid] = safe
        elif mode == 'pre':
            self._pre_callbacks[safe.uuid] = safe
        else:
            raise KeyError('Unknown callback mode')
        return safe.uuid
Beispiel #9
0
    def register_callback(self, callback, mode='post'):
        '''
        IPDB callbacks are routines executed on a RT netlink
        message arrival. There are two types of callbacks:
        "post" and "pre" callbacks.

        ...

        "Post" callbacks are executed after the message is
        processed by IPDB and all corresponding objects are
        created or deleted. Using ipdb reference in "post"
        callbacks you will access the most up-to-date state
        of the IP database.

        "Post" callbacks are executed asynchronously in
        separate threads. These threads can work as long
        as you want them to. Callback threads are joined
        occasionally, so for a short time there can exist
        stopped threads.

        ...

        "Pre" callbacks are synchronous routines, executed
        before the message gets processed by IPDB. It gives
        you the way to patch arriving messages, but also
        places a restriction: until the callback exits, the
        main event IPDB loop is blocked.

        Normally, only "post" callbacks are required. But in
        some specific cases "pre" also can be useful.

        ...

        The routine, `register_callback()`, takes two arguments:
            - callback function
            - mode (optional, default="post")

        The callback should be a routine, that accepts three
        arguments::

            cb(ipdb, msg, action)

        Arguments are:

            - **ipdb** is a reference to IPDB instance, that invokes
                the callback.
            - **msg** is a message arrived
            - **action** is just a msg['event'] field

        E.g., to work on a new interface, you should catch
        action == 'RTM_NEWLINK' and with the interface index
        (arrived in msg['index']) get it from IPDB::

            index = msg['index']
            interface = ipdb.interfaces[index]
        '''
        lock = threading.Lock()

        def safe(*argv, **kwarg):
            with lock:
                callback(*argv, **kwarg)

        safe.hook = callback
        safe.lock = lock
        safe.uuid = uuid32()

        if mode == 'post':
            self._post_callbacks[safe.uuid] = safe
        elif mode == 'pre':
            self._pre_callbacks[safe.uuid] = safe
        return safe.uuid
Beispiel #10
0
    def save_deps(self, objid, wref, iclass):
        uuid = uuid32()
        obj = wref()
        idx = self.indices[obj.table]
        conditions = []
        values = []
        for key in idx:
            conditions.append('f_%s = %s' % (key, self.plch))
            values.append(obj.get(iclass.nla2name(key)))
        #
        # save the old f_tflags value
        #
        tflags = self.fetchone('''
                               SELECT f_tflags FROM %s
                               WHERE %s
                               '''
                               % (obj.table,
                                  ' AND '.join(conditions)),
                               values)[0]
        #
        # mark tflags for obj
        #
        self.execute('''
                     UPDATE %s SET
                         f_tflags = %s
                     WHERE %s
                     '''
                     % (obj.utable,
                        self.plch,
                        ' AND '.join(conditions)),
                     [uuid] + values)
        #
        # t_flags is used in foreign keys ON UPDATE CASCADE, so all
        # related records will be marked, now just copy the marked data
        #
        for table in self.spec:
            #
            # create the snapshot table
            #
            self.execute('''
                         CREATE TABLE IF NOT EXISTS %s_%s
                         AS SELECT * FROM %s
                         WHERE
                             f_tflags IS NULL
                         '''
                         % (table, objid, table))
            #
            # copy the data -- is it possible to do it in one step?
            #
            self.execute('''
                         INSERT INTO %s_%s
                         SELECT * FROM %s
                         WHERE
                             f_tflags = %s
                         '''
                         % (table, objid, table, self.plch),
                         [uuid])

            if table.startswith('ifinfo_'):
                self.create_ifinfo_view(table, objid)
        #
        # unmark all the data
        #
        self.execute('''
                     UPDATE %s SET
                         f_tflags = %s
                     WHERE %s
                     '''
                     % (obj.utable,
                        self.plch,
                        ' AND '.join(conditions)),
                     [tflags] + values)
        for table in self.spec:
            self.execute('''
                         UPDATE %s_%s SET f_tflags = %s
                         ''' % (table, objid, self.plch),
                         [tflags])
            self.snapshots['%s_%s' % (table, objid)] = wref
Beispiel #11
0
    def save_deps(self, ctxid, weak_ref, iclass):
        uuid = uuid32()
        obj = weak_ref()
        obj_k = obj.key
        idx = self.indices[obj.table]
        conditions = []
        values = []
        for key in idx:
            conditions.append('f_%s = %s' % (key, self.plch))
            if key in obj_k:
                values.append(obj_k[key])
            else:
                values.append(obj.get(iclass.nla2name(key)))
        #
        # save the old f_tflags value
        #
        tflags = (self
                  .execute('''
                           SELECT f_tflags FROM %s
                           WHERE %s
                           '''
                           % (obj.table,
                              ' AND '.join(conditions)),
                           values)
                  .fetchone()[0])
        #
        # mark tflags for obj
        #
        obj.mark_tflags(uuid)

        #
        # f_tflags is used in foreign keys ON UPDATE CASCADE, so all
        # related records will be marked
        #
        for table in self.spec:
            self.log.debug('create snapshot %s_%s' % (table, ctxid))
            #
            # create the snapshot table
            #
            self.execute('''
                         CREATE TABLE IF NOT EXISTS %s_%s
                         AS SELECT * FROM %s
                         WHERE
                             f_tflags IS NULL
                         '''
                         % (table, ctxid, table))
            #
            # copy the data -- is it possible to do it in one step?
            #
            self.execute('''
                         INSERT INTO %s_%s
                         SELECT * FROM %s
                         WHERE
                             f_tflags = %s
                         '''
                         % (table, ctxid, table, self.plch),
                         [uuid])
        #
        # unmark all the data
        #
        obj.mark_tflags(tflags)

        for table in self.spec:
            self.execute('''
                         UPDATE %s_%s SET f_tflags = %s
                         ''' % (table, ctxid, self.plch),
                         [tflags])
            self.snapshots['%s_%s' % (table, ctxid)] = weak_ref
Beispiel #12
0
    def __init__(self, debug=False, timeout=3, do_connect=False,
                 host=None, key=None, cert=None, ca=None,
                 addr=None, fork=False, secret=None):
        addr = addr or uuid32()
        self._timeout = timeout
        self.default_broker = addr
        self.default_dport = 0
        self.uids = set()
        self.listeners = {}     # {nonce: Queue(), ...}
        self.callbacks = []     # [(predicate, callback, args), ...]
        self.debug = debug
        self.cid = None
        self.cmd_nonce = AddrPool(minaddr=0xf, maxaddr=0xfffe)
        self.nonce = AddrPool(minaddr=0xffff, maxaddr=0xffffffff)
        self.emarshal = MarshalEnv()
        self.save = None
        if self.marshal is not None:
            self.marshal.debug = debug
            self.marshal = self.marshal()
        self.buffers = Queue.Queue()
        self._mirror = False
        self.host = host

        self.ioloop = IOLoop()

        self._brs, self.bridge = pairPipeSockets()
        # To fork or not to fork?
        #
        # It depends on how you gonna use RT netlink sockets
        # in your application. Performance can also differ,
        # and sometimes forked broker can even speedup your
        # application -- keep in mind Python's GIL
        if fork:
            # Start the I/O broker in a separate process,
            # so you can use multiple RT netlink sockets in
            # one application -- it does matter, if your
            # application already uses some RT netlink
            # library and you want to smoothly try and
            # migrate to the pyroute2
            self.forked_broker = Process(target=self._start_broker,
                                         args=(fork, secret))
            self.forked_broker.start()
        else:
            # Start I/O broker as an embedded object, so
            # the RT netlink socket will be opened in the
            # same process. Technically, you can open
            # multiple RT netlink sockets within one process,
            # but only the first one will receive all the
            # answers -- so effectively only one socket per
            # process can be used.
            self.forked_broker = None
            self._start_broker(fork, secret)
        self.ioloop.start()
        self.ioloop.register(self.bridge,
                             self._route,
                             defer=True)
        if do_connect:
            path = urlparse.urlparse(host).path
            (self.default_link,
             self.default_peer) = self.connect(self.host,
                                               key, cert, ca)
            self.default_dport = self.discover(self.default_target or path,
                                               self.default_peer)
Beispiel #13
0
    def __init__(self,
                 debug=False,
                 timeout=3,
                 do_connect=False,
                 host=None,
                 key=None,
                 cert=None,
                 ca=None,
                 addr=None,
                 fork=False,
                 secret=None):
        addr = addr or uuid32()
        self._timeout = timeout
        self.default_broker = addr
        self.default_dport = 0
        self.uids = set()
        self.listeners = {}  # {nonce: Queue(), ...}
        self.callbacks = []  # [(predicate, callback, args), ...]
        self.debug = debug
        self.cid = None
        self.cmd_nonce = AddrPool(minaddr=0xf, maxaddr=0xfffe)
        self.nonce = AddrPool(minaddr=0xffff, maxaddr=0xffffffff)
        self.emarshal = MarshalEnv()
        self.save = None
        if self.marshal is not None:
            self.marshal.debug = debug
            self.marshal = self.marshal()
        self.buffers = Queue.Queue()
        self._mirror = False
        self.host = host

        self.ioloop = IOLoop()

        self._brs, self.bridge = pairPipeSockets()
        # To fork or not to fork?
        #
        # It depends on how you gonna use RT netlink sockets
        # in your application. Performance can also differ,
        # and sometimes forked broker can even speedup your
        # application -- keep in mind Python's GIL
        if fork:
            # Start the I/O broker in a separate process,
            # so you can use multiple RT netlink sockets in
            # one application -- it does matter, if your
            # application already uses some RT netlink
            # library and you want to smoothly try and
            # migrate to the pyroute2
            self.forked_broker = Process(target=self._start_broker,
                                         args=(fork, secret))
            self.forked_broker.start()
        else:
            # Start I/O broker as an embedded object, so
            # the RT netlink socket will be opened in the
            # same process. Technically, you can open
            # multiple RT netlink sockets within one process,
            # but only the first one will receive all the
            # answers -- so effectively only one socket per
            # process can be used.
            self.forked_broker = None
            self._start_broker(fork, secret)
        self.ioloop.start()
        self.ioloop.register(self.bridge, self._route, defer=True)
        if do_connect:
            path = urlparse.urlparse(host).path
            (self.default_link,
             self.default_peer) = self.connect(self.host, key, cert, ca)
            self.default_dport = self.discover(self.default_target or path,
                                               self.default_peer)