def __init__(self, netns, flags=os.O_CREAT): self.netns = netns self.flags = flags self.cmdch, cmdch = MpPipe() self.brdch, brdch = MpPipe() self.server = MpProcess(target=NetNServer, args=(self.netns, cmdch, brdch, self.flags)) self.server.start() super(NetNS, self).__init__() self.marshal = MarshalRtnl()
def __init__(self, *argv, **kwarg): self.cmdlock = threading.Lock() self.rcvch, rcvch = MpPipe() self.cmdch, cmdch = MpPipe() self.server = MpProcess(target=NetNServer, args=(self.netns, rcvch, cmdch, self.flags)) self.server.start() error = self.cmdch.recv() if error is not None: self.server.join() raise error else: atexit.register(self.close)
def __init__(self, netns, flags=os.O_CREAT): self.netns = netns self.flags = flags self.cmdch, self._cmdch = MpPipe() self.brdch, self._brdch = MpPipe() self.server = MpProcess(target=NetNServer, args=(self.netns, self._cmdch, self._brdch, self.flags)) self.server.start() super(NetNS, self).__init__() self.marshal = MarshalRtnl()
class NetNSProxy(object): netns = 'default' flags = os.O_CREAT def __init__(self, *argv, **kwarg): self.cmdlock = threading.Lock() self.rcvch, rcvch = MpPipe() self.cmdch, cmdch = MpPipe() self.server = MpProcess(target=NetNServer, args=(self.netns, rcvch, cmdch, self.flags)) self.server.start() error = self.cmdch.recv() if error is not None: self.server.join() raise error else: atexit.register(self.close) def recv(self, bufsize, flags=0): return self.rcvch.recv() def close(self): self.cmdch.send(None) self.server.join() def proxy(self, cmd, *argv, **kwarg): with self.cmdlock: self.cmdch.send((cmd, argv, kwarg)) response = self.cmdch.recv() if isinstance(response, Exception): raise response return response def fileno(self): return self.rcvch.fileno() def bind(self, *argv, **kwarg): if 'async' in kwarg: kwarg['async'] = False return self.proxy('bind', *argv, **kwarg) def send(self, *argv, **kwarg): return self.proxy('send', *argv, **kwarg) def sendto(self, *argv, **kwarg): return self.proxy('sendto', *argv, **kwarg) def getsockopt(self, *argv, **kwarg): return self.proxy('getsockopt', *argv, **kwarg) def setsockopt(self, *argv, **kwarg): return self.proxy('setsockopt', *argv, **kwarg)
class NetNS(IPRouteMixin, RemoteSocket): ''' NetNS is the IPRoute API with network namespace support. **Why not IPRoute?** The task to run netlink commands in some network namespace, being in another network namespace, requires the architecture, that differs too much from a simple Netlink socket. NetNS starts a proxy process in a network namespace and uses `multiprocessing` communication channels between the main and the proxy processes to route all `recv()` and `sendto()` requests/responses. **Any specific API calls?** Nope. `NetNS` supports all the same, that `IPRoute` does, in the same way. It provides full `socket`-compatible API and can be used in poll/select as well. The only difference is the `close()` call. In the case of `NetNS` it is **mandatory** to close the socket before exit. **NetNS and IPDB** It is possible to run IPDB with NetNS:: from pyroute2 import NetNS from pyroute2 import IPDB ip = IPDB(nl=NetNS('somenetns')) ... ip.release() Do not forget to call `release()` when the work is done. It will shut down `NetNS` instance as well. ''' def __init__(self, netns, flags=os.O_CREAT): self.netns = netns self.flags = flags self.cmdch, self._cmdch = MpPipe() self.brdch, self._brdch = MpPipe() atexit.register(self.close) self.server = MpProcess(target=NetNServer, args=(self.netns, self._cmdch, self._brdch, self.flags)) self.server.start() super(NetNS, self).__init__() self.marshal = MarshalRtnl() def close(self): try: super(NetNS, self).close() except: # something went wrong, force server shutdown self.cmdch.send({'stage': 'shutdown'}) logging.error('forced shutdown procedure, clean up netns manually') # force cleanup command channels self.cmdch.close() self.brdch.close() self._cmdch.close() self._brdch.close() # join the server self.server.join() def post_init(self): pass def remove(self): ''' Try to remove this network namespace from the system. ''' remove(self.netns)
class NetNS(IPRouteMixin, RemoteSocket): ''' NetNS is the IPRoute API with network namespace support. **Why not IPRoute?** The task to run netlink commands in some network namespace, being in another network namespace, requires the architecture, that differs too much from a simple Netlink socket. NetNS starts a proxy process in a network namespace and uses `multiprocessing` communication channels between the main and the proxy processes to route all `recv()` and `sendto()` requests/responses. **Any specific API calls?** Nope. `NetNS` supports all the same, that `IPRoute` does, in the same way. It provides full `socket`-compatible API and can be used in poll/select as well. The only difference is the `close()` call. In the case of `NetNS` it is **mandatory** to close the socket before exit. **NetNS and IPDB** It is possible to run IPDB with NetNS:: from pyroute2 import NetNS from pyroute2 import IPDB ip = IPDB(nl=NetNS('somenetns')) ... ip.release() Do not forget to call `release()` when the work is done. It will shut down `NetNS` instance as well. ''' def __init__(self, netns, flags=os.O_CREAT): self.netns = netns self.flags = flags self.cmdch, self._cmdch = MpPipe() self.brdch, self._brdch = MpPipe() self.server = MpProcess(target=NetNServer, args=(self.netns, self._cmdch, self._brdch, self.flags)) self.server.start() super(NetNS, self).__init__() self.marshal = MarshalRtnl() def close(self): super(NetNS, self).close() # force cleanup command channels self.cmdch.close() self.brdch.close() self._cmdch.close() self._brdch.close() # join the server self.server.join() def post_init(self): pass def remove(self): ''' Try to remove this network namespace from the system. ''' remove(self.netns)
class NetNS(IPRouteMixin, RemoteSocket): ''' NetNS is the IPRoute API with network namespace support. **Why not IPRoute?** The task to run netlink commands in some network namespace, being in another network namespace, requires the architecture, that differs too much from a simple Netlink socket. NetNS starts a proxy process in a network namespace and uses `multiprocessing` communication channels between the main and the proxy processes to route all `recv()` and `sendto()` requests/responses. **Any specific API calls?** Nope. `NetNS` supports all the same, that `IPRoute` does, in the same way. It provides full `socket`-compatible API and can be used in poll/select as well. The only difference is the `close()` call. In the case of `NetNS` it is **mandatory** to close the socket before exit. **NetNS and IPDB** It is possible to run IPDB with NetNS:: from pyroute2 import NetNS from pyroute2 import IPDB ip = IPDB(nl=NetNS('somenetns')) ... ip.release() Do not forget to call `release()` when the work is done. It will shut down `NetNS` instance as well. ''' def __init__(self, netns, flags=os.O_CREAT): self.netns = netns self.flags = flags self.cmdch, self._cmdch = MpPipe() self.brdch, self._brdch = MpPipe() atexit.register(self.close) self.server = MpProcess(target=NetNServer, args=(self.netns, self._cmdch, self._brdch, self.flags)) self.server.start() super(NetNS, self).__init__() self.marshal = MarshalRtnl() def clone(self): return type(self)(self.netns, self.flags) def close(self): try: super(NetNS, self).close() except: # something went wrong, force server shutdown self.cmdch.send({'stage': 'shutdown'}) log.error('forced shutdown procedure, clean up netns manually') # force cleanup command channels self.cmdch.close() self.brdch.close() self._cmdch.close() self._brdch.close() # join the server self.server.join() # Workaround for http://bugs.python.org/issue27151 if sys.version_info > (3, 2) and sys.version_info < (3, 6): try: fcntl.fcntl(self.server.sentinel, fcntl.F_GETFD) except: pass else: os.close(self.server.sentinel) def post_init(self): pass def remove(self): ''' Try to remove this network namespace from the system. ''' remove(self.netns)