Skip to content
Permalink
Browse files

Add cli tool to send signals as Icinga user

fixes #5991
  • Loading branch information...
Crunsher committed Jan 17, 2018
1 parent 73dcebe commit c6b86680a028f4f4c609aadd708e2454eae53cb0
Showing with 179 additions and 45 deletions.
  1. +44 −44 etc/initsystem/icinga2.init.d.cmake
  2. +1 −1 lib/cli/CMakeLists.txt
  3. +84 −0 lib/cli/internalsignalcommand.cpp
  4. +50 −0 lib/cli/internalsignalcommand.hpp
@@ -47,14 +47,14 @@ getent group $ICINGA2_COMMAND_GROUP >/dev/null 2>&1 || (echo "Icinga command gro

# Get function from functions library
if [ -f /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
. /etc/rc.d/init.d/functions
elif [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
. /etc/init.d/functions
fi

# Load extra environment variables
if [ -f /etc/default/icinga2 ]; then
. /etc/default/icinga2
. /etc/default/icinga2
fi

# Start Icinga 2
@@ -72,34 +72,33 @@ start() {

# Restart Icinga 2
stop() {
printf "Stopping Icinga 2: "
printf "Stopping Icinga 2: "

if [ ! -e $ICINGA2_PID_FILE ]; then
echo "The PID file '$ICINGA2_PID_FILE' does not exist."
if [ "x$1" = "xnofail" ]; then
if [ ! -e $ICINGA2_PID_FILE ]; then
echo "The PID file '$ICINGA2_PID_FILE' does not exist."
if [ "x$1" = "xnofail" ]; then
return
else
exit 7
fi
fi
fi

pid=`cat $ICINGA2_PID_FILE`
if kill -INT $pid >/dev/null 2>&1; then

if icinga2 internal signal -s SIGINT -p $pid >/dev/null 2>&1; then
for i in 1 2 3 4 5 6 7 8 9 10; do
if ! kill -CHLD $pid >/dev/null 2>&1; then
if ! icinga2 internal signal -s SIGCHLD -p $pid >/dev/null 2>&1; then
break
fi

printf '.'

sleep 3
done
fi

if kill -CHLD $pid >/dev/null 2>&1; then
kill -KILL $pid
fi
if icinga2 internal signal -s SIGCHLD -p $pid >/dev/null 2>&1; then
icinga2 internal signal -s SIGKILL -p $pid >/dev/null 2>&1
fi

echo "Done"
}
@@ -114,21 +113,21 @@ checkconfig() {
printf "Checking configuration: "

if ! $DAEMON daemon -c $ICINGA2_CONFIG_FILE -C > $ICINGA2_STARTUP_LOG 2>&1; then
if [ "x$1" = "x" ]; then
if [ "x$1" = "x" ]; then
cat $ICINGA2_STARTUP_LOG
echo "Icinga 2 detected configuration errors. Check '$ICINGA2_STARTUP_LOG' for details."
exit 1
else
exit 1
else
echo "Not "$1"ing Icinga 2 due to configuration errors. Check '$ICINGA2_STARTUP_LOG' for details."
if [ "x$2" = "xfail" ]; then
exit 1
fi
fi
fi
if [ "x$2" = "xfail" ]; then
exit 1
fi
fi
fi

echo "Done"
# no arguments requires full output
if [ "x$1" = "x" ]; then
if [ "x$1" = "x" ]; then
cat $ICINGA2_STARTUP_LOG
fi
}
@@ -143,7 +142,7 @@ status() {
fi

pid=`cat $ICINGA2_PID_FILE`
if kill -CHLD $pid >/dev/null 2>&1; then
if icinga2 internal signal -s SIGCHLD -p $pid >/dev/null 2>&1; then
echo "Running"
else
echo "Not running"
@@ -155,33 +154,34 @@ status() {
case "$1" in
start)
checkconfig start fail
start
;;
start
;;
stop)
stop
;;
stop
;;
status)
status
;;
status
;;
restart)
checkconfig restart fail
stop nofail
start
;;
stop nofail
start
;;
condrestart)
status > /dev/null 2>&1 || exit 0
checkconfig restart fail
stop nofail
start
;;
status > /dev/null 2>&1 || exit 0
checkconfig restart fail
stop nofail
start
;;
reload)
reload
;;
;;
checkconfig)
checkconfig
;;
;;
*)
echo "Usage: $0 {start|stop|restart|reload|checkconfig|status}"
exit 3
echo "Usage: $0 {start|stop|restart|reload|checkconfig|status}"
exit 3
esac

