Load system sysctl in amphora network namespace
In the default amphora image, load system sysctl optimizations inside the amphora-haproxy network namespace when it's created. Change-Id: I00981460c18784f268ee048662dfe0e42d4f42f3 Co-Authored-By: Dustin Lundqiust <dustin@null-ptr.net>
This commit is contained in:
parent
3ef947ad3a
commit
838e52f245
@ -158,6 +158,14 @@ class Plug(object):
|
||||
netns = pyroute2.NetNS(consts.AMPHORA_NAMESPACE, flags=os.O_CREAT)
|
||||
netns.close()
|
||||
|
||||
# Load sysctl in new namespace
|
||||
sysctl = pyroute2.NSPopen(consts.AMPHORA_NAMESPACE,
|
||||
[consts.SYSCTL_CMD, '--system'],
|
||||
stdout=subprocess.PIPE)
|
||||
sysctl.communicate()
|
||||
sysctl.wait()
|
||||
sysctl.release()
|
||||
|
||||
with pyroute2.IPRoute() as ipr:
|
||||
# Move the interfaces into the namespace
|
||||
idx = ipr.link_lookup(ifname=default_netns_interface)[0]
|
||||
@ -355,4 +363,4 @@ class Plug(object):
|
||||
for attr in link['attrs']:
|
||||
if attr[0] == 'IFLA_ADDRESS' and attr[1] == mac_address:
|
||||
return True
|
||||
return False
|
||||
return False
|
||||
|
@ -52,6 +52,8 @@ haproxy_start()
|
||||
{
|
||||
# Re-add the namespace
|
||||
ip netns add {{ amphora_nsname }} || true
|
||||
# Load the system sysctl into the new namespace
|
||||
ip netns exec {{ amphora_nsname }} sysctl --system || true
|
||||
# We need the plugged_interfaces file sorted to join the host interfaces
|
||||
sort -k 1 /var/lib/octavia/plugged_interfaces > /var/lib/octavia/plugged_interfaces.sorted || true
|
||||
# Assign the interfaces into the namespace with the appropriate name
|
||||
|
@ -33,6 +33,8 @@ pre-start script
|
||||
[ -r $CONF_PATH ]
|
||||
# Re-add the namespace
|
||||
ip netns add {{ amphora_nsname }} || true
|
||||
# Load the system sysctl into the new namespace
|
||||
ip netns exec {{ amphora_nsname }} sysctl --system || true
|
||||
# We need the plugged_interfaces file sorted to join with the host
|
||||
# interfaces
|
||||
sort -k 1 /var/lib/octavia/plugged_interfaces > /var/lib/octavia/plugged_interfaces.sorted || true
|
||||
|
@ -330,6 +330,7 @@ FLOW_DOC_TITLES = {'AmphoraFlows': 'Amphora Flows',
|
||||
'L7RuleFlows': 'Layer 7 Rule Flows'}
|
||||
|
||||
NETNS_PRIMARY_INTERFACE = 'eth1'
|
||||
SYSCTL_CMD = '/sbin/sysctl'
|
||||
|
||||
AMP_ACTION_START = 'start'
|
||||
AMP_ACTION_STOP = 'stop'
|
||||
|
@ -807,6 +807,7 @@ class TestServerTestCase(base.TestCase):
|
||||
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
|
||||
'ifup', consts.NETNS_PRIMARY_INTERFACE], stderr=-2)
|
||||
|
||||
@mock.patch('pyroute2.NSPopen')
|
||||
@mock.patch('octavia.amphorae.backends.agent.api_server.'
|
||||
'plug.Plug._netns_interface_exists')
|
||||
@mock.patch('netifaces.interfaces')
|
||||
@ -819,7 +820,8 @@ class TestServerTestCase(base.TestCase):
|
||||
@mock.patch('os.makedirs')
|
||||
def test_plug_VIP4(self, mock_makedirs, mock_copytree, mock_check_output,
|
||||
mock_netns, mock_netns_create, mock_pyroute2,
|
||||
mock_ifaddress, mock_interfaces, mock_int_exists):
|
||||
mock_ifaddress, mock_interfaces, mock_int_exists,
|
||||
mock_nspopen):
|
||||
|
||||
subnet_info = {
|
||||
'subnet_cidr': '203.0.113.0/24',
|
||||
@ -937,6 +939,11 @@ class TestServerTestCase(base.TestCase):
|
||||
'ifup', '{netns_int}:0'.format(
|
||||
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
|
||||
|
||||
# Verify sysctl was loaded
|
||||
mock_nspopen.assert_called_once_with(
|
||||
'amphora-haproxy', ['/sbin/sysctl', '--system'],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
# One Interface down, Happy Path IPv4
|
||||
mock_interfaces.side_effect = [['blah']]
|
||||
mock_ifaddress.side_effect = [[netifaces.AF_LINK],
|
||||
@ -1003,6 +1010,7 @@ class TestServerTestCase(base.TestCase):
|
||||
'message': 'Error plugging VIP'},
|
||||
json.loads(rv.data.decode('utf-8')))
|
||||
|
||||
@mock.patch('pyroute2.NSPopen')
|
||||
@mock.patch('netifaces.interfaces')
|
||||
@mock.patch('netifaces.ifaddresses')
|
||||
@mock.patch('pyroute2.IPRoute')
|
||||
@ -1013,7 +1021,7 @@ class TestServerTestCase(base.TestCase):
|
||||
@mock.patch('os.makedirs')
|
||||
def test_plug_vip6(self, mock_makedirs, mock_copytree, mock_check_output,
|
||||
mock_netns, mock_netns_create, mock_pyroute2,
|
||||
mock_ifaddress, mock_interfaces):
|
||||
mock_ifaddress, mock_interfaces, mock_nspopen):
|
||||
|
||||
subnet_info = {
|
||||
'subnet_cidr': '2001:db8::/32',
|
||||
@ -1119,6 +1127,11 @@ class TestServerTestCase(base.TestCase):
|
||||
'ifup', '{netns_int}:0'.format(
|
||||
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
|
||||
|
||||
# Verify sysctl was loaded
|
||||
mock_nspopen.assert_called_once_with(
|
||||
'amphora-haproxy', ['/sbin/sysctl', '--system'],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
# One Interface down, Happy Path IPv6
|
||||
mock_interfaces.side_effect = [['blah']]
|
||||
mock_ifaddress.side_effect = [[netifaces.AF_LINK],
|
||||
|
@ -663,6 +663,7 @@ class ServerTestCase(base.TestCase):
|
||||
['ip', 'netns', 'exec', consts.AMPHORA_NAMESPACE,
|
||||
'ifup', consts.NETNS_PRIMARY_INTERFACE], stderr=-2)
|
||||
|
||||
@mock.patch('pyroute2.NSPopen')
|
||||
@mock.patch('netifaces.interfaces')
|
||||
@mock.patch('netifaces.ifaddresses')
|
||||
@mock.patch('pyroute2.IPRoute')
|
||||
@ -673,7 +674,7 @@ class ServerTestCase(base.TestCase):
|
||||
@mock.patch('os.makedirs')
|
||||
def test_plug_vip4(self, mock_makedirs, mock_copytree, mock_check_output,
|
||||
mock_netns, mock_netns_create, mock_pyroute2,
|
||||
mock_ifaddress, mock_interfaces):
|
||||
mock_ifaddress, mock_interfaces, mock_nspopen):
|
||||
|
||||
subnet_info = {
|
||||
'subnet_cidr': '203.0.113.0/24',
|
||||
@ -779,6 +780,11 @@ class ServerTestCase(base.TestCase):
|
||||
'ifup', '{netns_int}:0'.format(
|
||||
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
|
||||
|
||||
# Verify sysctl was loaded
|
||||
mock_nspopen.assert_called_once_with(
|
||||
'amphora-haproxy', ['/sbin/sysctl', '--system'],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
# One Interface down, Happy Path IPv4
|
||||
mock_interfaces.side_effect = [['blah']]
|
||||
mock_ifaddress.side_effect = [[netifaces.AF_LINK],
|
||||
@ -845,6 +851,7 @@ class ServerTestCase(base.TestCase):
|
||||
'message': 'Error plugging VIP'},
|
||||
json.loads(rv.data.decode('utf-8')))
|
||||
|
||||
@mock.patch('pyroute2.NSPopen')
|
||||
@mock.patch('netifaces.interfaces')
|
||||
@mock.patch('netifaces.ifaddresses')
|
||||
@mock.patch('pyroute2.IPRoute')
|
||||
@ -855,7 +862,7 @@ class ServerTestCase(base.TestCase):
|
||||
@mock.patch('os.makedirs')
|
||||
def test_plug_vip6(self, mock_makedirs, mock_copytree, mock_check_output,
|
||||
mock_netns, mock_netns_create, mock_pyroute2,
|
||||
mock_ifaddress, mock_interfaces):
|
||||
mock_ifaddress, mock_interfaces, mock_nspopen):
|
||||
|
||||
subnet_info = {
|
||||
'subnet_cidr': '2001:db8::/32',
|
||||
@ -959,6 +966,11 @@ class ServerTestCase(base.TestCase):
|
||||
'ifup', '{netns_int}:0'.format(
|
||||
netns_int=consts.NETNS_PRIMARY_INTERFACE)], stderr=-2)
|
||||
|
||||
# Verify sysctl was loaded
|
||||
mock_nspopen.assert_called_once_with(
|
||||
'amphora-haproxy', ['/sbin/sysctl', '--system'],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
# One Interface down, Happy Path IPv6
|
||||
mock_interfaces.side_effect = [['blah']]
|
||||
mock_ifaddress.side_effect = [[netifaces.AF_LINK],
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import mock
|
||||
import netifaces
|
||||
@ -51,6 +52,7 @@ class TestPlug(base.TestCase):
|
||||
interface = self.test_plug._interface_by_mac(FAKE_MAC_ADDRESS.upper())
|
||||
self.assertEqual(FAKE_INTERFACE, interface)
|
||||
|
||||
@mock.patch('pyroute2.NSPopen')
|
||||
@mock.patch.object(plug, "flask")
|
||||
@mock.patch('pyroute2.IPRoute')
|
||||
@mock.patch('pyroute2.netns.create')
|
||||
@ -60,7 +62,7 @@ class TestPlug(base.TestCase):
|
||||
@mock.patch('os.makedirs')
|
||||
def test_plug_vip_ipv4(self, mock_makedirs, mock_copytree,
|
||||
mock_check_output, mock_netns, mock_netns_create,
|
||||
mock_pyroute2, mock_flask):
|
||||
mock_pyroute2, mock_flask, mock_nspopen):
|
||||
m = mock.mock_open()
|
||||
with mock.patch('os.open'), mock.patch.object(os, 'fdopen', m):
|
||||
self.test_plug.plug_vip(
|
||||
@ -74,7 +76,11 @@ class TestPlug(base.TestCase):
|
||||
'details': 'VIP {vip} plugged on interface {interface}'.format(
|
||||
vip=FAKE_IP_IPV4, interface='eth1')
|
||||
})
|
||||
mock_nspopen.assert_called_once_with(
|
||||
'amphora-haproxy', ['/sbin/sysctl', '--system'],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
@mock.patch('pyroute2.NSPopen')
|
||||
@mock.patch.object(plug, "flask")
|
||||
@mock.patch('pyroute2.IPRoute')
|
||||
@mock.patch('pyroute2.netns.create')
|
||||
@ -84,7 +90,7 @@ class TestPlug(base.TestCase):
|
||||
@mock.patch('os.makedirs')
|
||||
def test_plug_vip_ipv6(self, mock_makedirs, mock_copytree,
|
||||
mock_check_output, mock_netns, mock_netns_create,
|
||||
mock_pyroute2, mock_flask):
|
||||
mock_pyroute2, mock_flask, mock_nspopen):
|
||||
m = mock.mock_open()
|
||||
with mock.patch('os.open'), mock.patch.object(os, 'fdopen', m):
|
||||
self.test_plug.plug_vip(
|
||||
@ -98,6 +104,9 @@ class TestPlug(base.TestCase):
|
||||
'details': 'VIP {vip} plugged on interface {interface}'.format(
|
||||
vip=FAKE_IP_IPV6_EXPANDED, interface='eth1')
|
||||
})
|
||||
mock_nspopen.assert_called_once_with(
|
||||
'amphora-haproxy', ['/sbin/sysctl', '--system'],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
@mock.patch.object(plug, "flask")
|
||||
@mock.patch('pyroute2.IPRoute')
|
||||
|
Loading…
Reference in New Issue
Block a user