summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Angel Ajo <majopela@redhat.com>2018-06-12 14:35:39 +0200
committerMiguel Angel Ajo <majopela@redhat.com>2018-06-12 16:05:48 +0200
commit7458575cfbc00a9bedf4d514a95e9b891639d5e8 (patch)
tree30a8c86b9c12890ffac5673d74d74733c6cecf4c
parent5106dfe5217b5274305ab565e23dbd1548c1f756 (diff)
Convert missing exception on device.link.delete()
Once we started using oslo.privsep the call to device.link.delete() should return RuntimeError when the device can't be handled by ip link for example, when it's an ovs internal device. Closes-Bug: #1776469 Change-Id: Ibf4b0bbb54aef38fc569036880668c745cb5c096
Notes
Notes (review): Code-Review+2: Jakub Libosvar <jlibosva-redhat@email.cz> Code-Review+2: Slawek Kaplonski <skaplons@redhat.com> Workflow+1: Slawek Kaplonski <skaplons@redhat.com> Code-Review+1: Nate Johnston <nate.johnston@redhat.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Tue, 12 Jun 2018 21:55:06 +0000 Reviewed-on: https://review.openstack.org/574712 Project: openstack/neutron Branch: refs/heads/master
-rw-r--r--neutron/privileged/agent/linux/ip_lib.py36
-rw-r--r--neutron/tests/unit/privileged/agent/linux/test_ip_lib.py11
2 files changed, 38 insertions, 9 deletions
diff --git a/neutron/privileged/agent/linux/ip_lib.py b/neutron/privileged/agent/linux/ip_lib.py
index 14157f2..ab7181b 100644
--- a/neutron/privileged/agent/linux/ip_lib.py
+++ b/neutron/privileged/agent/linux/ip_lib.py
@@ -62,6 +62,21 @@ class NetworkInterfaceNotFound(RuntimeError):
62 super(NetworkInterfaceNotFound, self).__init__(message) 62 super(NetworkInterfaceNotFound, self).__init__(message)
63 63
64 64
65class InterfaceOperationNotSupported(RuntimeError):
66 message = _("Operation not supported on interface %(device)s, namespace "
67 "%(namespace)s.")
68
69 def __init__(self, message=None, device=None, namespace=None):
70 # NOTE(slaweq): 'message' can be passed as an optional argument
71 # because of how privsep daemon works. If exception is raised in
72 # function called by privsep daemon, it will then try to reraise it
73 # and will call it always with passing only message from originally
74 # raised exception.
75 message = message or self.message % {
76 'device': device, 'namespace': namespace}
77 super(InterfaceOperationNotSupported, self).__init__(message)
78
79
65class IpAddressAlreadyExists(RuntimeError): 80class IpAddressAlreadyExists(RuntimeError):
66 message = _("IP address %(ip)s already configured on %(device)s.") 81 message = _("IP address %(ip)s already configured on %(device)s.")
67 82
@@ -116,6 +131,15 @@ def _get_iproute(namespace):
116 return pyroute2.IPRoute() 131 return pyroute2.IPRoute()
117 132
118 133
134def _translate_ip_device_exception(e, device=None, namespace=None):
135 if e.code == errno.ENODEV:
136 raise NetworkInterfaceNotFound(device=device, namespace=namespace)
137 if e.code == errno.EOPNOTSUPP:
138 raise InterfaceOperationNotSupported(device=device,
139 namespace=namespace)
140 raise
141
142
119def _get_link_id(device, namespace): 143def _get_link_id(device, namespace):
120 try: 144 try:
121 with _get_iproute(namespace) as ip: 145 with _get_iproute(namespace) as ip:
@@ -130,9 +154,7 @@ def _run_iproute_link(command, device, namespace=None, **kwargs):
130 idx = _get_link_id(device, namespace) 154 idx = _get_link_id(device, namespace)
131 return ip.link(command, index=idx, **kwargs) 155 return ip.link(command, index=idx, **kwargs)
132 except NetlinkError as e: 156 except NetlinkError as e:
133 if e.code == errno.ENODEV: 157 _translate_ip_device_exception(e, device, namespace)
134 raise NetworkInterfaceNotFound(device=device, namespace=namespace)
135 raise
136 except OSError as e: 158 except OSError as e:
137 if e.errno == errno.ENOENT: 159 if e.errno == errno.ENOENT:
138 raise NetworkNamespaceNotFound(netns_name=namespace) 160 raise NetworkNamespaceNotFound(netns_name=namespace)
@@ -145,9 +167,7 @@ def _run_iproute_neigh(command, device, namespace, **kwargs):
145 idx = _get_link_id(device, namespace) 167 idx = _get_link_id(device, namespace)
146 return ip.neigh(command, ifindex=idx, **kwargs) 168 return ip.neigh(command, ifindex=idx, **kwargs)
147 except NetlinkError as e: 169 except NetlinkError as e:
148 if e.code == errno.ENODEV: 170 _translate_ip_device_exception(e, device, namespace)
149 raise NetworkInterfaceNotFound(device=device, namespace=namespace)
150 raise
151 except OSError as e: 171 except OSError as e:
152 if e.errno == errno.ENOENT: 172 if e.errno == errno.ENOENT:
153 raise NetworkNamespaceNotFound(netns_name=namespace) 173 raise NetworkNamespaceNotFound(netns_name=namespace)
@@ -160,9 +180,7 @@ def _run_iproute_addr(command, device, namespace, **kwargs):
160 idx = _get_link_id(device, namespace) 180 idx = _get_link_id(device, namespace)
161 return ip.addr(command, index=idx, **kwargs) 181 return ip.addr(command, index=idx, **kwargs)
162 except NetlinkError as e: 182 except NetlinkError as e:
163 if e.code == errno.ENODEV: 183 _translate_ip_device_exception(e, device, namespace)
164 raise NetworkInterfaceNotFound(device=device, namespace=namespace)
165 raise
166 except OSError as e: 184 except OSError as e:
167 if e.errno == errno.ENOENT: 185 if e.errno == errno.ENOENT:
168 raise NetworkNamespaceNotFound(netns_name=namespace) 186 raise NetworkNamespaceNotFound(netns_name=namespace)
diff --git a/neutron/tests/unit/privileged/agent/linux/test_ip_lib.py b/neutron/tests/unit/privileged/agent/linux/test_ip_lib.py
index 6c85128..a4845dc 100644
--- a/neutron/tests/unit/privileged/agent/linux/test_ip_lib.py
+++ b/neutron/tests/unit/privileged/agent/linux/test_ip_lib.py
@@ -62,6 +62,17 @@ class IpLibTestCase(base.BaseTestCase):
62 priv_lib._run_iproute_link, 62 priv_lib._run_iproute_link,
63 "test_cmd", "eth0", None, test_param="test_value") 63 "test_cmd", "eth0", None, test_param="test_value")
64 64
65 def test_run_iproute_link_op_not_supported(self):
66 with mock.patch.object(pyroute2, "IPRoute") as iproute_mock:
67 ip_mock = iproute_mock()
68 ip_mock.__enter__().link_lookup.return_value = [2]
69 ip_mock.__enter__().link.side_effect = pyroute2.NetlinkError(
70 code=errno.EOPNOTSUPP)
71 self.assertRaises(
72 priv_lib.InterfaceOperationNotSupported,
73 priv_lib._run_iproute_link,
74 "test_cmd", "eth0", None, test_param="test_value")
75
65 def test_run_iproute_link_namespace_not_exists(self): 76 def test_run_iproute_link_namespace_not_exists(self):
66 with mock.patch.object(pyroute2, "IPRoute") as iproute_mock: 77 with mock.patch.object(pyroute2, "IPRoute") as iproute_mock:
67 iproute_mock.side_effect = OSError( 78 iproute_mock.side_effect = OSError(