TT#37401 Use Unix sockets to avoid relying on hostnames for localhost/loopback

If the file /etc/hosts gets handled by templates, as ongoing changes
attempt to do, there's a problem because /etc/hosts gets truncated to
create a new file when it's needed to generate itself, to resolve the
"localhost" string as hostname, so the generation fails and /etc/hosts
gets empty at that point, affecting the system until restored.

The simplest way to break that cycle is to switch to Unix sockets.

Change-Id: I1e33ead6a134625346b9cf1beb09a7bdbfdfc8d2
changes/90/21590/4
Guillem Jover 7 years ago
parent d57184ba6e
commit 50ecc15441

@ -4,7 +4,7 @@ use warnings;
use English;
use Carp;
use POSIX qw( setsid );
use IO::Socket;
use IO::Socket::UNIX;
use Hash::Merge qw(merge);
use Template;
use YAML::XS qw(LoadFile);
@ -15,11 +15,11 @@ my $quiet = 0;
GetOptions("q|quiet" => \$quiet);
my $server_port = get_server_port();
my $server_socket = get_server_socket();
daemonize();
handle_connections( $server_port, $quiet );
handle_connections( $server_socket, $quiet );
exit;
@ -35,25 +35,19 @@ sub daemonize {
return;
}
sub get_server_port {
my $server = IO::Socket::INET->new(
'Proto' => 'tcp',
'LocalAddr' => 'localhost',
sub get_server_socket {
my $NGCP_SOCKETFILE = $ENV{'NGCP_SOCKETFILE'} //= '/var/run/ngcpcfg.socket';
my $server = IO::Socket::UNIX->new(
'Type' => SOCK_STREAM(),
'Local' => $NGCP_SOCKETFILE,
'Listen' => SOMAXCONN,
'Reuse' => 1,
);
die "Error: can't setup tt2-daemon!\n$EVAL_ERROR\n$ERRNO\n" unless $server;
binmode $server => ":encoding(utf8)";
my $NGCP_PORTFILE = $ENV{'NGCP_PORTFILE'} //= '/var/run/ngcpcfg.port';
if (open (my $portfile, '>', "$NGCP_PORTFILE")) {
print $portfile $server->sockport();
close ($portfile);
return $server;
} else {
die "Can't write to $NGCP_PORTFILE\n";
}
return $server;
}
sub handle_connections {

@ -1,19 +1,12 @@
#!/bin/bash
NGCP_PORTFILE="${NGCP_PORTFILE:-/var/run/ngcpcfg.port}"
NGCP_SOCKETFILE="${NGCP_SOCKETFILE:-/var/run/ngcpcfg.socket}"
if [ -r "${NGCP_PORTFILE}" ] ; then
port=$(cat "${NGCP_PORTFILE}")
else
echo "ERROR: Couldn't read file ${NGCP_PORTFILE}" >&2
if [ ! -e "$NGCP_SOCKETFILE" ] ; then
echo "ERROR: Wrong ngcpcfg tt2-daemon socket file: $NGCP_SOCKETFILE" >&2
exit 1
fi
if ! [[ $port =~ [0-9]+ ]] ; then
echo "ERROR: Wrong ngcpcfg tt2-daemon port: $port" >&2
exit 1
fi
echo "$@" | netcat localhost "$port"
echo "$@" | netcat -U "$NGCP_SOCKETFILE"
exit $?

@ -41,13 +41,13 @@ fi
# Kill all previous started tt2-daemon Perl processes if they were not stopped properly
killall tt2-daemon 2>/dev/null || true
if [ -n "${NGCP_PORTFILE:-}" ] ; then
log_debug "Using $NGCP_PORTFILE as tt2-daemon port file as set via 'NGCP_PORTFILE'."
if [ -n "${NGCP_SOCKETFILE:-}" ] ; then
log_debug "Using $NGCP_SOCKETFILE as tt2-daemon socket file as set via 'NGCP_SOCKETFILE'."
else
NGCP_PORTFILE='/var/run/ngcpcfg.port'
NGCP_SOCKETFILE='/var/run/ngcpcfg.socket'
fi
rm -f "${NGCP_PORTFILE}"
rm -f "${NGCP_SOCKETFILE}"
# Start new tt2-daemon Perl process
"${HELPER}"/tt2-daemon
@ -151,7 +151,7 @@ fi
# Kill all previous started tt2-daemon Perl processes
killall tt2-daemon 2>/dev/null || true
rm -f "${NGCP_PORTFILE}"
rm -f "${NGCP_SOCKETFILE}"
exit "$RC"

@ -43,12 +43,12 @@ TT_WRAPPER="${HELPER}/tt2-wrapper"
# Kill all previous started tt2-daemon Perl processes if they were not stopped properly
killall tt2-daemon 2>/dev/null || true
if [ -n "${NGCP_PORTFILE:-}" ] ; then
log_debug "Using $NGCP_PORTFILE as tt2-daemon port file as set via 'NGCP_PORTFILE'."
if [ -n "${NGCP_SOCKETFILE:-}" ] ; then
log_debug "Using $NGCP_SOCKETFILE as tt2-daemon socket file as set via 'NGCP_SOCKETFILE'."
else
NGCP_PORTFILE='/var/run/ngcpcfg.port'
NGCP_SOCKETFILE='/var/run/ngcpcfg.socket'
fi
rm -f "${NGCP_PORTFILE}"
rm -f "${NGCP_SOCKETFILE}"
# Start new tt2-daemon Perl process
"${HELPER}"/tt2-daemon --quiet
@ -77,7 +77,7 @@ fi
# Kill all previous started tt2-daemon Perl processes
killall tt2-daemon 2>/dev/null || true
rm -f "${NGCP_PORTFILE}"
rm -f "${NGCP_SOCKETFILE}"
exit "$RC"

@ -17,7 +17,7 @@ The following command line provides an example invocation:
[source,bash]
cd t # we're assuming in the following command line that you're inside this testing folder
HELPER=../helper CONFIG_POOL=/etc/ NGCPCFG=./fixtures/ngcpcfg.cfg SCRIPTS=../scripts/ FUNCTIONS=../functions/ \
NGCP_BASE_TT2=/tmp/pytest-of-root/pytest-XX/test_YYY/ NGCP_PORTFILE=/tmp/ngcpcfg.port OUTPUT_DIRECTORY=/tmp/ \
NGCP_BASE_TT2=/tmp/pytest-of-root/pytest-XX/test_YYY/ NGCP_SOCKETFILE=/tmp/ngcpcfg.socket OUTPUT_DIRECTORY=/tmp/ \
TEMPLATE_POOL_BASE=/tmp/pytest-of-root/pytest-XX/test_YYY ../sbin/ngcpcfg [...]
Test runs

@ -16,7 +16,7 @@ def ngcpcfgcli(tmpdir, *args):
'NGCPCFG': 'fixtures/ngcpcfg.cfg',
'SCRIPTS': '../scripts/',
'HELPER': '../helper/',
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
}
testenv.update(env)

@ -29,7 +29,7 @@ def test_simple_build_template_ok(ngcpcfgcli):
out = ngcpcfgcli("build", "--ignore-branch-check",
"/etc/apt/apt.conf.d/71_no_recommended",
env={
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': tmpdir,
})
regex = re.compile(r"Generating " +
@ -45,7 +45,7 @@ def test_fail_on_existing_dir_matching_output_filename(ngcpcfgcli, tmpdir):
os.makedirs(tmpdir + output)
out = ngcpcfgcli("build", "--ignore-branch-check", output,
env={
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': tmpdir,
})
regex = re.compile("Error: Generating file " +

@ -14,7 +14,7 @@ def test_all_ips(ngcpcfgcli, tmpdir):
"/etc/kamailio/lb/db/dispatcher",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': tmpdir,
'NGCPCFG': 'fixtures/ngcpcfg_pro.cfg',
})
@ -36,7 +36,7 @@ def test_all_ips_carrier(ngcpcfgcli, tmpdir):
"/etc/kamailio/lb/db/dispatcher",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': tmpdir,
'NGCPCFG': 'fixtures/ngcpcfg_carrier.cfg',
})

