Correct return values for bridge sysctl calls
This fixes an issue where the lb agent did not plug the
dhcp tap device into the bridge when having vlan networking
set up. Caused by setting of disable_ipv6 value.
Conflicts:
neutron/agent/linux/bridge_lib.py
neutron/tests/functional/agent/linux/test_bridge_lib.py
neutron/tests/unit/agent/linux/test_bridge_lib.py
Closes-Bug: #1520618
Change-Id: I0d21fad3a676d1fdd30501ea6a295f1e9b207a3a
Co-Authored-By: Brian Haley <brian.haley@hpe.com>
(cherry picked from commit cac2436f29
)
This commit is contained in:
parent
30b1d88e19
commit
1382da468f
|
@ -16,7 +16,12 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from neutron.agent.linux import ip_lib
|
||||
from neutron.i18n import _LE
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BridgeDevice(ip_lib.IPDevice):
|
||||
|
@ -26,9 +31,30 @@ class BridgeDevice(ip_lib.IPDevice):
|
|||
return ip_wrapper.netns.execute(cmd, run_as_root=True)
|
||||
|
||||
def _sysctl(self, cmd):
|
||||
"""execute() doesn't return the exit status of the command it runs,
|
||||
it returns stdout and stderr. Setting check_exit_code=True will cause
|
||||
it to raise a RuntimeError if the exit status of the command is
|
||||
non-zero, which in sysctl's case is an error. So we're normalizing
|
||||
that into zero (success) and one (failure) here to mimic what
|
||||
"echo $?" in a shell would be.
|
||||
|
||||
This is all because sysctl is too verbose and prints the value you
|
||||
just set on success, unlike most other utilities that print nothing.
|
||||
|
||||
execute() will have dumped a message to the logs with the actual
|
||||
output on failure, so it's not lost, and we don't need to print it
|
||||
here.
|
||||
"""
|
||||
cmd = ['sysctl', '-w'] + cmd
|
||||
ip_wrapper = ip_lib.IPWrapper(self.namespace)
|
||||
return ip_wrapper.netns.execute(cmd, run_as_root=True)
|
||||
try:
|
||||
ip_wrapper.netns.execute(cmd, run_as_root=True,
|
||||
check_exit_code=True)
|
||||
except RuntimeError:
|
||||
LOG.exception(_LE("Failed running %s"), cmd)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
@classmethod
|
||||
def addbr(cls, name, namespace=None):
|
||||
|
|
|
@ -36,6 +36,11 @@ class BridgeLibTest(base.BaseTestCase):
|
|||
self.execute.assert_called_once_with(cmd, run_as_root=True)
|
||||
self.execute.reset_mock()
|
||||
|
||||
def _verify_bridge_mock_check_exit_code(self, cmd):
|
||||
self.execute.assert_called_once_with(cmd, run_as_root=True,
|
||||
check_exit_code=True)
|
||||
self.execute.reset_mock()
|
||||
|
||||
def _test_br(self, namespace=None):
|
||||
br = bridge_lib.BridgeDevice.addbr(self._BR_NAME, namespace)
|
||||
self.assertEqual(namespace, br.namespace)
|
||||
|
@ -49,7 +54,7 @@ class BridgeLibTest(base.BaseTestCase):
|
|||
|
||||
br.disable_ipv6()
|
||||
cmd = 'net.ipv6.conf.%s.disable_ipv6=1' % self._BR_NAME
|
||||
self._verify_bridge_mock(['sysctl', '-w', cmd])
|
||||
self._verify_bridge_mock_check_exit_code(['sysctl', '-w', cmd])
|
||||
|
||||
br.addif(self._IF_NAME)
|
||||
self._verify_bridge_mock(
|
||||
|
|
Loading…
Reference in New Issue