Browse Source

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
tags/13.0.0.0b3
Miguel Angel Ajo 11 months ago
parent
commit
7458575cfb

+ 27
- 9
neutron/privileged/agent/linux/ip_lib.py View File

@@ -62,6 +62,21 @@ class NetworkInterfaceNotFound(RuntimeError):
62 62
         super(NetworkInterfaceNotFound, self).__init__(message)
63 63
 
64 64
 
65
+class 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
+
65 80
 class IpAddressAlreadyExists(RuntimeError):
66 81
     message = _("IP address %(ip)s already configured on %(device)s.")
67 82
 
@@ -116,6 +131,15 @@ def _get_iproute(namespace):
116 131
         return pyroute2.IPRoute()
117 132
 
118 133
 
134
+def _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
+
119 143
 def _get_link_id(device, namespace):
120 144
     try:
121 145
         with _get_iproute(namespace) as ip:
@@ -130,9 +154,7 @@ def _run_iproute_link(command, device, namespace=None, **kwargs):
130 154
             idx = _get_link_id(device, namespace)
131 155
             return ip.link(command, index=idx, **kwargs)
132 156
     except NetlinkError as e:
133
-        if e.code == errno.ENODEV:
134
-            raise NetworkInterfaceNotFound(device=device, namespace=namespace)
135
-        raise
157
+        _translate_ip_device_exception(e, device, namespace)
136 158
     except OSError as e:
137 159
         if e.errno == errno.ENOENT:
138 160
             raise NetworkNamespaceNotFound(netns_name=namespace)
@@ -145,9 +167,7 @@ def _run_iproute_neigh(command, device, namespace, **kwargs):
145 167
             idx = _get_link_id(device, namespace)
146 168
             return ip.neigh(command, ifindex=idx, **kwargs)
147 169
     except NetlinkError as e:
148
-        if e.code == errno.ENODEV:
149
-            raise NetworkInterfaceNotFound(device=device, namespace=namespace)
150
-        raise
170
+        _translate_ip_device_exception(e, device, namespace)
151 171
     except OSError as e:
152 172
         if e.errno == errno.ENOENT:
153 173
             raise NetworkNamespaceNotFound(netns_name=namespace)
@@ -160,9 +180,7 @@ def _run_iproute_addr(command, device, namespace, **kwargs):
160 180
             idx = _get_link_id(device, namespace)
161 181
             return ip.addr(command, index=idx, **kwargs)
162 182
     except NetlinkError as e:
163
-        if e.code == errno.ENODEV:
164
-            raise NetworkInterfaceNotFound(device=device, namespace=namespace)
165
-        raise
183
+        _translate_ip_device_exception(e, device, namespace)
166 184
     except OSError as e:
167 185
         if e.errno == errno.ENOENT:
168 186
             raise NetworkNamespaceNotFound(netns_name=namespace)

+ 11
- 0
neutron/tests/unit/privileged/agent/linux/test_ip_lib.py View File

@@ -62,6 +62,17 @@ class IpLibTestCase(base.BaseTestCase):
62 62
                 priv_lib._run_iproute_link,
63 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 76
     def test_run_iproute_link_namespace_not_exists(self):
66 77
         with mock.patch.object(pyroute2, "IPRoute") as iproute_mock:
67 78
             iproute_mock.side_effect = OSError(

Loading…
Cancel
Save