13 Commits
0.1.1 ... 0.3.5

Author SHA1 Message Date
fbt
32b26b5783 cfg_path bugfix
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-10 20:13:51 +03:00
fbt
6f2db37dff Show the config path in the info
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-10 19:48:22 +03:00
fbt
842662f3d5 Actually, let's move softly
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-10 19:42:25 +03:00
fbt
d9f22bf634 init.d -> services
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-10 19:27:51 +03:00
fbt
587ed04903 init.d and reverse functions load order
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-08 16:49:34 +03:00
fbt
8fdd73af45 More flexibility
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-08 16:39:05 +03:00
fbt
34a43d4db6 also search for services in a package dir
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-08 15:16:03 +03:00
fbt
253fd1f094 default can do arrays now
Signed-off-by: fbt <fbt@fleshless.org>
2017-12-08 14:39:50 +03:00
fbt
b13b47d1c0 show the full service command; do not escape the pager
Signed-off-by: fbt <fbt@fleshless.org>
2017-11-14 16:58:53 +03:00
fbt
8173828c62 stopped services and workdir
Signed-off-by: fbt <fbt@fleshless.org>
2017-11-09 04:19:26 +03:00
fbt
3ead5f0492 better readaility
Signed-off-by: fbt <fbt@fleshless.org>
2017-07-13 16:25:41 +03:00
fbt
a921025ce9 oops
Signed-off-by: fbt <fbt@fleshless.org>
2017-07-13 16:20:57 +03:00
fbt
33d35654fc licence and readme
Signed-off-by: fbt <fbt@fleshless.org>
2017-07-13 15:45:56 +03:00
3 changed files with 104 additions and 31 deletions

13
LICENSE Normal file
View 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
View 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.

95
ssm
View File

@@ -4,11 +4,13 @@ shopt -s nullglob
# Utility functions
## Make setting default values a bit less awkward
default() {
declare -n _p=$1
declare -n _p=$1; shift
if ! [[ "$_p" ]]; then
_p=$2
fi
[[ "$_p" ]] || {
for v in "$@"; do
_p+=( "$v" )
done
}
}
## Die. Why not?
@@ -96,7 +98,7 @@ pid_wait() {
## See if NAME is a function
is_function() {
declare name=$1 name_tupe
declare name=$1 name_type
name_type=$( type -t "$name" )
@@ -109,7 +111,7 @@ is_function() {
## Simple timer
timer() {
declare cnt timeout=$1
declare cnt=0 timeout=$1
shift
while ! "$@"; do
@@ -188,6 +190,8 @@ depend_ready() {
super_start() {
(( service_running )) && return 3
rm -f "$service_stopped_flag"
[[ -f "${service_command[0]}" ]] || return 9
depend "${service_depends[@]}" || return 7
@@ -250,6 +254,7 @@ super_stop() {
nullexec kill -n "$service_stop_signal" "$service_pid" || return 1
pid_wait "$service_pid" || return 5
> "$service_stopped_flag"
return 0
fi
@@ -273,8 +278,9 @@ info() {
"Name" "$service_name"
"Type" "$_type"
"$_status_label" "$_status"
"Exec" "$service_command ${service_args[*]}"
"Exec" "${service_command[*]} ${service_args[*]}"
"Respawn" "${service_respawn:-false}"
"Config path" "${service_config}"
)
[[ "$_status" == 'yes' ]] && {
@@ -312,12 +318,14 @@ restart() {
"$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() {
(( service_running )) && return 0
(( service_enabled )) && return 0
(( service_stopped )) && return 7
return 1
}
@@ -335,26 +343,52 @@ main() {
# Let's set some defaults
service_managed=1
usrdir='/usr/share/ssm'
if (( $UID )); then
# XDG stuff
default XDG_CONFIG_HOME "$HOME/.config"
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"
logdir="$HOME/log/ssm"
else
cfgdir='/etc/ssm'
rundir='/run/ssm'
logdir='/var/log/ssm'
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' )
# Load custom functions
for f in "$cfgdir/functions"/*; do
for (( idx=${#cfg_path[@]}-1; idx>=0; idx-- )); do
cfg_dir="${cfg_path[idx]}"
for f in "$cfg_dir/functions"/*; do
source "$f" || die 9 "Failed to source functions from $f"
done
done
# Now create the needed runtime stuff
for d in "$rundir" "$logdir"; do
@@ -367,7 +401,10 @@ main() {
service_config=$1
else
for i in "${service_path[@]}"; do
[[ -f "$i/$1" ]] && service_config="$i/$1"
[[ -f "$i/$1" ]] && {
service_config="$i/$1"
break
}
done
fi
@@ -381,12 +418,15 @@ main() {
svc_pidfile="$rundir/$service_name.pid"
# Get the service defaults
[[ -f "$cfgdir/conf.d/$service_name" ]] && {
source "$cfgdir/conf.d/$service_name" || die 5 "Failed to read service defaults: $cfgdir/conf.d/$service_name"
for p in "${cfg_path[@]}"; do
[[ -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
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
[[ "$service_args" ]] && service_command=( "${service_command[@]}" "${service_args[@]}" )
@@ -404,15 +444,14 @@ main() {
# Service-level defaults
default service_pidfile "$svc_pidfile"
default service_logfile "$logdir/$service_name.log"
default service_ready_flag "$rundir/$service_name.ready"
default service_enabled_flag "$rundir/$service_name.enabled"
default service_stopped_flag "$rundir/$service_name.stopped"
default service_stop_timeout 30
default service_ready_timeout 15
default service_stop_signal 15
default service_reload_signal 1
default service_ready_flag "$rundir/$service_name.ready"
default service_enabled_flag "$rundir/$service_name.enabled"
# default does not support arrays
[[ "$service_signals" ]] || service_signals=( 1 10 12 )
default service_signals 1 10 12
# Let's see if there's a PID
if [[ -f "$service_pidfile" ]]; then
@@ -430,9 +469,20 @@ main() {
service_enabled=1
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
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
if is_function "pre_$2"; then
"pre_$2" || {
@@ -475,7 +525,8 @@ main() {
else
result "$res" \
0 "$service_name is running" \
1 "$service_name is not running"
1 "$service_name is not running" \
7 "$service_name was stopped"
fi
;;
esac