From 124253e11b0664ab242df6ed9ae3f74473923cfb Mon Sep 17 00:00:00 2001 From: Darren 'Tadgy' Austin Date: Tue, 11 Oct 2022 00:56:24 +0100 Subject: [PATCH] Add some rc templates. --- templates/rc.d/rc.template | 54 ++++----- templates/rc.d/rc.template-daemon | 122 +++++++++++++++++++ templates/rc.d/rc.template-daemon-runuser | 135 ++++++++++++++++++++++ 3 files changed, 284 insertions(+), 27 deletions(-) create mode 100755 templates/rc.d/rc.template-daemon create mode 100755 templates/rc.d/rc.template-daemon-runuser diff --git a/templates/rc.d/rc.template b/templates/rc.d/rc.template index 0b8f119..d51222f 100755 --- a/templates/rc.d/rc.template +++ b/templates/rc.d/rc.template @@ -1,24 +1,24 @@ #!/bin/bash -# Version: 0.3.1 +# Version: 0.4.0 # Copyright (c) 2005-2022: # Darren 'Tadgy' Austin # Licensed under the terms of the GNU General Public License version 3. -EXEC="%BUILD_PREFIX%/" -ARGS=() -PIDFILE="" +SERVICE_EXEC="%BUILD_PREFIX%/EDITME" +SERVICE_ARGS=('EDITME') +SERVICE_PIDFILE="EDITME" # Allow configuration in /etc/default to override. # Additional available variables: -# ENVIRONMENT=() # Extra environment passed to $EXEC. Must be an array. -# EXTRA_ARGS=() # Extra arguments passed to $EXEC. Must be an array. -# SLAY_DELAY="" # Delay between the SIGTERM and SIGKILL on a 'stop'. Default: 2s. -# RESTART_DELAY="" # Delay between stopping and starting on a 'restart'. Default: 2s. +# SERVICE_ENVIRONMENT=() # Extra environment passed to $SERVICE_EXEC. Must be an array. +# SERVICE_EXTRA_ARGS=() # Extra arguments passed to $SERVICE_EXEC. Must be an array. +# SLAY_DELAY="" # Delay between the SIGTERM and SIGKILL on a 'stop'. Default: 2s. +# RESTART_DELAY="" # Delay between stopping and starting on a 'restart'. Default: 2s. # shellcheck disable=SC1090 [[ -e "/etc/default/${0##*rc.}" ]] && { source "/etc/default/${0##*rc.}" || return 1 2>/dev/null || exit 1; } error() { - printf "%s: %s: %s\\n" "${BASH_SOURCE[0]##*/}" "${EXEC##*/}" "$*" >&2 + printf "%s: %s\\n" "${BASH_SOURCE[0]##*/}" "$*" >&2 } checkconfigured() { @@ -31,40 +31,40 @@ checkconfigured() { checkstatus() { # shellcheck disable=SC2155 - local RUNPIDS="$({ pgrep -f "$EXEC"; pgrep -F "$PIDFILE" 2>/dev/null; } | sort -u )" + local RUNPIDS="$({ pgrep -f "$SERVICE_EXEC"; pgrep -F "$SERVICE_PIDFILE" 2>/dev/null; } | sort -u )" if [[ -n "$RUNPIDS" ]]; then - printf "%s: %s: %s" "${BASH_SOURCE[0]##*/}" "${EXEC##*/}" "running" - if [[ -n "$PIDFILE" ]]; then - if [[ ! -e "$PIDFILE" ]]; then + printf "%s: %s: %s" "${BASH_SOURCE[0]##*/}" "${SERVICE_EXEC##*/}" "running" + if [[ -n "$SERVICE_PIDFILE" ]]; then + if [[ ! -e "$SERVICE_PIDFILE" ]]; then printf "%s" ", but .pid file does not exist" - elif ! grep "\<$(<"$PIDFILE")\>" <<<"$RUNPIDS" >/dev/null 2>&1; then + elif ! grep "\<$(<"$SERVICE_PIDFILE")\>" <<<"$RUNPIDS" >/dev/null 2>&1; then printf "%s" ", but .pid file is stale" fi fi printf "\\n" else - printf "%s: %s: %s\\n" "${BASH_SOURCE[0]##*/}" "${EXEC##*/}" "stopped" + printf "%s: %s: %s\\n" "${BASH_SOURCE[0]##*/}" "${SERVICE_EXEC##*/}" "stopped" return 1 fi return 0 } startdaemon() { - if [[ ! -e "$EXEC" ]]; then - error "not found" + if [[ ! -e "$SERVICE_EXEC" ]]; then + error "not found: $SERVICE_EXEC" return 2 - elif [[ ! -x "$EXEC" ]]; then - error "not executable" + elif [[ ! -x "$SERVICE_EXEC" ]]; then + error "not executable: $SERVICE_EXEC" return 2 elif ! checkconfigured; then error "not started - pre-start checks failed" return 2 fi # shellcheck disable=SC2048,SC2086 - ${ENVIRONMENT:+declare ${ENVIRONMENT[*]};} "$EXEC" ${ARGS[*]} ${EXTRA_ARGS[*]} + ${SERVICE_ENVIRONMENT:+declare ${SERVICE_ENVIRONMENT[*]};} "$SERVICE_EXEC" ${SERVICE_ARGS[*]} ${SERVICE_EXTRA_ARGS[*]} # shellcheck disable=SC2181 if (( $? != 0 )); then - error "error starting daemon" + error "error starting '${SERVICE_EXEC##*/}'" return 2 else return 0 @@ -72,15 +72,15 @@ startdaemon() { } stopdaemon() { - kill -TERM "$(pgrep -f "$EXEC" | tr $'\n' " ")" >/dev/null 2>&1 - [[ -e "$PIDFILE" ]] && { + kill -TERM "$(pgrep -f "$SERVICE_EXEC" | tr $'\n' " ")" >/dev/null 2>&1 + [[ -e "$SERVICE_PIDFILE" ]] && { sleep 0.5 - kill -TERM "$(<"$PIDFILE")" >/dev/null 2>&1 + kill -TERM "$(<"$SERVICE_PIDFILE")" >/dev/null 2>&1 } sleep "${SLAY_DELAY:-2}" checkstatus >/dev/null && { error "failed to stop gracefully - slaying" - kill -KILL "$({ cat "$PIDFILE"; pgrep -f "$EXEC"; } 2>/dev/null | sort -u | tr $'\n' " ")" >/dev/null 2>&1 + kill -KILL "$({ cat "$SERVICE_PIDFILE"; pgrep -f "$SERVICE_EXEC"; } 2>/dev/null | sort -u | tr $'\n' " ")" >/dev/null 2>&1 } return 0 } @@ -88,7 +88,7 @@ stopdaemon() { case "$1" in 'start') if checkstatus >/dev/null; then - error "already running" + error "${SERVICE_EXEC##*/}: already running" printf " %s\\n" "Try: ${BASH_SOURCE[0]} status" >&2 RET=1 else @@ -98,7 +98,7 @@ case "$1" in ;; 'stop') if ! checkstatus >/dev/null; then - error "not running" + error "${SERVICE_EXEC##*/}: not running" printf " %s\\n" "Try: ${BASH_SOURCE[0]} status" >&2 RET=1 else diff --git a/templates/rc.d/rc.template-daemon b/templates/rc.d/rc.template-daemon new file mode 100755 index 0000000..3b9e43e --- /dev/null +++ b/templates/rc.d/rc.template-daemon @@ -0,0 +1,122 @@ +#!/bin/bash +# Version: 0.4.0-daemon +# Copyright (c) 2005-2022: +# Darren 'Tadgy' Austin +# Licensed under the terms of the GNU General Public License version 3. + +SERVICE_EXEC="%BUILD_PREFIX%/EDITME" +SERVICE_ARGS=('EDITME') +DAEMON_EXEC="/usr/bin/daemon" +DAEMON_ARGS=('-N' '-n' "${0##*rc.}" '-r' '-a' '60' '-A' '5' '-L' '3600' '-M' '3' '-l' 'daemon.err' '-b' 'daemon.debug' '-o' 'daemon.info' '--') + +# Allow configuration in /etc/default to override. +# Additional available variables: +# SERVICE_ENVIRONMENT=() # Extra environment passed to $SERVICE_EXEC. Must be an array. +# SERVICE_EXTRA_ARGS=() # Extra arguments passed to $SERVICE_EXEC. Must be an array. +# DAEMON_ENVIRONMENT=() # Extra environment passed to $DAEMON_EXEC. Must be an array. +# DAEMON_EXTRA_ARGS=() # Extra arguments passed to $DAEMON_EXEC. Must be an array. +# SLAY_DELAY="" # Delay between the SIGTERM and SIGKILL on a 'stop'. Default: 2s. +# RESTART_DELAY="" # Delay between stopping and starting on a 'restart'. Default: 2s. +# shellcheck disable=SC1090 +[[ -e "/etc/default/${0##*rc.}" ]] && { source "/etc/default/${0##*rc.}" || return 1 2>/dev/null || exit 1; } + +error() { + printf "%s: %s\\n" "${BASH_SOURCE[0]##*/}" "$*" >&2 +} + +checkconfigured() { + # This function can be used to perform any pre-start tests; hopfully to insure the daemon + # can start correctly, before actually trying to start it. A return value of 0 means the + # tests were passed and the daemon should be started. Any other value prevents the + # daemon from being started, and an error message will be emitted. + return 0 +} + +checkstatus() { + if "$DAEMON_EXEC" --running -n "${0##*rc.}"; then + printf "%s: %s: %s\\n" "${BASH_SOURCE[0]##*/}" "${SERVICE_EXEC##*/}" "running" + return 0 + else + printf "%s: %s: %s\\n" "${BASH_SOURCE[0]##*/}" "${SERVICE_EXEC##*/}" "stopped" + return 1 + fi +} + +startdaemon() { + local EXEC + for EXEC in "$SERVICE_EXEC" "$DAEMON_EXEC"; do + if [[ ! -e "$EXEC" ]]; then + error "not found: $EXEC" + return 2 + elif [[ ! -x "$EXEC" ]]; then + error "not executable: $EXEC" + return 2 + fi + done + checkconfigured || { + error "not started - pre-start checks failed" + return 2 + } + # shellcheck disable=SC2048,SC2046,SC2086 + ${DAEMON_ENVIRONMENT:+declare ${DAEMON_ENVIRONMENT[*]};} "$DAEMON_EXEC" ${DAEMON_ARGS[*]} ${DAEMON_EXTRA_ARGS[*]} \ + $(printf -- "-e \"%s\" " "${SERVICE_ENVIRONMENT[@]}") "$SERVICE_EXEC" ${SERVICE_ARGS[*]} ${SERVICE_EXTRA_ARGS[*]} + # shellcheck disable=SC2181 + if (( $? != 0 )); then + error "error starting '${DAEMON_EXEC##*/}:'" + return 2 + else + return 0 + fi +} + +stopdaemon() { + "$DAEMON_EXEC" -n "${0##*rc.}" --stop 2>/dev/null + sleep "${SLAY_DELAY:-2}" + checkstatus >/dev/null && { + error "failed to stop gracefully - slaying" + "$DAEMON_EXEC" -n "${0##*rc.}" --signal=kill 2>/dev/null + } + return 0 +} + +case "$1" in + 'start') + if checkstatus >/dev/null; then + error "${SERVICE_EXEC##*/}: already running" + printf " %s\\n" "Try: ${BASH_SOURCE[0]} status" >&2 + RET=1 + else + startdaemon + RET=$? + fi + ;; + 'stop') + if ! checkstatus >/dev/null; then + error "${SERVICE_EXEC##*/}: not running" + printf " %s\\n" "Try: ${BASH_SOURCE[0]} status" >&2 + RET=1 + else + stopdaemon + RET=$? + fi + ;; + 'restart') + checkstatus >/dev/null + (( $? != 3 )) && { + stopdaemon >/dev/null 2>&1 + sleep "${RESTART_DELAY:-2}" + } + startdaemon + RET=$? + ;; + 'status') + checkstatus + RET=$? + ;; + *) + printf "%s\\n" "Usage: ${BASH_SOURCE[0]} " >&2 + RET=1 + ;; +esac + +return $RET 2>/dev/null || exit $RET diff --git a/templates/rc.d/rc.template-daemon-runuser b/templates/rc.d/rc.template-daemon-runuser new file mode 100755 index 0000000..98418ee --- /dev/null +++ b/templates/rc.d/rc.template-daemon-runuser @@ -0,0 +1,135 @@ +#!/bin/bash +# Version: 0.4.0-daemon-runuser +# Copyright (c) 2005-2022: +# Darren 'Tadgy' Austin +# Licensed under the terms of the GNU General Public License version 3. + +SERVICE_EXEC="%BUILD_PREFIX%/EDITME" +SERVICE_ARGS=('EDITME') +SERVICE_RUNUSER="EDITME" +DAEMON_EXEC="/usr/bin/daemon" +DAEMON_ARGS=('-N' '-n' "${0##*rc.}" '-r' '-a' '60' '-A' '5' '-L' '3600' '-M' '3' '-l' 'daemon.err' '-b' 'daemon.debug' '-o' 'daemon.info' '--') + +# Allow configuration in /etc/default to override. +# Additional available variables: +# SERVICE_ENVIRONMENT=() # Extra environment passed to $SERVICE_EXEC. Must be an array. +# SERVICE_EXTRA_ARGS=() # Extra arguments passed to $SERVICE_EXEC. Must be an array. +# SERVICE_RUNUSER="" # Username to run the service as. Default: User who starts the script. +# DAEMON_ENVIRONMENT=() # Extra environment passed to $DAEMON_EXEC. Must be an array. +# DAEMON_EXTRA_ARGS=() # Extra arguments passed to $DAEMON_EXEC. Must be an array. +# SLAY_DELAY="" # Delay between the SIGTERM and SIGKILL on a 'stop'. Default: 2s. +# RESTART_DELAY="" # Delay between stopping and starting on a 'restart'. Default: 2s. +# shellcheck disable=SC1090 +[[ -e "/etc/default/${0##*rc.}" ]] && { source "/etc/default/${0##*rc.}" || return 1 2>/dev/null || exit 1; } + +error() { + printf "%s: %s\\n" "${BASH_SOURCE[0]##*/}" "$*" >&2 +} + +checkconfigured() { + # This function can be used to perform any pre-start tests; hopfully to insure the daemon + # can start correctly, before actually trying to start it. A return value of 0 means the + # tests were passed and the daemon should be started. Any other value prevents the + # daemon from being started, and an error message will be emitted. + return 0 +} + +checkstatus() { + id "${SERVICE_RUNUSER:-$(whoami)}" >/dev/null 2>&1 || { + error "invalid user: ${SERVICE_RUNUSER:-$(whoami)}" + return 2 + } + if su - "${SERVICE_RUNUSER:-$(whoami)}" -c "\"$DAEMON_EXEC\" --running -n \"${0##*rc.}\""; then + printf "%s: %s: %s\\n" "${BASH_SOURCE[0]##*/}" "${SERVICE_EXEC##*/}" "running" + return 0 + else + printf "%s: %s: %s\\n" "${BASH_SOURCE[0]##*/}" "${SERVICE_EXEC##*/}" "stopped" + return 1 + fi +} + +startdaemon() { + local EXEC + for EXEC in "$SERVICE_EXEC" "$DAEMON_EXEC"; do + if [[ ! -e "$EXEC" ]]; then + error "not found: $EXEC" + return 2 + elif [[ ! -x "$EXEC" ]]; then + error "not executable: $EXEC" + return 2 + fi + done + id "${SERVICE_RUNUSER:-$(whoami)}" >/dev/null 2>&1 || { + error "invalid user: ${SERVICE_RUNUSER:-$(whoami)}" + return 2 + } + checkconfigured || { + error "not started - pre-start checks failed" + return 2 + } + su - "${SERVICE_RUNUSER:-$(whoami)}" -c "${DAEMON_ENVIRONMENT:+declare ${DAEMON_ENVIRONMENT[*]};} \"$DAEMON_EXEC\" ${DAEMON_ARGS[*]} \ + ${DAEMON_EXTRA_ARGS[*]} $(printf -- "-e \"%s\" " "${SERVICE_ENVIRONMENT[@]}") \"$SERVICE_EXEC\" ${SERVICE_ARGS[*]} ${SERVICE_EXTRA_ARGS[*]}" + # shellcheck disable=SC2181 + if (( $? != 0 )); then + error "error starting '${DAEMON_EXEC##*/}'" + return 2 + else + return 0 + fi +} + +stopdaemon() { + id "${SERVICE_RUNUSER:-$(whoami)}" >/dev/null 2>&1 || { + error "invalid user: ${SERVICE_RUNUSER:-$(whoami)}" + return 2 + } + su - "${SERVICE_RUNUSER:-$(whoami)}" -c "\"$DAEMON_EXEC\" -n \"${0##*rc.}\" --stop 2>/dev/null" + sleep "${SLAY_DELAY:-2}" + checkstatus >/dev/null && { + error "failed to stop gracefully - slaying" + su - "${SERVICE_RUNUSER:-$(whoami)}" -c "\"$DAEMON_EXEC\" -n \"${0##*rc.}\" --signal=kill 2>/dev/null" + } + return 0 +} + +case "$1" in + 'start') + if checkstatus >/dev/null; then + error "${SERVICE_EXEC##*/}: already running" + printf " %s\\n" "Try: ${BASH_SOURCE[0]} status" >&2 + RET=1 + else + startdaemon + RET=$? + fi + ;; + 'stop') + if ! checkstatus >/dev/null; then + error "${SERVICE_EXEC##*/}: not running" + printf " %s\\n" "Try: ${BASH_SOURCE[0]} status" >&2 + RET=1 + else + stopdaemon + RET=$? + fi + ;; + 'restart') + checkstatus >/dev/null + (( $? != 3 )) && { + stopdaemon >/dev/null 2>&1 + sleep "${RESTART_DELAY:-2}" + } + startdaemon + RET=$? + ;; + 'status') + checkstatus + RET=$? + ;; + *) + printf "%s\\n" "Usage: ${BASH_SOURCE[0]} " >&2 + RET=1 + ;; +esac + +return $RET 2>/dev/null || exit $RET