diff --git a/.gitignore b/.gitignore index e1d44f8..8122f6d 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,4 @@ /salt-2016.11.1.tar.gz /salt-2016.3.5.tar.gz /salt-2016.11.2.tar.gz +/salt-2016.11.3.tar.gz diff --git a/salt-api b/salt-api index 87067a1..dab2ef4 100644 --- a/salt-api +++ b/salt-api @@ -139,7 +139,7 @@ case "$1" in RETVAL=$? fi ;; - condrestart) + condrestart|try-restart) [ -f $LOCKFILE ] && restart || : ;; reload) @@ -147,7 +147,7 @@ case "$1" in RETVAL=1 ;; *) - echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}" + echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload}" exit 1 ;; esac diff --git a/salt-minion b/salt-minion index b0898a4..06d5f0b 100644 --- a/salt-minion +++ b/salt-minion @@ -24,133 +24,301 @@ # # processname: /usr/bin/salt-minion +# Allow these to be overridden for tests +: "${SALTMINION_BINDIR:=/usr/bin}" +: "${SALTMINION_SYSCONFDIR:=/etc}" -DEBIAN_VERSION=/etc/debian_version -SUSE_RELEASE=/etc/SuSE-release -# Source function library. -if [ -f $DEBIAN_VERSION ]; then - break -elif [ -f $SUSE_RELEASE -a -r /etc/rc.status ]; then - . /etc/rc.status -else - . /etc/rc.d/init.d/functions -fi +# 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 -# Default values (can be overridden below) -SALTMINION=/usr/bin/salt-minion -PYTHON=/usr/bin/python -MINION_ARGS="" +SERVICE="salt-minion" -if [ -f /etc/default/salt ]; then - . /etc/default/salt +# 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 -SERVICE=salt-minion -PROCESS=salt-minion - 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//;' \ + | uniq +} + + +_is_running() { + [ -n "$(_get_pid)" ] +} + + +_get_salt_config_value() { + _su_cmd \ + "$MINION_USER" \ + "\ + \"$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() { - echo -n $"Starting salt-minion daemon: " - if [ -f $SUSE_RELEASE ]; then - startproc -f -p /var/run/$SERVICE.pid $SALTMINION -d $MINION_ARGS - rc_status -v - elif [ -e $DEBIAN_VERSION ]; then - if [ -f $LOCKFILE ]; then - echo -n "already started, lock file found" - RETVAL=1 - elif $PYTHON $SALTMINION -d $MINION_ARGS >& /dev/null; then - echo -n "OK" - RETVAL=0 - fi + # $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 - if [[ ! -z "$(pidofproc -p /var/run/$SERVICE.pid $PROCESS)" ]]; then - RETVAL=$? - echo -n "already running" - else - daemon --check $SERVICE $SALTMINION -d $MINION_ARGS - RETVAL=$? - [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$SERVICE - echo - return $RETVAL + 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 - RETVAL=$? echo - return $RETVAL + + return $retval } + stop() { - echo -n $"Stopping salt-minion daemon: " - if [ -f $SUSE_RELEASE ]; then - killproc -TERM $SALTMINION - rc_status -v - RETVAL=$? - elif [ -f $DEBIAN_VERSION ]; then - # Added this since Debian's start-stop-daemon doesn't support spawned processes - if ps -ef | grep "$PYTHON $SALTMINION" | grep -v grep | awk '{print $2}' | xargs kill &> /dev/null; then - echo -n "OK" - RETVAL=0 - else - echo -n "Daemon is not started" - RETVAL=1 - fi - else - killproc $PROCESS - RETVAL=$? - [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$SERVICE - # tidy up any rogue processes: - PROCS=`ps -ef | grep "$SALTMINION" | grep -v grep | awk '{print $2}'` - if [ -n "$PROCS" ]; then - kill $PROCS &> /dev/null - sleep 1 - PROCS=`ps -ef | grep "$SALTMINION" | grep -v grep | awk '{print $2}'` - if [ -n "$PROCS" ]; then - kill -9 $PROCS &> /dev/null + # $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 - 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() { - stop - start + # $1 - config dir + stop "$1" + start "$1" } -# See how we were called. -case "$1" in - start|stop|restart) - $1 - ;; - status) - if [ -f $SUSE_RELEASE ]; then - echo -n "Checking for service salt-minion " - checkproc $SALTMINION - rc_status -v - elif [ -f $DEBIAN_VERSION ]; then - if [ -f $LOCKFILE ]; then - RETVAL=0 - echo "salt-minion is running." - else - RETVAL=1 - echo "salt-minion is stopped." - fi - else - status $PROCESS - RETVAL=$? + +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 "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 - ;; - condrestart) - [ -f $LOCKFILE ] && restart || : - ;; - reload) - echo "can't reload configuration, you have to restart it" - RETVAL=1 - ;; - *) - echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}" - exit 1 - ;; -esac -exit $RETVAL + + 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 < - 2016.11.3-1 +- Update to feature release 2016.11.3 + * Sat Feb 11 2017 Fedora Release Engineering - 2016.11.2-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild diff --git a/sources b/sources index f5723b7..2f0c4de 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (salt-2016.11.2.tar.gz) = 0dbc861424643af664edd2d9cb8bcbde7e9bcf7c1d202a5e844af83c21dc2d75fd7034db27dffc58dc2a6e47cfe2ea2c42e2a9af867c7ca78f93166eb4fd03ad +SHA512 (salt-2016.11.3.tar.gz) = 24bc75c50b4d6bd38a6f2dedc0a8c12142cc1b9d551455e49ea0ede405c78eb6a939f741dd8c0cbb8f206937ee69582bebe2fc127a24a4c2cf06cf3c3c16e507 SHA512 (SaltTesting-2016.10.26.tar.gz) = 0817d3738992bb1e89728a9cd939056bc919de9c995445aac8820f895204e0f14df4cff989c46456b382180e3a1685827a113dbb609518e88c6b944f9222698a