Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
842662f3d5 | |||
d9f22bf634 | |||
587ed04903 | |||
8fdd73af45 | |||
34a43d4db6 | |||
253fd1f094 | |||
b13b47d1c0 | |||
8173828c62 | |||
3ead5f0492 | |||
a921025ce9 | |||
33d35654fc |
13
LICENSE
Normal file
13
LICENSE
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Copyright (c) 2017+, Jack L. Frost <fbt@fleshless.org>
|
||||||
|
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without
|
||||||
|
fee is hereby granted, provided that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||||
|
SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||||
|
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
||||||
|
OF THIS SOFTWARE.
|
9
README.md
Normal file
9
README.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
ssm
|
||||||
|
===
|
||||||
|
|
||||||
|
Yet another service manager.
|
||||||
|
|
||||||
|
Services
|
||||||
|
--------
|
||||||
|
A service is a script in the ssm's init.d directory.
|
||||||
|
By default it's /etc/ssm/init.d for system services and $XDG_CONFIG_HOME/ssm/init.d for user ones.
|
110
ssm
110
ssm
@@ -4,11 +4,13 @@ shopt -s nullglob
|
|||||||
# Utility functions
|
# Utility functions
|
||||||
## Make setting default values a bit less awkward
|
## Make setting default values a bit less awkward
|
||||||
default() {
|
default() {
|
||||||
declare -n _p=$1
|
declare -n _p=$1; shift
|
||||||
|
|
||||||
if ! [[ "$_p" ]]; then
|
[[ "$_p" ]] || {
|
||||||
_p=$2
|
for v in "$@"; do
|
||||||
fi
|
_p+=( "$v" )
|
||||||
|
done
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
## Die. Why not?
|
## Die. Why not?
|
||||||
@@ -96,7 +98,7 @@ pid_wait() {
|
|||||||
|
|
||||||
## See if NAME is a function
|
## See if NAME is a function
|
||||||
is_function() {
|
is_function() {
|
||||||
declare name=$1 name_tupe
|
declare name=$1 name_type
|
||||||
|
|
||||||
name_type=$( type -t "$name" )
|
name_type=$( type -t "$name" )
|
||||||
|
|
||||||
@@ -109,7 +111,7 @@ is_function() {
|
|||||||
|
|
||||||
## Simple timer
|
## Simple timer
|
||||||
timer() {
|
timer() {
|
||||||
declare cnt timeout=$1
|
declare cnt=0 timeout=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
while ! "$@"; do
|
while ! "$@"; do
|
||||||
@@ -188,6 +190,8 @@ depend_ready() {
|
|||||||
super_start() {
|
super_start() {
|
||||||
(( service_running )) && return 3
|
(( service_running )) && return 3
|
||||||
|
|
||||||
|
rm -f "$service_stopped_flag"
|
||||||
|
|
||||||
[[ -f "${service_command[0]}" ]] || return 9
|
[[ -f "${service_command[0]}" ]] || return 9
|
||||||
|
|
||||||
depend "${service_depends[@]}" || return 7
|
depend "${service_depends[@]}" || return 7
|
||||||
@@ -250,6 +254,7 @@ super_stop() {
|
|||||||
|
|
||||||
nullexec kill -n "$service_stop_signal" "$service_pid" || return 1
|
nullexec kill -n "$service_stop_signal" "$service_pid" || return 1
|
||||||
pid_wait "$service_pid" || return 5
|
pid_wait "$service_pid" || return 5
|
||||||
|
> "$service_stopped_flag"
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -273,7 +278,7 @@ info() {
|
|||||||
"Name" "$service_name"
|
"Name" "$service_name"
|
||||||
"Type" "$_type"
|
"Type" "$_type"
|
||||||
"$_status_label" "$_status"
|
"$_status_label" "$_status"
|
||||||
"Exec" "$service_command ${service_args[*]}"
|
"Exec" "${service_command[*]} ${service_args[*]}"
|
||||||
"Respawn" "${service_respawn:-false}"
|
"Respawn" "${service_respawn:-false}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -312,12 +317,14 @@ restart() {
|
|||||||
"$0" "$service_name" start
|
"$0" "$service_name" start
|
||||||
}
|
}
|
||||||
|
|
||||||
logs() { "${PAGER:-less}" "$service_logfile"; }
|
logs() { ${PAGER:-less} "$service_logfile"; }
|
||||||
|
|
||||||
## Status is a bit of a special case. It's talkative.
|
## Status is a bit of a special case. It's talkative.
|
||||||
status() {
|
status() {
|
||||||
(( service_running )) && return 0
|
(( service_running )) && return 0
|
||||||
(( service_enabled )) && return 0
|
(( service_enabled )) && return 0
|
||||||
|
(( service_stopped )) && return 7
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,25 +342,51 @@ main() {
|
|||||||
# Let's set some defaults
|
# Let's set some defaults
|
||||||
service_managed=1
|
service_managed=1
|
||||||
|
|
||||||
|
usrdir='/usr/share/ssm'
|
||||||
|
|
||||||
if (( $UID )); then
|
if (( $UID )); then
|
||||||
# XDG stuff
|
# XDG stuff
|
||||||
default XDG_CONFIG_HOME "$HOME/.config"
|
default XDG_CONFIG_HOME "$HOME/.config"
|
||||||
default XDG_RUNTIME_DIR "/run/user/$UID"
|
default XDG_RUNTIME_DIR "/run/user/$UID"
|
||||||
|
|
||||||
cfgdir="$XDG_CONFIG_HOME/ssm"
|
service_path=( "$XDG_CONFIG_HOME/ssm/services" )
|
||||||
|
cfg_path=( "$XDG_CONFIG_HOME/ssm" )
|
||||||
|
|
||||||
|
# Warn the user of deprecated stuff.
|
||||||
|
if [[ -d "$XDG_CONFIG_HOME/ssm/init.d" ]]; then
|
||||||
|
printf 'WARNING: `%s` was renamed to `%s`! Please move your scripts accordingly!\n' \
|
||||||
|
"$XDG_CONFIG_HOME/ssm/init.d" \
|
||||||
|
"$XDG_CONFIG_HOME/ssm/services" >&2
|
||||||
|
|
||||||
|
service_path+=( "$XDG_CONFIG_HOME/ssm/init.d" )
|
||||||
|
fi
|
||||||
|
|
||||||
rundir="$XDG_RUNTIME_DIR/ssm"
|
rundir="$XDG_RUNTIME_DIR/ssm"
|
||||||
logdir="$HOME/log/ssm"
|
logdir="$HOME/log/ssm"
|
||||||
else
|
else
|
||||||
cfgdir='/etc/ssm'
|
|
||||||
rundir='/run/ssm'
|
rundir='/run/ssm'
|
||||||
logdir='/var/log/ssm'
|
logdir='/var/log/ssm'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
service_path+=( "$cfgdir/init.d" "$rundir/services" )
|
# Warn the user of deprecated stuff.
|
||||||
|
if [[ -d "/etc/ssm/init.d" ]]; then
|
||||||
|
printf 'WARNING: `/etc/ssm/init.d` was renamed to `/etc/ssm/services`! Please move your scripts accordingly!\n' >&2
|
||||||
|
service_path+=( "/etc/ssm/init.d" )
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Common service path
|
||||||
|
service_path+=( '/etc/ssm/services' "$rundir/services" "$usrdir/services" )
|
||||||
|
|
||||||
|
# Common config path
|
||||||
|
cfg_path+=( '/etc/ssm/conf.d' )
|
||||||
|
|
||||||
# Load custom functions
|
# Load custom functions
|
||||||
for f in "$cfgdir/functions"/*; do
|
for (( idx=${#cfg_path[@]}-1; idx>=0; idx-- )); do
|
||||||
source "$f" || die 9 "Failed to source functions from $f"
|
cfg_dir="${cfg_path[idx]}"
|
||||||
|
|
||||||
|
for f in "$cfg_dir/functions"/*; do
|
||||||
|
source "$f" || die 9 "Failed to source functions from $f"
|
||||||
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
# Now create the needed runtime stuff
|
# Now create the needed runtime stuff
|
||||||
@@ -367,7 +400,10 @@ main() {
|
|||||||
service_config=$1
|
service_config=$1
|
||||||
else
|
else
|
||||||
for i in "${service_path[@]}"; do
|
for i in "${service_path[@]}"; do
|
||||||
[[ -f "$i/$1" ]] && service_config="$i/$1"
|
[[ -f "$i/$1" ]] && {
|
||||||
|
service_config="$i/$1"
|
||||||
|
break
|
||||||
|
}
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -381,12 +417,15 @@ main() {
|
|||||||
svc_pidfile="$rundir/$service_name.pid"
|
svc_pidfile="$rundir/$service_name.pid"
|
||||||
|
|
||||||
# Get the service defaults
|
# Get the service defaults
|
||||||
[[ -f "$cfgdir/conf.d/$service_name" ]] && {
|
for p in "${cfg_path[@]}"; do
|
||||||
source "$cfgdir/conf.d/$service_name" || die 5 "Failed to read service defaults: $cfgdir/conf.d/$service_name"
|
[[ -f "$p/conf.d/$service_name" ]] && {
|
||||||
}
|
source "$p/conf.d/$service_name" || die 5 "Failed to read service defaults: $p/conf.d/$service_name"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
done
|
||||||
|
|
||||||
# Get the service config
|
# Get the service config
|
||||||
source -- "$service_config" "${@:3}" || die 7 "Failed to read the service config: $cfgdir/init.d/$service_name"
|
source -- "$service_config" "${@:3}" || die 7 "Failed to read the service config: $service_config"
|
||||||
|
|
||||||
# Legacy
|
# Legacy
|
||||||
[[ "$service_args" ]] && service_command=( "${service_command[@]}" "${service_args[@]}" )
|
[[ "$service_args" ]] && service_command=( "${service_command[@]}" "${service_args[@]}" )
|
||||||
@@ -402,17 +441,16 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Service-level defaults
|
# Service-level defaults
|
||||||
default service_pidfile "$svc_pidfile"
|
default service_pidfile "$svc_pidfile"
|
||||||
default service_logfile "$logdir/$service_name.log"
|
default service_logfile "$logdir/$service_name.log"
|
||||||
default service_stop_timeout 30
|
default service_ready_flag "$rundir/$service_name.ready"
|
||||||
default service_ready_timeout 15
|
default service_enabled_flag "$rundir/$service_name.enabled"
|
||||||
default service_stop_signal 15
|
default service_stopped_flag "$rundir/$service_name.stopped"
|
||||||
default service_reload_signal 1
|
default service_stop_timeout 30
|
||||||
default service_ready_flag "$rundir/$service_name.ready"
|
default service_ready_timeout 15
|
||||||
default service_enabled_flag "$rundir/$service_name.enabled"
|
default service_stop_signal 15
|
||||||
|
default service_reload_signal 1
|
||||||
# default does not support arrays
|
default service_signals 1 10 12
|
||||||
[[ "$service_signals" ]] || service_signals=( 1 10 12 )
|
|
||||||
|
|
||||||
# Let's see if there's a PID
|
# Let's see if there's a PID
|
||||||
if [[ -f "$service_pidfile" ]]; then
|
if [[ -f "$service_pidfile" ]]; then
|
||||||
@@ -430,9 +468,20 @@ main() {
|
|||||||
service_enabled=1
|
service_enabled=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Let's see if the service was deliberately stopped
|
||||||
|
if [[ -f "$service_stopped_flag" ]]; then
|
||||||
|
# Ooh, it was.
|
||||||
|
service_stopped=1
|
||||||
|
fi
|
||||||
|
|
||||||
# Check if action is even defined
|
# Check if action is even defined
|
||||||
is_function "$2" || die 17 "Function $2 is not defined for $service_name."
|
is_function "$2" || die 17 "Function $2 is not defined for $service_name."
|
||||||
|
|
||||||
|
# cd into the workdir, if defined.
|
||||||
|
[[ "$service_workdir" ]] && {
|
||||||
|
cd "$service_workdir" || die $?
|
||||||
|
}
|
||||||
|
|
||||||
# Run pre_$action function
|
# Run pre_$action function
|
||||||
if is_function "pre_$2"; then
|
if is_function "pre_$2"; then
|
||||||
"pre_$2" || {
|
"pre_$2" || {
|
||||||
@@ -475,7 +524,8 @@ main() {
|
|||||||
else
|
else
|
||||||
result "$res" \
|
result "$res" \
|
||||||
0 "$service_name is running" \
|
0 "$service_name is running" \
|
||||||
1 "$service_name is not running"
|
1 "$service_name is not running" \
|
||||||
|
7 "$service_name was stopped"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
Reference in New Issue
Block a user