Load nf_conntrack at boot time
Sysctl rules fined in charm config fails to be applied in ovn enviroments because the rules are applied before nf_conntrack is loaded. By adding nf_conntrack to the /etc/modules file it guarantees that it will be loaded before the rules are applied. Closes-Bug: #1922778 Change-Id: I51dae65cdc06e35230160bcaedda99710a72617d
This commit is contained in:
parent
31df8c6bf2
commit
389d2b7cb1
@ -24,9 +24,12 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import grp
|
import grp
|
||||||
import shutil
|
import shutil
|
||||||
|
import yaml
|
||||||
|
|
||||||
import charmhelpers.core.unitdata as unitdata
|
import charmhelpers.core.unitdata as unitdata
|
||||||
|
|
||||||
|
from charmhelpers.core.kernel import modprobe
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
Hooks,
|
Hooks,
|
||||||
config,
|
config,
|
||||||
@ -250,6 +253,7 @@ def config_changed():
|
|||||||
send_remote_restart = True
|
send_remote_restart = True
|
||||||
|
|
||||||
sysctl_settings = config('sysctl')
|
sysctl_settings = config('sysctl')
|
||||||
|
ensure_nf_conntrack_module_loaded(sysctl_settings)
|
||||||
if sysctl_settings and not is_container():
|
if sysctl_settings and not is_container():
|
||||||
create_sysctl(
|
create_sysctl(
|
||||||
sysctl_settings,
|
sysctl_settings,
|
||||||
@ -330,6 +334,29 @@ def config_changed():
|
|||||||
check_and_start_iscsid()
|
check_and_start_iscsid()
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_nf_conntrack_module_loaded(sysctl_str):
|
||||||
|
"""Loads and writes nf_conntrack to /etc/modules if present in sysctls."""
|
||||||
|
# abort if empty or container
|
||||||
|
if not sysctl_str or is_container():
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
sysctl_dict = yaml.safe_load(sysctl_str)
|
||||||
|
except yaml.YAMLError:
|
||||||
|
log("Error parsing YAML sysctl_dict: {}".format(sysctl_str),
|
||||||
|
level=ERROR)
|
||||||
|
return
|
||||||
|
|
||||||
|
if any("nf_conntrack" in key for key in sysctl_dict.keys()):
|
||||||
|
try:
|
||||||
|
# this call loads the module and writes an entry in /etc/modules
|
||||||
|
# for automatic loading at early boot
|
||||||
|
modprobe("nf_conntrack")
|
||||||
|
except Exception as e:
|
||||||
|
log("Failed to load or persist nf_conntrack"
|
||||||
|
" kernel module: {}".format(e), level=WARNING)
|
||||||
|
|
||||||
|
|
||||||
def update_all_configs():
|
def update_all_configs():
|
||||||
|
|
||||||
CONFIGS.write_all()
|
CONFIGS.write_all()
|
||||||
|
@ -453,6 +453,89 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
user='nova'
|
user='nova'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'is_container')
|
||||||
|
@patch('yaml.safe_load')
|
||||||
|
def test_ensure_nf_conntrack_module_loaded_empty(
|
||||||
|
self, safe_load, is_container):
|
||||||
|
is_container.return_value = False
|
||||||
|
hooks.ensure_nf_conntrack_module_loaded("")
|
||||||
|
safe_load.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(hooks, 'is_container')
|
||||||
|
@patch('yaml.safe_load')
|
||||||
|
def test_ensure_nf_conntrack_module_loaded_container(
|
||||||
|
self, safe_load, is_container):
|
||||||
|
is_container.return_value = True
|
||||||
|
hooks.ensure_nf_conntrack_module_loaded("foo")
|
||||||
|
safe_load.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(hooks, 'modprobe')
|
||||||
|
@patch.object(hooks, 'is_container')
|
||||||
|
@patch('yaml.safe_load')
|
||||||
|
def test_ensure_nf_conntrack_module_loaded_failed_yaml(
|
||||||
|
self, safe_load, is_container, modprobe):
|
||||||
|
is_container.return_value = False
|
||||||
|
hooks.ensure_nf_conntrack_module_loaded("foo")
|
||||||
|
safe_load.assert_called_once_with("foo")
|
||||||
|
modprobe.assert_not_called()
|
||||||
|
|
||||||
|
@patch.object(hooks, 'log')
|
||||||
|
@patch.object(hooks, 'modprobe')
|
||||||
|
@patch.object(hooks, 'is_container')
|
||||||
|
def test_ensure_nf_conntrack_module_loaded_failed_mobprobe(
|
||||||
|
self, is_container, modprobe, log):
|
||||||
|
is_container.return_value = False
|
||||||
|
modprobe.side_effect = Exception("FOO")
|
||||||
|
data = ("{ net.ipv4.neigh.default.gc_thresh1 : 128,"
|
||||||
|
"net.ipv4.neigh.default.gc_thresh2 : 28672,"
|
||||||
|
"net.ipv4.neigh.default.gc_thresh3 : 32768,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh1 : 128,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh2 : 28672,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh3 : 32768,"
|
||||||
|
"net.nf_conntrack_max : 1000000,"
|
||||||
|
"net.netfilter.nf_conntrack_buckets : 204800,"
|
||||||
|
"net.netfilter.nf_conntrack_max : 1000000 }")
|
||||||
|
hooks.ensure_nf_conntrack_module_loaded(data)
|
||||||
|
log.assert_called_once_with(
|
||||||
|
"Failed to load or persist nf_conntrack kernel module: FOO",
|
||||||
|
level="WARNING")
|
||||||
|
modprobe.assert_called_once_with("nf_conntrack")
|
||||||
|
|
||||||
|
@patch.object(hooks, 'log')
|
||||||
|
@patch.object(hooks, 'modprobe')
|
||||||
|
@patch.object(hooks, 'is_container')
|
||||||
|
def test_ensure_nf_conntrack_module_loaded(
|
||||||
|
self, is_container, modprobe, log):
|
||||||
|
is_container.return_value = False
|
||||||
|
data = ("{ net.ipv4.neigh.default.gc_thresh1 : 128,"
|
||||||
|
"net.ipv4.neigh.default.gc_thresh2 : 28672,"
|
||||||
|
"net.ipv4.neigh.default.gc_thresh3 : 32768,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh1 : 128,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh2 : 28672,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh3 : 32768,"
|
||||||
|
"net.nf_conntrack_max : 1000000,"
|
||||||
|
"net.netfilter.nf_conntrack_buckets : 204800,"
|
||||||
|
"net.netfilter.nf_conntrack_max : 1000000 }")
|
||||||
|
hooks.ensure_nf_conntrack_module_loaded(data)
|
||||||
|
log.assert_not_called()
|
||||||
|
modprobe.assert_called_once_with("nf_conntrack")
|
||||||
|
|
||||||
|
@patch.object(hooks, 'log')
|
||||||
|
@patch.object(hooks, 'modprobe')
|
||||||
|
@patch.object(hooks, 'is_container')
|
||||||
|
def test_ensure_nf_conntrack_module_loaded_no_sysctl(
|
||||||
|
self, is_container, modprobe, log):
|
||||||
|
is_container.return_value = False
|
||||||
|
data = ("{ net.ipv4.neigh.default.gc_thresh1 : 128,"
|
||||||
|
"net.ipv4.neigh.default.gc_thresh2 : 28672,"
|
||||||
|
"net.ipv4.neigh.default.gc_thresh3 : 32768,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh1 : 128,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh2 : 28672,"
|
||||||
|
"net.ipv6.neigh.default.gc_thresh3 : 32768 }")
|
||||||
|
hooks.ensure_nf_conntrack_module_loaded(data)
|
||||||
|
modprobe.assert_not_called()
|
||||||
|
log.assert_not_called()
|
||||||
|
|
||||||
def test_amqp_joined(self):
|
def test_amqp_joined(self):
|
||||||
hooks.amqp_joined()
|
hooks.amqp_joined()
|
||||||
self.relation_set.assert_called_with(
|
self.relation_set.assert_called_with(
|
||||||
|
Loading…
Reference in New Issue
Block a user