Merge pull request #6328 from Icinga/sysconfig-env

Rework sysconfig file/startup environment
This commit is contained in:
Michael Friedrich 2018-06-05 13:27:36 +02:00 committed by GitHub
commit bf0737ded5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 96 additions and 134 deletions

View File

@ -15,6 +15,7 @@
# along with this program; if not, write to the Free Software Foundation # along with this program; if not, write to the Free Software Foundation
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
if(NOT WIN32) if(NOT WIN32)
configure_file(icinga2.sysconfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/initsystem/icinga2.sysconfig @ONLY) configure_file(icinga2.sysconfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/initsystem/icinga2.sysconfig @ONLY)
get_filename_component(ICINGA2_SYSCONFIGFILE_NAME ${ICINGA2_SYSCONFIGFILE} NAME) get_filename_component(ICINGA2_SYSCONFIGFILE_NAME ${ICINGA2_SYSCONFIGFILE} NAME)
@ -26,8 +27,10 @@ if(NOT WIN32)
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
) )
configure_file(prepare-dirs.cmake ${CMAKE_CURRENT_BINARY_DIR}/initsystem/prepare-dirs @ONLY)
configure_file(safe-reload.cmake ${CMAKE_CURRENT_BINARY_DIR}/initsystem/safe-reload @ONLY)
install( install(
FILES prepare-dirs safe-reload FILES ${CMAKE_CURRENT_BINARY_DIR}/initsystem/prepare-dirs ${CMAKE_CURRENT_BINARY_DIR}/initsystem/safe-reload
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/icinga2 DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/icinga2
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
) )
@ -37,7 +40,7 @@ if(NOT WIN32)
"Force install both the systemd service definition file and the SysV initscript in parallel, regardless of how USE_SYSTEMD is set. Only use this for special packaging purposes and if you know what you are doing" OFF) "Force install both the systemd service definition file and the SysV initscript in parallel, regardless of how USE_SYSTEMD is set. Only use this for special packaging purposes and if you know what you are doing" OFF)
if (NOT USE_SYSTEMD OR INSTALL_SYSTEMD_SERVICE_AND_INITSCRIPT) if (NOT USE_SYSTEMD OR INSTALL_SYSTEMD_SERVICE_AND_INITSCRIPT)
configure_file(icinga2.init.d.cmake ${CMAKE_CURRENT_BINARY_DIR}/initsystem/icinga2) configure_file(icinga2.init.d.cmake ${CMAKE_CURRENT_BINARY_DIR}/initsystem/icinga2 @ONLY)
install( install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/initsystem/icinga2 FILES ${CMAKE_CURRENT_BINARY_DIR}/initsystem/icinga2
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/init.d DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/init.d

View File

@ -20,8 +20,23 @@ SYSCONFIGFILE=@ICINGA2_SYSCONFIGFILE@
if [ -f $SYSCONFIGFILE ]; then if [ -f $SYSCONFIGFILE ]; then
. $SYSCONFIGFILE . $SYSCONFIGFILE
else else
echo "Can't load system specific defines from $SYSCONFIGFILE." echo "Couldn't load system specific defines from $SYSCONFIGFILE. Using defaults."
exit 6 fi
# Set defaults, to overwrite see "@ICINGA2_SYSCONFIGFILE@"
: ${ICINGA2_USER:="@ICINGA2_USER@"}
: ${ICINGA2_GROUP:="@ICINGA2_GROUP@"}
: ${ICINGA2_COMMAND_GROUP:="@ICINGA2_COMMAND_GROUP@"}
: ${DAEMON:="@CMAKE_INSTALL_FULL_SBINDIR@/icinga2"}
: ${ICINGA2_CONFIG_FILE:="@CMAKE_INSTALL_FULL_SYSCONFDIR@/icinga2/icinga2.conf"}
: ${ICINGA2_ERROR_LOG:=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/error.log}
: ${ICINGA2_STARTUP_LOG:=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/startup.log}
: ${ICINGA2_PID_FILE:="@ICINGA2_RUNDIR@/icinga2/icinga2.pid"}
# Load extra environment variables
if [ -f /etc/default/icinga2 ]; then
. /etc/default/icinga2
fi fi
test -x $DAEMON || exit 5 test -x $DAEMON || exit 5
@ -31,16 +46,6 @@ if [ ! -e $ICINGA2_CONFIG_FILE ]; then
exit 6 exit 6
fi fi
if [ ! $ICINGA2_USER ]; then
echo "Could not fetch \$ICINGA2_USER. Exiting."
exit 6
fi
if [ ! $ICINGA2_GROUP ]; then
echo "Could not fetch \$ICINGA2_GROUP. Exiting."
exit 6
fi
getent passwd $ICINGA2_USER >/dev/null 2>&1 || (echo "Icinga user '$ICINGA2_USER' does not exist. Exiting." && exit 6) getent passwd $ICINGA2_USER >/dev/null 2>&1 || (echo "Icinga user '$ICINGA2_USER' does not exist. Exiting." && exit 6)
getent group $ICINGA2_GROUP >/dev/null 2>&1 || (echo "Icinga group '$ICINGA2_GROUP' does not exist. Exiting." && exit 6) getent group $ICINGA2_GROUP >/dev/null 2>&1 || (echo "Icinga group '$ICINGA2_GROUP' does not exist. Exiting." && exit 6)
getent group $ICINGA2_COMMAND_GROUP >/dev/null 2>&1 || (echo "Icinga command group '$ICINGA2_COMMAND_GROUP' does not exist. Exiting." && exit 6) getent group $ICINGA2_COMMAND_GROUP >/dev/null 2>&1 || (echo "Icinga command group '$ICINGA2_COMMAND_GROUP' does not exist. Exiting." && exit 6)
@ -52,15 +57,10 @@ elif [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions . /etc/init.d/functions
fi fi
# Load extra environment variables
if [ -f /etc/default/icinga2 ]; then
. /etc/default/icinga2
fi
# Start Icinga 2 # Start Icinga 2
start() { start() {
printf "Starting Icinga 2: " printf "Starting Icinga 2: "
@CMAKE_INSTALL_PREFIX@/lib/icinga2/prepare-dirs $SYSCONFIGFILE @CMAKE_INSTALL_PREFIX@/lib/icinga2/prepare-dirs
if ! $DAEMON daemon -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG > $ICINGA2_STARTUP_LOG 2>&1; then if ! $DAEMON daemon -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG > $ICINGA2_STARTUP_LOG 2>&1; then
echo "Error starting Icinga. Check '$ICINGA2_STARTUP_LOG' for details." echo "Error starting Icinga. Check '$ICINGA2_STARTUP_LOG' for details."

View File

@ -1,13 +1,16 @@
DAEMON=@CMAKE_INSTALL_FULL_SBINDIR@/icinga2 #This is the default environment Icinga 2 runs with.
ICINGA2_CONFIG_FILE=@CMAKE_INSTALL_FULL_SYSCONFDIR@/icinga2/icinga2.conf #Make your changes here.
ICINGA2_RUN_DIR=@ICINGA2_RUNDIR@
ICINGA2_STATE_DIR=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@ #DAEMON=@CMAKE_INSTALL_FULL_SBINDIR@/icinga2
ICINGA2_PID_FILE=@ICINGA2_RUNDIR@/icinga2/icinga2.pid #ICINGA2_CONFIG_FILE=@CMAKE_INSTALL_FULL_SYSCONFDIR@/icinga2/icinga2.conf
ICINGA2_LOG_DIR=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2 #ICINGA2_RUN_DIR=@ICINGA2_RUNDIR@
ICINGA2_ERROR_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/error.log #ICINGA2_STATE_DIR=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@
ICINGA2_STARTUP_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/startup.log #ICINGA2_PID_FILE=@ICINGA2_RUNDIR@/icinga2/icinga2.pid
ICINGA2_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/icinga2.log #ICINGA2_LOG_DIR=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2
ICINGA2_CACHE_DIR=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/cache/icinga2 #ICINGA2_ERROR_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/error.log
ICINGA2_USER=@ICINGA2_USER@ #ICINGA2_STARTUP_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/startup.log
ICINGA2_GROUP=@ICINGA2_GROUP@ #ICINGA2_LOG=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2/icinga2.log
ICINGA2_COMMAND_GROUP=@ICINGA2_COMMAND_GROUP@ #ICINGA2_CACHE_DIR=@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/cache/icinga2
#ICINGA2_USER=@ICINGA2_USER@
#ICINGA2_GROUP=@ICINGA2_GROUP@
#ICINGA2_COMMAND_GROUP=@ICINGA2_COMMAND_GROUP@

View File

@ -3,25 +3,15 @@
# This script prepares directories and files needed for running Icinga2 # This script prepares directories and files needed for running Icinga2
# #
# load system specific defines # Set defaults, to overwrite see "@ICINGA2_SYSCONFIGFILE@"
SYSCONFIGFILE=$1
if [ -f "$SYSCONFIGFILE" ]; then
. $SYSCONFIGFILE
else
echo "Error: You need to supply the path to the Icinga2 sysconfig file as parameter."
exit 1
fi
: ${ICINGA2_USER:="@ICINGA2_USER@"}
if [ ! $ICINGA2_USER ]; then : ${ICINGA2_GROUP:="@ICINGA2_GROUP@"}
echo "Could not fetch \$ICINGA2_USER. Exiting." : ${ICINGA2_COMMAND_GROUP:="@ICINGA2_COMMAND_GROUP@"}
exit 6 : ${ICINGA2_RUN_DIR:="@ICINGA2_RUNDIR@"}
fi : ${ICINGA2_LOG_DIR:="@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/log/icinga2"}
: ${ICINGA2_STATE_DIR:="@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/cache/icinga2"}
if [ ! $ICINGA2_GROUP ]; then : ${ICINGA2_CACHE_DIR:="@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/cache/icinga2"}
echo "Could not fetch \$ICINGA2_GROUP. Exiting."
exit 6
fi
getent passwd $ICINGA2_USER >/dev/null 2>&1 || (echo "Icinga user '$ICINGA2_USER' does not exist. Exiting." && exit 6) getent passwd $ICINGA2_USER >/dev/null 2>&1 || (echo "Icinga user '$ICINGA2_USER' does not exist. Exiting." && exit 6)
getent group $ICINGA2_GROUP >/dev/null 2>&1 || (echo "Icinga group '$ICINGA2_GROUP' does not exist. Exiting." && exit 6) getent group $ICINGA2_GROUP >/dev/null 2>&1 || (echo "Icinga group '$ICINGA2_GROUP' does not exist. Exiting." && exit 6)
@ -35,20 +25,10 @@ if [ ! -e "$ICINGA2_RUN_DIR"/icinga2 ]; then
chown -R $ICINGA2_USER:$ICINGA2_COMMAND_GROUP "$ICINGA2_RUN_DIR"/icinga2 chown -R $ICINGA2_USER:$ICINGA2_COMMAND_GROUP "$ICINGA2_RUN_DIR"/icinga2
fi fi
# Could be undefined in installations where sysconf is not overridden on upgrade
if [ -z "$ICINGA2_LOG_DIR" ]; then
ICINGA2_LOG_DIR=$(dirname -- "$ICINGA2_LOG")
fi
test -e "$ICINGA2_LOG_DIR" || install -m 750 -o $ICINGA2_USER -g $ICINGA2_COMMAND_GROUP -d "$ICINGA2_LOG_DIR" test -e "$ICINGA2_LOG_DIR" || install -m 750 -o $ICINGA2_USER -g $ICINGA2_COMMAND_GROUP -d "$ICINGA2_LOG_DIR"
if type restorecon >/dev/null 2>&1; then if type restorecon >/dev/null 2>&1; then
restorecon -R "$ICINGA2_RUN_DIR"/icinga2/ restorecon -R "$ICINGA2_RUN_DIR"/icinga2/
fi fi
# Add a fallback if the user did not specify this directory in the sysconfig file
if [ -z "$ICINGA2_CACHE_DIR" ]; then
ICINGA2_CACHE_DIR="$ICINGA2_STATE_DIR"/cache/icinga2
fi
test -e "$ICINGA2_CACHE_DIR" || install -m 750 -o $ICINGA2_USER -g $ICINGA2_COMMAND_GROUP -d "$ICINGA2_CACHE_DIR" test -e "$ICINGA2_CACHE_DIR" || install -m 750 -o $ICINGA2_USER -g $ICINGA2_COMMAND_GROUP -d "$ICINGA2_CACHE_DIR"

View File

@ -1,12 +1,7 @@
#!/bin/sh #!/bin/sh
# load system specific defines
SYSCONFIGFILE=$1
if [ ! -f "$SYSCONFIGFILE" ]; then
echo "Error: You need to supply the path to the Icinga2 sysconfig file as a parameter."
exit 1
fi
. $SYSCONFIGFILE : ${ICINGA2_PID_FILE:="@ICINGA2_RUNDIR@/icinga2/icinga2.pid"}
: ${DAEMON:="@CMAKE_INSTALL_FULL_SBINDIR@/icinga2"}
printf "Validating config files: " printf "Validating config files: "

View File

@ -156,67 +156,69 @@ static int Main()
Application::DeclareZonesDir(Application::GetSysconfDir() + "/icinga2/zones.d"); Application::DeclareZonesDir(Application::GetSysconfDir() + "/icinga2/zones.d");
#ifndef _WIN32 #ifndef _WIN32
if (!Utility::PathExists(Application::GetSysconfigFile())) { if (!autocomplete && !Utility::PathExists(Application::GetSysconfigFile())) {
Log(LogWarning, "icinga-app") Log(LogWarning, "icinga-app")
<< "Sysconfig file '" << Application::GetSysconfigFile() << "' cannot be read. Using default values."; << "Sysconfig file '" << Application::GetSysconfigFile() << "' cannot be read. Using default values.";
} }
#endif /* _WIN32 */ #endif /* _WIN32 */
String icingaUser = Utility::GetFromSysconfig("ICINGA2_USER"); String icingaUser = Utility::GetFromEnvironment("ICINGA2_USER");
if (icingaUser.IsEmpty()) if (icingaUser.IsEmpty())
icingaUser = ICINGA_USER; icingaUser = ICINGA_USER;
String icingaGroup = Utility::GetFromSysconfig("ICINGA2_GROUP"); String icingaGroup = Utility::GetFromEnvironment("ICINGA2_GROUP");
if (icingaGroup.IsEmpty()) if (icingaGroup.IsEmpty())
icingaGroup = ICINGA_GROUP; icingaGroup = ICINGA_GROUP;
Application::DeclareRunAsUser(icingaUser); Application::DeclareRunAsUser(icingaUser);
Application::DeclareRunAsGroup(icingaGroup); Application::DeclareRunAsGroup(icingaGroup);
if (!autocomplete) {
#ifdef RLIMIT_NOFILE #ifdef RLIMIT_NOFILE
String rLimitFiles = Utility::GetFromSysconfig("ICINGA2_RLIMIT_FILES"); String rLimitFiles = Utility::GetFromEnvironment("ICINGA2_RLIMIT_FILES");
if (rLimitFiles.IsEmpty()) if (rLimitFiles.IsEmpty())
Application::DeclareRLimitFiles(Application::GetDefaultRLimitFiles()); Application::DeclareRLimitFiles(Application::GetDefaultRLimitFiles());
else { else {
try { try {
Application::DeclareRLimitFiles(Convert::ToLong(rLimitFiles)); Application::DeclareRLimitFiles(Convert::ToLong(rLimitFiles));
} catch (const std::invalid_argument& ex) { } catch (const std::invalid_argument& ex) {
std::cout std::cout
<< "Error while parsing \"ICINGA2_RLIMIT_FILES\" from sysconfig: " << ex.what() << '\n'; << "Error setting \"ICINGA2_RLIMIT_FILES\": " << ex.what() << '\n';
return EXIT_FAILURE; return EXIT_FAILURE;
}
} }
}
#endif /* RLIMIT_NOFILE */ #endif /* RLIMIT_NOFILE */
#ifdef RLIMIT_NPROC #ifdef RLIMIT_NPROC
String rLimitProcesses = Utility::GetFromSysconfig("ICINGA2_RLIMIT_PROCESSES"); String rLimitProcesses = Utility::GetFromEnvironment("ICINGA2_RLIMIT_PROCESSES");
if (rLimitProcesses.IsEmpty()) if (rLimitProcesses.IsEmpty())
Application::DeclareRLimitProcesses(Application::GetDefaultRLimitProcesses()); Application::DeclareRLimitProcesses(Application::GetDefaultRLimitProcesses());
else { else {
try { try {
Application::DeclareRLimitProcesses(Convert::ToLong(rLimitProcesses)); Application::DeclareRLimitProcesses(Convert::ToLong(rLimitProcesses));
} catch (const std::invalid_argument& ex) { } catch (const std::invalid_argument& ex) {
std::cout std::cout
<< "Error while parsing \"ICINGA2_RLIMIT_PROCESSES\" from sysconfig: " << ex.what() << '\n'; << "Error setting \"ICINGA2_RLIMIT_PROCESSES\": " << ex.what() << '\n';
return EXIT_FAILURE; return EXIT_FAILURE;
}
} }
}
#endif /* RLIMIT_NPROC */ #endif /* RLIMIT_NPROC */
#ifdef RLIMIT_STACK #ifdef RLIMIT_STACK
String rLimitStack = Utility::GetFromSysconfig("ICINGA2_RLIMIT_STACK"); String rLimitStack = Utility::GetFromEnvironment("ICINGA2_RLIMIT_STACK");
if (rLimitStack.IsEmpty()) if (rLimitStack.IsEmpty())
Application::DeclareRLimitStack(Application::GetDefaultRLimitStack()); Application::DeclareRLimitStack(Application::GetDefaultRLimitStack());
else { else {
try { try {
Application::DeclareRLimitStack(Convert::ToLong(rLimitStack)); Application::DeclareRLimitStack(Convert::ToLong(rLimitStack));
} catch (const std::invalid_argument& ex) { } catch (const std::invalid_argument& ex) {
std::cout std::cout
<< "Error while parsing \"ICINGA2_RLIMIT_STACK\" from sysconfig: " << ex.what() << '\n'; << "Error setting \"ICINGA2_RLIMIT_STACK\": " << ex.what() << '\n';
return EXIT_FAILURE; return EXIT_FAILURE;
}
} }
}
#endif /* RLIMIT_STACK */ #endif /* RLIMIT_STACK */
}
Application::DeclareConcurrency(std::thread::hardware_concurrency()); Application::DeclareConcurrency(std::thread::hardware_concurrency());
Application::DeclareMaxConcurrentChecks(Application::GetDefaultMaxConcurrentChecks()); Application::DeclareMaxConcurrentChecks(Application::GetDefaultMaxConcurrentChecks());

View File

@ -1936,37 +1936,16 @@ String Utility::GetIcingaDataPath()
#endif /* _WIN32 */ #endif /* _WIN32 */
String Utility::GetFromSysconfig(const String& env) String Utility::GetFromEnvironment(const String& env)
{ {
#ifndef _WIN32 #ifndef _WIN32
String sysconf = Application::GetSysconfigFile(); const char *envValue = getenv(env.CStr());
if (sysconf.IsEmpty()) if (envValue == NULL)
return ""; return String();
if (!Utility::PathExists(sysconf))
return "";
String cmdInner = ". " + EscapeShellArg(sysconf) + " 2>&1 >/dev/null;echo \"$" + env + "\"";
String cmd = "sh -c " + EscapeShellArg(cmdInner);
FILE *fp = popen(cmd.CStr(), "r");
if (!fp)
return "";
char line[1024];
String out;
if (fgets(line, sizeof(line), fp))
out = line;
else else
return ""; return String(envValue);
#else /* _WIN32 */
pclose(fp); // While getenv exists on Windows, we don't set them. Therefore there is no reason to read them.
return String();
return out.Trim();
#else
//TODO: Figure out how to do this on windows
return "";
#endif /* _WIN32 */ #endif /* _WIN32 */
} }

View File

@ -147,7 +147,7 @@ public:
static String GetIcingaDataPath(); static String GetIcingaDataPath();
#endif /* _WIN32 */ #endif /* _WIN32 */
static String GetFromSysconfig(const String& env); static String GetFromEnvironment(const String& env);
#ifdef I2_DEBUG #ifdef I2_DEBUG
static void SetTime(double); static void SetTime(double);