mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 17:33:54 +00:00
0efbbcd17f
* * Improve init script: specifically manage salt configurations rather than arbitrary salt processes Unfortunately SysV init scripts tend to rummage through PIDs filtering for appropriate processes to manage. Unfortunately the filters are usually weak and don't account for similar processes run by other users, PIDs of dead processes being re-used for completely different executables, etc.. These weaknesses can result in killing unrelated processes with potentially serious results. These improvements to the SysV init script is a complete rewrite with the following improvements: * Specifically manage individual salt configurations rather than looking for salt minion-like processes. * Obtain salt minion information from the salt configuration - use the information to manage the specifically configured process. * Drop all of the platform-specific helper functions that allow the previously-mentioned weaknesses. + Unfortunately this means that the output information may not match the specific platform (this could easily be corrected). * Now can manage multiple salt processes started by different users + Unfortunately starts/stops/restarts as a group and is unable to manage them both as a group or as individual processes (this could easily be corrected) The new initscript also allows various control variables to be overridden by environment variables or through settings put in ``/etc/sysconf/salt`` or ``/etc/default/salt``. :SALTMINION_DEBUG: Dump each line expansion before execution, output system information on failure. Default: unset :SALTMINION_BINDIR: Location of ``salt-minion``, ``salt-call`` and other executables. Default: ``/usr/bin`` :SALTMINION_SYSCONFDIR: The parent directory for the ``salt`` configuration directory and the ``sysconfig`` or ``default`` directory. * Add lines that went missing in the rebase+squash
325 lines
7.7 KiB
Bash
Executable File
325 lines
7.7 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Salt minion
|
|
###################################
|
|
|
|
# LSB header
|
|
|
|
### BEGIN INIT INFO
|
|
# Provides: salt-minion
|
|
# Required-Start: $all
|
|
# Required-Stop:
|
|
# Default-Start: 2 3 4 5
|
|
# Default-Stop: 0 1 6
|
|
# Short-Description: Salt minion daemon
|
|
# Description: This is the Salt minion daemon that can be controlled by the
|
|
# Salt master.
|
|
### END INIT INFO
|
|
|
|
|
|
# chkconfig header
|
|
|
|
# chkconfig: 345 97 04
|
|
# description: This is the Salt minion daemon that can be controlled by the Salt master.
|
|
#
|
|
# processname: /usr/bin/salt-minion
|
|
|
|
# Allow these to be overridden for tests
|
|
: ${SALTMINION_BINDIR:=/usr/bin}
|
|
: ${SALTMINION_SYSCONFDIR:=/etc}
|
|
: ${SALTMINION_PYTHON:=python} # Python must be 2.6 or newer
|
|
|
|
# Default values (can be overridden in settings file)
|
|
: ${USER:=$(id -nu)}
|
|
SALTMINION="${SALTMINION_BINDIR}/salt-minion"
|
|
SALTCALL="${SALTMINION_BINDIR}/salt-call"
|
|
# SALTMINION_CONFIGS are newline-separated entries of: MINION_USER CONFIG_DIR
|
|
: ${SALTMINION_CONFIGS:="
|
|
$USER ${SALTMINION_SYSCONFDIR}/salt
|
|
"}
|
|
SALTMINION_ARGS=""
|
|
SALTMINION_TIMEOUT=30
|
|
SALTMINION_TICK=1
|
|
|
|
SERVICE="salt-minion"
|
|
PROCESS="salt-minion"
|
|
|
|
# Read in settings file
|
|
if [ -f "${SALTMINION_SYSCONFDIR}/default/salt" ]; then
|
|
. "${SALTMINION_SYSCONFDIR}/default/salt"
|
|
elif [ -f "${SALTMINION_SYSCONFDIR}/sysconfig/salt" ]; then
|
|
. "${SALTMINION_SYSCONFDIR}/sysconfig/salt"
|
|
fi
|
|
|
|
RETVAL=0
|
|
NS_NOTRIM="--notrim"
|
|
ERROR_TO_DEVNULL="/dev/null"
|
|
|
|
|
|
_su_cmd() {
|
|
local user="$1"
|
|
shift
|
|
|
|
if [ "X$USER" = "X$user" ]; then
|
|
eval $1
|
|
else
|
|
su -l -c "$1" "$user"
|
|
fi
|
|
}
|
|
|
|
|
|
_get_pid() {
|
|
netstat $NS_NOTRIM -ap --protocol=unix 2>$ERROR_TO_DEVNULL \
|
|
| sed -r -e "\|\s${SOCK_DIR}/minion_event_${MINION_ID_HASH}_pub\.ipc$|"'!d; s|/.*||; s/.*\s//;'
|
|
}
|
|
|
|
|
|
_is_running() {
|
|
[ -n "$(_get_pid)" ]
|
|
}
|
|
|
|
|
|
_get_salt_config_value() {
|
|
_su_cmd \
|
|
"$MINION_USER" \
|
|
"\"$SALTMINION_PYTHON\" \
|
|
\"$SALTCALL\" \
|
|
-c \"$CONFIG_DIR\" \
|
|
--no-color \
|
|
--local config.get \
|
|
\"$1\" \
|
|
" \
|
|
2>$ERROR_TO_DEVNULL \
|
|
| sed -r -e '2!d; s/^\s*//;'
|
|
}
|
|
|
|
|
|
_make_id_hash() {
|
|
# $1 - minion_id
|
|
local hasher=''
|
|
|
|
case "$(_get_salt_config_value hash_type)" in
|
|
(md5) hasher="md5sum";;
|
|
(sha1) hasher="sha1sum";;
|
|
(sha224) hasher="sha224sum";;
|
|
(sha256) hasher="sha256sum";;
|
|
(sha384) hasher="sha384sum";;
|
|
(sha512) hasher="sha512sum";;
|
|
(*) echo "ERROR: No salt hash_type specified";;
|
|
esac
|
|
|
|
if [ -n "$hasher" ]; then
|
|
printf "$1" | "$hasher" | cut -c 1-10
|
|
fi
|
|
}
|
|
|
|
|
|
start() {
|
|
# $1 - config dir
|
|
local retval=0
|
|
|
|
if _is_running; then
|
|
echo "Service $SERVICE:$MINION_USER:$MINION_ID already running"
|
|
return 0
|
|
fi
|
|
|
|
echo -n "Starting $SERVICE:$MINION_USER:$MINION_ID daemon: "
|
|
|
|
_su_cmd \
|
|
"$MINION_USER" \
|
|
"\"$SALTMINION_PYTHON\" \
|
|
\"$SALTMINION\" \
|
|
-c \"$CONFIG_DIR\" \
|
|
-d $SALTMINION_ARGS \
|
|
${SALTMINION_DEBUG:+-l debug} \
|
|
" \
|
|
2>$ERROR_TO_DEVNULL \
|
|
|| retval=$?
|
|
|
|
if [ 0 -eq "$retval" ]; then
|
|
local endtime=$(($(date '+%s')+$SALTMINION_TIMEOUT))
|
|
while ! _is_running; do
|
|
if [ "$endtime" -lt "$(date '+%s')" ]; then
|
|
echo -n "TIMEOUT "
|
|
retval=1
|
|
break
|
|
fi
|
|
sleep $SALTMINION_TICK
|
|
done
|
|
fi
|
|
|
|
if [ 0 -eq "$retval" ]; then
|
|
echo -n "OK"
|
|
else
|
|
echo -n "FAIL"
|
|
if [ -n "$SALTMINION_DEBUG" ]; then
|
|
printf "\nPROCESSES:\n" >&2
|
|
ps wwwaxu | grep '[s]alt-minion' >&2
|
|
printf "\nSOCKETS:\n" >&2
|
|
netstat $NS_NOTRIM -ap --protocol=unix | grep 'salt.*minion' >&2
|
|
printf "\nLOG_FILE:\n" >&2
|
|
tail -n 20 "$LOG_FILE" >&2
|
|
printf "\nENVIRONMENT:\n" >&2
|
|
env >&2
|
|
fi
|
|
fi
|
|
echo
|
|
|
|
return $retval
|
|
}
|
|
|
|
|
|
stop() {
|
|
# $1 - config dir
|
|
local retval=0
|
|
|
|
if ! _is_running; then
|
|
echo "Service $SERVICE:$MINION_USER:$MINION_ID is not running"
|
|
return 0
|
|
fi
|
|
|
|
echo -n "Stopping $SERVICE:$MINION_USER:$MINION_ID daemon: "
|
|
local pid="$(_get_pid)"
|
|
|
|
# pid below is intentionally not quoted in case there are *multiple*
|
|
# minions running with the same configuration.
|
|
_su_cmd "$MINION_USER" "kill -TERM $pid 2>/dev/null" || retval=$?
|
|
if [ 0 -eq "$retval" ]; then
|
|
local endtime=$(($(date '+%s')+$SALTMINION_TIMEOUT))
|
|
while _is_running; do
|
|
if [ "$endtime" -lt "$(date '+%s')" ]; then
|
|
# Try one more time with a big hammer
|
|
_su_cmd "$MINION_USER" "kill -KILL $pid 2>/dev/null" || :
|
|
sleep $SALTMINION_TICK
|
|
if _is_running; then
|
|
echo -n "TIMEOUT "
|
|
retval=1
|
|
fi
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
fi
|
|
|
|
if [ 0 -eq "$retval" ]; then
|
|
rm -f "$PID_FILE"
|
|
echo -n "OK"
|
|
else
|
|
echo -n "FAIL"
|
|
fi
|
|
|
|
echo
|
|
|
|
return $retval
|
|
}
|
|
|
|
|
|
status() {
|
|
local retval=0
|
|
local pid="$(_get_pid)"
|
|
|
|
if [ -n "$pid" ]; then
|
|
echo "$SERVICE:$MINION_USER:$MINION_ID is running: $pid"
|
|
else
|
|
retval=3
|
|
echo "$SERVICE:$MINION_USER:$MINION_ID is stopped."
|
|
if [ -e "$PID_FILE" ]; then
|
|
echo "$SERVICE:$MINION_USER:$MINION_ID has orphaned pid file: $PID_FILE."
|
|
retval=1
|
|
fi
|
|
fi
|
|
return $retval
|
|
}
|
|
|
|
restart() {
|
|
# $1 - config dir
|
|
stop "$1"
|
|
start "$1"
|
|
}
|
|
|
|
|
|
main() {
|
|
if [ -n "$SALTMINION_DEBUG" ]; then
|
|
set -x
|
|
ERROR_TO_DEVNULL="&2"
|
|
fi
|
|
|
|
# Check to see if --notrim is a valid netstat option
|
|
if netstat --notrim 2>&1 >/dev/null | grep -q 'unrecognized'; then
|
|
NS_NOTRIM=''
|
|
fi
|
|
|
|
# Pre-filter for unhandled commands
|
|
case "$1" in
|
|
(start|stop|status|restart|condrestart|try-restart|reload) ;;
|
|
(*)
|
|
echo "Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload}"
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
while read MINION_USER CONFIG_DIR; do
|
|
if [ -z "$CONFIG_DIR" ]; then
|
|
continue
|
|
fi
|
|
|
|
if ! [ -d "$CONFIG_DIR" ]; then
|
|
echo "ERROR: non-existent $SERVICE config directory: $CONFIG_DIR"
|
|
RETVAL=1
|
|
continue
|
|
fi
|
|
|
|
SOCK_DIR="$(_get_salt_config_value sock_dir)"
|
|
PID_FILE="$(_get_salt_config_value pidfile)"
|
|
LOG_FILE="$(_get_salt_config_value log_file)"
|
|
MINION_ID="$(_get_salt_config_value id)"
|
|
MINION_ID_HASH="$(_make_id_hash "$MINION_ID")"
|
|
if [ \
|
|
-z "$SOCK_DIR" \
|
|
-o -z "$PID_FILE" \
|
|
-o -z "$LOG_FILE" \
|
|
-o -z "$MINION_ID" \
|
|
-o -z "$MINION_ID_HASH" \
|
|
]; then
|
|
echo "ERROR: Unable to look-up config values for $CONFIG_DIR"
|
|
RETVAL=1
|
|
continue
|
|
fi
|
|
|
|
# See how we were called.
|
|
case "$1" in
|
|
(start|stop|restart|status)
|
|
"$1" || RETVAL=$?
|
|
;;
|
|
(condrestart|try-restart)
|
|
if ! _is_running; then
|
|
RETVAL=7
|
|
else
|
|
stop
|
|
start || RETVAL=$?
|
|
fi
|
|
;;
|
|
(reload)
|
|
echo "Can't reload $SERVICE configuration - you must restart it"
|
|
RETVAL=3
|
|
;;
|
|
(*)
|
|
echo "Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload}"
|
|
RETVAL=2
|
|
;;
|
|
esac
|
|
done <<EOF
|
|
$SALTMINION_CONFIGS
|
|
EOF
|
|
|
|
exit $RETVAL
|
|
}
|
|
|
|
|
|
if [ "$#" = 0 ]; then
|
|
main
|
|
else
|
|
main "$@"
|
|
fi
|