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 grp
|
||||
import shutil
|
||||
import yaml
|
||||
|
||||
import charmhelpers.core.unitdata as unitdata
|
||||
|
||||
from charmhelpers.core.kernel import modprobe
|
||||
|
||||
from charmhelpers.core.hookenv import (
|
||||
Hooks,
|
||||
config,
|
||||
@ -250,6 +253,7 @@ def config_changed():
|
||||
send_remote_restart = True
|
||||
|
||||
sysctl_settings = config('sysctl')
|
||||
ensure_nf_conntrack_module_loaded(sysctl_settings)
|
||||
if sysctl_settings and not is_container():
|
||||
create_sysctl(
|
||||
sysctl_settings,
|
||||
@ -330,6 +334,29 @@ def config_changed():
|
||||
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():
|
||||
|
||||
CONFIGS.write_all()
|
||||
|
@ -453,6 +453,89 @@ class NovaComputeRelationsTests(CharmTestCase):
|
||||
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):
|
||||
hooks.amqp_joined()
|
||||
self.relation_set.assert_called_with(
|
||||
|
Loading…
Reference in New Issue
Block a user