Fix ifup failures on member interfaces with IPv6

When an older version of ifup is used, there are cases where bringing
up an IPv6 address on an interface will fail with "RTNETLINK answers:
File exists"
This patch corrects this issue by bringing the interface up and
flushing the existing addresses prior to the ifup.
This returns a previous behavior of the ifdown/ifup commands.

Change-Id: I0dbb145ab9a0bb8f831c1db28cabd262f9394e7e
Story: 2005320
Task: 30248
This commit is contained in:
Michael Johnson 2019-03-28 11:33:14 -07:00
parent ab413f971e
commit 23a411413f
3 changed files with 31 additions and 12 deletions

View File

@ -202,10 +202,25 @@ class BaseOS(object):
def _bring_if_up(cls, interface, what): def _bring_if_up(cls, interface, what):
# Note, we are not using pyroute2 for this as it is not /etc/netns # Note, we are not using pyroute2 for this as it is not /etc/netns
# aware. # aware.
cmd = ("ip netns exec {ns} ifup {params}".format( # Work around for bug:
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=845121
int_up = "ip netns exec {ns} ip link set {int} up".format(
ns=consts.AMPHORA_NAMESPACE, int=interface)
addr_flush = "ip netns exec {ns} ip addr flush {int}".format(
ns=consts.AMPHORA_NAMESPACE, int=interface)
cmd = ("ip netns exec {ns} ifup -v {params}".format(
ns=consts.AMPHORA_NAMESPACE, params=interface)) ns=consts.AMPHORA_NAMESPACE, params=interface))
try: try:
subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT) out = subprocess.check_output(int_up.split(),
stderr=subprocess.STDOUT)
LOG.debug(out)
out = subprocess.check_output(addr_flush.split(),
stderr=subprocess.STDOUT)
LOG.debug(out)
out = subprocess.check_output(cmd.split(),
stderr=subprocess.STDOUT)
LOG.debug(out)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
LOG.error('Failed to ifup %s due to error: %s %s', interface, e, LOG.error('Failed to ifup %s due to error: %s %s', interface, e,
e.output) e.output)

View File

@ -1185,7 +1185,7 @@ class TestServerTestCase(base.TestCase):
'PERSISTENT_DHCLIENT="1"\n'.format(int=test_int_num)) 'PERSISTENT_DHCLIENT="1"\n'.format(int=test_int_num))
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', 'eth' + test_int_num], stderr=-2) 'ifup', '-v', 'eth' + test_int_num], stderr=-2)
# fixed IPs happy path # fixed IPs happy path
port_info = {'mac_address': '123', 'mtu': 1450, 'fixed_ips': [ port_info = {'mac_address': '123', 'mtu': 1450, 'fixed_ips': [
@ -1263,7 +1263,7 @@ class TestServerTestCase(base.TestCase):
'NETMASK="255.255.255.0"\n'.format(int=test_int_num)) 'NETMASK="255.255.255.0"\n'.format(int=test_int_num))
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', 'eth' + test_int_num], stderr=-2) 'ifup', '-v', 'eth' + test_int_num], stderr=-2)
# fixed IPs happy path IPv6 # fixed IPs happy path IPv6
port_info = {'mac_address': '123', 'mtu': 1450, 'fixed_ips': [ port_info = {'mac_address': '123', 'mtu': 1450, 'fixed_ips': [
@ -1337,7 +1337,7 @@ class TestServerTestCase(base.TestCase):
'0000:0002"\n'.format(int=test_int_num)) '0000:0002"\n'.format(int=test_int_num))
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', 'eth' + test_int_num], stderr=-2) 'ifup', '-v', 'eth' + test_int_num], stderr=-2)
# fixed IPs, bogus IP # fixed IPs, bogus IP
port_info = {'mac_address': '123', 'fixed_ips': [ port_info = {'mac_address': '123', 'fixed_ips': [
@ -1539,7 +1539,7 @@ class TestServerTestCase(base.TestCase):
mock_os_chmod.assert_has_calls(calls) mock_os_chmod.assert_has_calls(calls)
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', consts.NETNS_PRIMARY_INTERFACE], stderr=-2) 'ifup', '-v', consts.NETNS_PRIMARY_INTERFACE], stderr=-2)
def test_ubuntu_plug_VIP4(self): def test_ubuntu_plug_VIP4(self):
self._test_plug_VIP4(consts.UBUNTU) self._test_plug_VIP4(consts.UBUNTU)
@ -1800,7 +1800,7 @@ class TestServerTestCase(base.TestCase):
mock_os_chmod.assert_has_calls(calls) mock_os_chmod.assert_has_calls(calls)
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', '{netns_int}:0'.format( 'ifup', '-v', '{netns_int}:0'.format(
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2) netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
# Verify sysctl was loaded # Verify sysctl was loaded
@ -1903,7 +1903,7 @@ class TestServerTestCase(base.TestCase):
netns_int=consts.NETNS_PRIMARY_INTERFACE)) netns_int=consts.NETNS_PRIMARY_INTERFACE))
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', '{netns_int}:0'.format( 'ifup', '-v', '{netns_int}:0'.format(
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2) netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
mock_interfaces.side_effect = [['blah']] mock_interfaces.side_effect = [['blah']]
@ -2167,12 +2167,12 @@ class TestServerTestCase(base.TestCase):
if distro == consts.UBUNTU: if distro == consts.UBUNTU:
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', '{netns_int}:0'.format( 'ifup', '-v', '{netns_int}:0'.format(
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2) netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
elif distro == consts.CENTOS: elif distro == consts.CENTOS:
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', '{netns_int}'.format( 'ifup', '-v', '{netns_int}'.format(
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2) netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
# Verify sysctl was loaded # Verify sysctl was loaded
@ -2277,12 +2277,12 @@ class TestServerTestCase(base.TestCase):
if distro == consts.UBUNTU: if distro == consts.UBUNTU:
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', '{netns_int}:0'.format( 'ifup', '-v', '{netns_int}:0'.format(
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2) netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
elif distro == consts.CENTOS: elif distro == consts.CENTOS:
mock_check_output.assert_called_with( mock_check_output.assert_called_with(
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE, ['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
'ifup', '{netns_int}'.format( 'ifup', '-v', '{netns_int}'.format(
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2) netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
mock_interfaces.side_effect = [['blah']] mock_interfaces.side_effect = [['blah']]

View File

@ -0,0 +1,4 @@
---
fixes:
- |
Fixed an issue creating members on networks with IPv6 subnets.