1#!/bin/sh 2# 3# Salt minion 4################################### 5 6# LSB header 7 8### BEGIN INIT INFO 9# Provides: salt-minion 10# Required-Start: $all 11# Required-Stop: 12# Default-Start: 2 3 4 5 13# Default-Stop: 0 1 6 14# Short-Description: Salt minion daemon 15# Description: This is the Salt minion daemon that can be controlled by the 16# Salt master. 17### END INIT INFO 18 19 20# chkconfig header 21 22# chkconfig: 345 97 04 23# description: This is the Salt minion daemon that can be controlled by the Salt master. 24# 25# processname: /usr/bin/salt-minion 26 27# Allow these to be overridden for tests 28: "${SALTMINION_BINDIR:=/usr/bin}" 29: "${SALTMINION_SYSCONFDIR:=/etc}" 30 31# Default values (can be overridden in settings file) 32: "${USER:=$(id -nu)}" 33SALTMINION="${SALTMINION_BINDIR}/salt-minion" 34SALTCALL="${SALTMINION_BINDIR}/salt-call" 35# SALTMINION_CONFIGS are newline-separated entries of: MINION_USER CONFIG_DIR 36: "${SALTMINION_CONFIGS:=" 37$USER ${SALTMINION_SYSCONFDIR}/salt 38"}" 39SALTMINION_ARGS="" 40SALTMINION_TIMEOUT=30 41SALTMINION_TICK=1 42 43SERVICE="salt-minion" 44 45# Read in settings file 46if [ -f "${SALTMINION_SYSCONFDIR}/default/salt" ]; then 47 . "${SALTMINION_SYSCONFDIR}/default/salt" 48elif [ -f "${SALTMINION_SYSCONFDIR}/sysconfig/salt" ]; then 49 . "${SALTMINION_SYSCONFDIR}/sysconfig/salt" 50fi 51 52RETVAL=0 53NS_NOTRIM="--notrim" 54ERROR_TO_DEVNULL="/dev/null" 55 56 57_su_cmd() { 58 local user="$1" 59 shift 60 61 if [ "X$USER" = "X$user" ]; then 62 eval $1 63 else 64 su -l -c "$1" "$user" 65 fi 66} 67 68 69_get_pid() { 70 cat $PID_FILE 2>/dev/null 71} 72 73 74_is_running() { 75 [ -n "$(_get_pid)" ] && ps wwwaxu | grep '[s]alt-minion' | awk '{print $2}' | grep -qi "\b$(_get_pid)\b" 76} 77 78 79_get_salt_config_value() { 80 _su_cmd \ 81 "$MINION_USER" \ 82 "\ 83 \"$SALTCALL\" \ 84 -c \"$CONFIG_DIR\" \ 85 --no-color \ 86 --skip-grains \ 87 --local config.get \ 88 \"$1\" \ 89 " \ 90 2>$ERROR_TO_DEVNULL \ 91 | sed -r -e '2!d; s/^\s*//;' 92} 93 94 95_make_id_hash() { 96 # $1 - minion_id 97 local hasher='' 98 99 case "$(_get_salt_config_value hash_type)" in 100 (md5) hasher="md5sum";; 101 (sha1) hasher="sha1sum";; 102 (sha224) hasher="sha224sum";; 103 (sha256) hasher="sha256sum";; 104 (sha384) hasher="sha384sum";; 105 (sha512) hasher="sha512sum";; 106 (*) echo "ERROR: No salt hash_type specified";; 107 esac 108 109 if [ -n "$hasher" ]; then 110 printf "$1" | "$hasher" | cut -c 1-10 111 fi 112} 113 114 115start() { 116 # $1 - config dir 117 local retval=0 118 119 if _is_running; then 120 echo "Service $SERVICE:$MINION_USER:$MINION_ID already running" 121 return 0 122 fi 123 124 echo -n "Starting $SERVICE:$MINION_USER:$MINION_ID daemon: " 125 126 _su_cmd \ 127 "$MINION_USER" \ 128 "\ 129 \"$SALTMINION\" \ 130 -c \"$CONFIG_DIR\" \ 131 -d $SALTMINION_ARGS \ 132 ${SALTMINION_DEBUG:+-l debug} \ 133 " \ 134 2>$ERROR_TO_DEVNULL \ 135 || retval=$? 136 137 if [ 0 -eq "$retval" ]; then 138 local endtime=$(($(date '+%s')+$SALTMINION_TIMEOUT)) 139 while ! _is_running; do 140 if [ "$endtime" -lt "$(date '+%s')" ]; then 141 echo -n "TIMEOUT " 142 retval=1 143 break 144 fi 145 sleep $SALTMINION_TICK 146 done 147 fi 148 149 if [ 0 -eq "$retval" ]; then 150 echo -n "OK" 151 else 152 echo -n "FAIL" 153 if [ -n "$SALTMINION_DEBUG" ]; then 154 printf "\nPROCESSES:\n" >&2 155 ps wwwaxu | grep '[s]alt-minion' >&2 156 printf "\nSOCKETS:\n" >&2 157 netstat -n $NS_NOTRIM -ap --protocol=unix | grep 'salt.*minion' >&2 158 printf "\nLOG_FILE:\n" >&2 159 tail -n 20 "$LOG_FILE" >&2 160 printf "\nENVIRONMENT:\n" >&2 161 env >&2 162 fi 163 fi 164 echo 165 166 return $retval 167} 168 169 170stop() { 171 # $1 - config dir 172 local retval=0 173 174 if ! _is_running; then 175 echo "Service $SERVICE:$MINION_USER:$MINION_ID is not running" 176 return 0 177 fi 178 179 echo -n "Stopping $SERVICE:$MINION_USER:$MINION_ID daemon: " 180 local pid="$(_get_pid)" 181 182 # pid below is intentionally not quoted in case there are *multiple* 183 # minions running with the same configuration. 184 _su_cmd "$MINION_USER" "kill -TERM $pid 2>/dev/null" || retval=$? 185 if [ 0 -eq "$retval" ]; then 186 local endtime=$(($(date '+%s')+$SALTMINION_TIMEOUT)) 187 while _is_running; do 188 if [ "$endtime" -lt "$(date '+%s')" ]; then 189 # Try one more time with a big hammer 190 _su_cmd "$MINION_USER" "kill -KILL $pid 2>/dev/null" || : 191 sleep $SALTMINION_TICK 192 if _is_running; then 193 echo -n "TIMEOUT " 194 retval=1 195 fi 196 break 197 fi 198 sleep 1 199 done 200 201 fi 202 203 if [ 0 -eq "$retval" ]; then 204 rm -f "$PID_FILE" 205 echo -n "OK" 206 else 207 echo -n "FAIL" 208 fi 209 210 echo 211 212 return $retval 213} 214 215 216status() { 217 local retval=0 218 local pid="$(_get_pid)" 219 220 if _is_running; then 221 # Unquote $pid here to display multiple PIDs in one line 222 echo "$SERVICE:$MINION_USER:$MINION_ID is running:" $pid 223 else 224 retval=3 225 echo "$SERVICE:$MINION_USER:$MINION_ID is stopped." 226 if [ -e "$PID_FILE" ]; then 227 echo "$SERVICE:$MINION_USER:$MINION_ID has orphaned pid file: $PID_FILE." 228 retval=1 229 fi 230 fi 231 return $retval 232} 233 234restart() { 235 # $1 - config dir 236 stop "$1" 237 start "$1" 238} 239 240 241main() { 242 if [ -n "$SALTMINION_DEBUG" ]; then 243 set -x 244 ERROR_TO_DEVNULL="&2" 245 fi 246 247 # Check to see if --notrim is a valid netstat option 248 if ! ( netstat --help 2>&1 | grep -wq '\-\-notrim') ; then 249 NS_NOTRIM='' 250 fi 251 252 # Pre-filter for unhandled commands 253 case "$1" in 254 (start|stop|status|restart|condrestart|try-restart) ;; 255 (reload) 256 echo "Can't reload $SERVICE - you must restart it" 257 exit 3 258 ;; 259 (*) 260 echo "Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload}" 261 exit 2 262 ;; 263 esac 264 265 while read MINION_USER CONFIG_DIR; do 266 if [ -z "$CONFIG_DIR" ]; then 267 continue 268 fi 269 270 if ! [ -d "$CONFIG_DIR" ]; then 271 echo "ERROR: non-existent $SERVICE config directory: $CONFIG_DIR" 272 RETVAL=1 273 continue 274 fi 275 276 SOCK_DIR="$(_get_salt_config_value sock_dir)" 277 PID_FILE="$(_get_salt_config_value pidfile)" 278 LOG_FILE="$(_get_salt_config_value log_file)" 279 MINION_ID="$(_get_salt_config_value id)" 280 MINION_ID_HASH="$(_make_id_hash "$MINION_ID")" 281 if [ \ 282 -z "$SOCK_DIR" \ 283 -o -z "$PID_FILE" \ 284 -o -z "$LOG_FILE" \ 285 -o -z "$MINION_ID" \ 286 -o -z "$MINION_ID_HASH" \ 287 ]; then 288 echo "ERROR: Unable to look-up config values for $CONFIG_DIR" 289 RETVAL=1 290 continue 291 fi 292 293 # See how we were called. 294 case "$1" in 295 (start|stop|restart|status) 296 "$1" || RETVAL=$? 297 ;; 298 (condrestart|try-restart) 299 if ! _is_running; then 300 RETVAL=7 301 else 302 stop 303 start || RETVAL=$? 304 fi 305 ;; 306 (*) 307 echo "Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload}" 308 RETVAL=2 309 ;; 310 esac 311 done <<EOF 312$SALTMINION_CONFIGS 313EOF 314 315 exit $RETVAL 316} 317 318 319if [ "$#" = 0 ]; then 320 main 321else 322 main "$@" 323fi 324