Commit 089dbd85 authored by Martín Ferrari's avatar Martín Ferrari

Try to handle pre-existing interfaces. Add del_if

parent ba49ec6d
...@@ -5,8 +5,6 @@ import netns.iproute ...@@ -5,8 +5,6 @@ import netns.iproute
__all__ = ['NodeInterface', 'P2PInterface', 'ExternalInterface'] __all__ = ['NodeInterface', 'P2PInterface', 'ExternalInterface']
# FIXME: should nodes register interfaces?
class _Interface(object): class _Interface(object):
"""Just a base class for the *Interface classes: assign names and handle """Just a base class for the *Interface classes: assign names and handle
destruction.""" destruction."""
...@@ -167,6 +165,7 @@ class ExternalInterface(_Interface): ...@@ -167,6 +165,7 @@ class ExternalInterface(_Interface):
self._ctl_if = iface.index self._ctl_if = iface.index
self._original_state = iface self._original_state = iface
# FIXME: register somewhere for destruction!
def destroy(self): # override: restore as much as possible def destroy(self): # override: restore as much as possible
try: try:
netns.iproute.set_if(self._original_state) netns.iproute.set_if(self._original_state)
...@@ -177,6 +176,26 @@ class ExternalInterface(_Interface): ...@@ -177,6 +176,26 @@ class ExternalInterface(_Interface):
def control_index(self): def control_index(self):
return self._ctl_if return self._ctl_if
class ExternalNodeInterface(_NSInterface):
"""Class to handle already existing interfaces inside a name space, usually
just the loopback device, but it can be other user-created interfaces. On
destruction, the code will try to restore the interface to the state it was
in before being imported into netns."""
def __init__(self, node, iface):
iface = node._slave.get_if_data(iface)
self._original_state = iface
self._ns_if = iface.index
self._slave = node._slave
node._add_interface(self)
# FIXME: register somewhere for destruction!
def destroy(self): # override: restore as much as possible
try:
self._slave.set_if(self._original_state)
except:
pass
# don't look after this :-) # don't look after this :-)
# helpers # helpers
......
...@@ -54,12 +54,16 @@ class Node(object): ...@@ -54,12 +54,16 @@ class Node(object):
def Subprocess(self, *kargs, **kwargs): def Subprocess(self, *kargs, **kwargs):
return netns.subprocess_.Subprocess(self, *kargs, **kwargs) return netns.subprocess_.Subprocess(self, *kargs, **kwargs)
def Popen(self, *kargs, **kwargs): def Popen(self, *kargs, **kwargs):
return netns.subprocess_.Popen(self, *kargs, **kwargs) return netns.subprocess_.Popen(self, *kargs, **kwargs)
def system(self, *kargs, **kwargs): def system(self, *kargs, **kwargs):
return netns.subprocess_.system(self, *kargs, **kwargs) return netns.subprocess_.system(self, *kargs, **kwargs)
def backticks(self, *kargs, **kwargs): def backticks(self, *kargs, **kwargs):
return netns.subprocess_.backticks(self, *kargs, **kwargs) return netns.subprocess_.backticks(self, *kargs, **kwargs)
def backticks_raise(self, *kargs, **kwargs): def backticks_raise(self, *kargs, **kwargs):
return netns.subprocess_.backticks_raise(self, *kargs, **kwargs) return netns.subprocess_.backticks_raise(self, *kargs, **kwargs)
...@@ -72,11 +76,29 @@ class Node(object): ...@@ -72,11 +76,29 @@ class Node(object):
for k, v in kwargs.items(): for k, v in kwargs.items():
setattr(i, k, v) setattr(i, k, v)
return i return i
def get_interfaces(self):
# FIXME: loopback et al
s = sorted(self._interfaces.items(), key = lambda x: x[0])
return [x[1] for x in s]
def del_if(self, iface):
"""Doesn't destroy the interface if it wasn't created by us."""
del self._interfaces[iface.index]
iface.destroy()
def get_interfaces(self):
ifaces = self._slave.get_if_data()
ret = []
for i in ifaces:
if i not in self._interfaces:
ret.append(netns.interface.ExternalNodeInterface(self, i))
else:
ret.append(self._interfaces[i])
# by the way, clean up _interfaces
for i in self._interfaces:
if i not in ifaces:
sys.stderr.write("WARNING: interface #%d went away." % i)
del self._interfaces[i]
return sorted(ret, key = lambda x: x.index)
# FIXME: Routing
def add_route(self, prefix, prefix_len, nexthop = None, interface = None): def add_route(self, prefix, prefix_len, nexthop = None, interface = None):
assert nexthop or interface assert nexthop or interface
def add_default_route(self, nexthop, interface = None): def add_default_route(self, nexthop, interface = None):
......
...@@ -422,7 +422,6 @@ class Client(object): ...@@ -422,7 +422,6 @@ class Client(object):
e = yaml.load(text) e = yaml.load(text)
raise e raise e
if code / 100 != expected: if code / 100 != expected:
# FIXME: shuld try to save and re-create exceptions
raise RuntimeError("Error from slave: %d %s" % (code, text)) raise RuntimeError("Error from slave: %d %s" % (code, text))
return text return text
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment