#!/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}" # 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" # 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 -n $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//;' \ | uniq } _is_running() { [ -n "$(_get_pid)" ] } _get_salt_config_value() { _su_cmd \ "$MINION_USER" \ "\ \"$SALTCALL\" \ -c \"$CONFIG_DIR\" \ --no-color \ --skip-grains \ --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\" \ -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 -n $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 # Unquote $pid here to display multiple PIDs in one line 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 --help 2>&1 | grep -wq '\-\-notrim') ; then NS_NOTRIM='' fi # Pre-filter for unhandled commands case "$1" in (start|stop|status|restart|condrestart|try-restart) ;; (reload) echo "Can't reload $SERVICE - you must restart it" exit 3 ;; (*) 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 ;; (*) echo "Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload}" RETVAL=2 ;; esac done <