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)
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()
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()
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
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
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
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
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
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)