exit 0
@@ -26,7 +26,7 @@ set(cli_SOURCES
objectlistcommand.cpp objectlistutility.cpp
pkinewcacommand.cpp pkinewcertcommand.cpp pkisigncsrcommand.cpp pkirequestcommand.cpp pkisavecertcommand.cpp pkiticketcommand.cpp
variablegetcommand.cpp variablelistcommand.cpp variableutility.cpp
apiusercommand.cpp troubleshootcommand.cpp
internalsignalcommand.cpp apiusercommand.cpp troubleshootcommand.cpp
)

if(ICINGA2_UNITY_BUILD)
@@ -0,0 +1,84 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/

#include "cli/internalsignalcommand.hpp"
#include "base/logger.hpp"
#include <signal.h>

using namespace icinga;
namespace po = boost::program_options;

REGISTER_CLICOMMAND("internal/signal", InternalSignalCommand);

String InternalSignalCommand::GetDescription() const
{
return "Send signal as Icinga user";
}

String InternalSignalCommand::GetShortDescription() const
{
return "Send signal as Icinga user";
}

ImpersonationLevel InternalSignalCommand::GetImpersonationLevel() const
{
return ImpersonateIcinga;
}

bool InternalSignalCommand::IsHidden() const
{
return true;
}

void InternalSignalCommand::InitParameters(boost::program_options::options_description& visibleDesc,
boost::program_options::options_description& hiddenDesc) const
{
visibleDesc.add_options()
("pid,p", po::value<int>(), "Target PID")
("sig,s", po::value<String>(), "Signal (POSIX string) to send")
;
}

/**
* The entry point for the "internal signal" CLI command.
*
* @returns An exit status.
*/
int InternalSignalCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
{
#ifndef _WIN32
String signal = vm["sig"].as<String>();

/* Thank POSIX */
if (signal == "SIGKILL")
return kill(vm["pid"].as<int>(), SIGKILL);
if (signal == "SIGINT")
return kill(vm["pid"].as<int>(), SIGINT);
if (signal == "SIGCHLD")
return kill(vm["pid"].as<int>(), SIGCHLD);
if (signal == "SIGHUP")
return kill(vm["pid"].as<int>(), SIGHUP);

Log(LogCritical, "cli") << "Unsupported signal \"" << signal << "\"";
#else
Log(LogCritical, "cli", "Unsupported action on Windows.");
#endif /* _Win32 */
return 1;
}

@@ -0,0 +1,50 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/

#ifndef INTERNALSIGNALCOMMAND_H
#define INTERNALSIGNALCOMMAND_H

#include "cli/clicommand.hpp"

namespace icinga
{

/**
* The "internal signal" command.
*
* @ingroup cli
*/
class InternalSignalCommand final : public CLICommand
{
public:
DECLARE_PTR_TYPEDEFS(InternalSignalCommand);

String GetDescription() const override;
String GetShortDescription() const override;
ImpersonationLevel GetImpersonationLevel() const override;
bool IsHidden() const override;
void InitParameters(boost::program_options::options_description& visibleDesc,
boost::program_options::options_description& hiddenDesc) const override;
int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;

};

}

#endif /* INTERNALSIGNALCOMMAND_H */

0 comments on commit c6b8668

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.