@ -14,7 +14,7 @@ def test_status_carrier(ngcpcfgcli, tmpdir):
"/etc/status.cfg",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': tmpdir,
'NGCPCFG': 'fixtures/ngcpcfg_carrier.cfg',
})

@ -13,7 +13,7 @@ import tempfile
def test_patch_action_no_args(ngcpcfgcli, tmpdir):
out = ngcpcfgcli("patch",
env={
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
})
string = r"No patchtt files found, nothing to patch."
assert string in out.stdout
@ -45,7 +45,7 @@ APT::Install-Recommends "0";
"--help",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -82,7 +82,7 @@ APT::Install-Recommends "0";
"/etc/apt/apt.conf.d/",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -127,7 +127,7 @@ APT::Install-Recommends "0";
"/etc/apt/apt.conf.d/",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -164,7 +164,7 @@ def test_patch_action_template_missing_for_patchtt(ngcpcfgcli, tmpdir):
"/etc/apt/apt.conf.d/",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -216,7 +216,7 @@ APT::Install-Recommends "0";
"/etc/apt/apt.conf.d/71_no_recommended.patchtt.tt2",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -281,7 +281,7 @@ APT::Install-Recommends "0";
"71_no_recommended.patchtt.tt2",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -323,7 +323,7 @@ APT::Install-Recommends "0";
"/etc/missing_patchtt_file.patchtt.tt2",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -406,7 +406,7 @@ dome dummy customtt message
"/etc/apt/apt.conf.d/",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir) + "/output",
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -523,7 +523,7 @@ dome dummy customtt message
out = ngcpcfgcli("build", "--ignore-branch-check",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir) + "/output",
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -604,7 +604,7 @@ APT::Install-Recommends "1";
"/etc/apt/apt.conf.d/",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir) + "/output",
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -653,7 +653,7 @@ APT::Install-Recommends "0";
"/etc/apt/apt.conf.d/",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir) + "/output",
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -704,7 +704,7 @@ APT::Install-Recommends "2";
out = ngcpcfgcli("patch", "--from-customtt",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir) + "/output",
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -743,7 +743,7 @@ def test_patch_action_from_customtt_missing_file_argument(ngcpcfgcli, tmpdir):
"missing.customtt.tt2",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -786,7 +786,7 @@ APT::Install-Recommends "2";
"71_no_recommended.customtt.tt2",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',
@ -831,7 +831,7 @@ the content here doesn't matter as no tt2 file available
"--from-customtt",
env={
'NGCP_BASE_TT2': os.getcwd(),
'NGCP_PORTFILE': '/tmp/ngcpcfg.port',
'NGCP_SOCKETFILE': '/tmp/ngcpcfg.socket',
'OUTPUT_DIRECTORY': str(tmpdir),
'TEMPLATE_POOL_BASE': str(tmpdir),
'CONFIG_POOL': '/etc',

Loading…
Cancel
Save