diff --git a/ssm b/ssm index 80d1b17..9653de7 100755 --- a/ssm +++ b/ssm @@ -200,6 +200,30 @@ result() { printf '%s\n' "${msgs[$rc]}" }; readonly -f result +read_systemd_service() { + declare section key value + + while read -r line; do + [[ $line =~ ^\[(.+)\] ]] && section=${BASH_REMATCH[1],,} + [[ $line =~ ^([^=]+)=(.+) ]] && { + key=${BASH_REMATCH[1],,} + value=${BASH_REMATCH[2]} + } + + case $section in + (service) + case $key in + (pidfile) service_pidfile=$value;; + (execstart) eval "service_command=( $value )";; + (execstop) eval "service_command_stop=( $value )";; + (execreload) eval "service_command_reload=( $value )";; + (restart) [[ $value == 'always' ]] && service_respawn=1;; + esac + ;; + esac + done < "$1" +} + # Overloadable functions ## Start the service, write down the svc pid start() { @@ -241,12 +265,7 @@ start() { ## Usually just sends HUP reload() { (( service_running )) || return 3 - - if (( service_managed )); then - kill -n 1 "$service_pid" - else - kill -n "$service_reload_signal" "$service_pid" - fi + "${service_command_reload[@]}" } ## Stop the service @@ -262,7 +281,8 @@ stop() { else (( service_running )) || return 3 - nullexec kill -n "$service_stop_signal" "$service_pid" || return 1 + "${service_command_stop[@]}" || return 1 + pid_wait "$service_pid" || return 5 > "$service_stopped_flag" @@ -404,26 +424,43 @@ main() { break } done + + # Search for a systemd service too + for i in {/etc/systemd,/run/systemd,/lib/systemd,/usr/lib/systemd}/system/$1.service; do + [[ -f "$i" ]] && { + service_name=$1 + service_systemd=1 + service_config=$i + read_systemd_service "$i" + break + } + done fi - # Die if there is no such file + # Die if there is no service config file [[ "$service_config" ]] || die 19 "Service not found: $1" - - # Service name is the basename - service_name="${1##*/}" # Semi-hardcoded stuff svc_pidfile="$rundir/$service_name.pid" - # Get the service defaults - for p in "${cfg_path[@]/%//$service_name}"; do - [[ -f "$p" ]] && { - source "$p" || die 5 "Failed to read service defaults: $p" - } - done + # We can handle other people's service configs, poorly + if (( service_systemd )); then + # I'm pretty sure we'll need this + : + else + # Service name is the basename + service_name="${1##*/}" - # Get the service config - source -- "$service_config" "${@:3}" || die 7 "Failed to read the service config: $service_config" + # Get the service defaults + for p in "${cfg_path[@]/%//$service_name}"; do + [[ -f "$p" ]] && { + source "$p" || die 5 "Failed to read service defaults: $p" + } + done + + # Get the service config + source -- "$service_config" "${@:3}" || die 7 "Failed to read the service config: $service_config" + fi # Legacy [[ "$service_args" ]] && service_command=( "${service_command[@]}" "${service_args[@]}" ) @@ -460,6 +497,10 @@ main() { fi fi + # The stop and reload commands need the service pid + default service_command_stop kill -n "$service_stop_signal" "$service_pid" + default service_command_reload kill -n "$service_reload_signal" "$service_pid" + # Maybe the service is enabled? if [[ -f "$service_enabled_flag" ]]; then # Yay, it is!