Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 406eb2cca6 | |||
| d240dbcb39 | |||
| 6959074db1 | |||
| 931a5f45cb | |||
| 90062cb1fa | |||
| 54a6c3f17f | |||
| 2a494bcdc4 | |||
| 2e63f5b5a0 | |||
|
95ebba50e3
|
|||
|
0506889700
|
|||
|
59d2325f73
|
|||
|
0477798c9e
|
|||
|
750cde1aa1
|
|||
|
16f8b86d1b
|
|||
|
3bd632a39b
|
|||
|
b17e0376bc
|
|||
|
250654bfdb
|
|||
|
edbabda2df
|
|||
|
9d13a0576b
|
|||
|
27bcdec74f
|
|||
|
6815946574
|
|||
|
f4e12ec2e1
|
|||
|
533d0e6250
|
|||
|
3a69fa0a14
|
|||
|
b9aad0805e
|
|||
|
f27c7d4a1b
|
|||
|
18cc57a58b
|
|||
|
ecfe06d32f
|
|||
|
35ab839e35
|
|||
|
84077fd97a
|
|||
|
938d7a8c47
|
|||
|
bdff302a2b
|
1
LICENSE
1
LICENSE
@@ -1,5 +1,6 @@
|
||||
Copyright 2020 Dave Eddy <dave@daveeddy.com> (https://www.daveeddy.com)
|
||||
Forked as a contribution to Artix Linux by linuxer <linuxer@artixlinux.org>
|
||||
Forked by nikolar <nikolar@artixlinux.org> (24. 12. 2022)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
116
README.md
116
README.md
@@ -1,4 +1,114 @@
|
||||
# Runit-Service-Manager
|
||||
# `rsm` - Runit Service Manager
|
||||
|
||||
This is the CLI Runit Service Manager {rsv}, forked from Void Service Manager {vsv} https://github.com/bahamas10/vsv/blob/master/vsv
|
||||
|
||||
- This is the CLI Runit Service Manager {rsm}, forked from Void Service Manager {vsv} https://github.com/bahamas10/vsv/blob/master/vsv
|
||||
|
||||
- Terminal Commands are exactly the same as sv, but produces a beautified layout.
|
||||
|
||||

|
||||
|
||||
## Manage and view runit services.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Quick Examples:
|
||||
|
||||
- `rsm` - show all services
|
||||
- `rsm status` - same as above
|
||||
- `rsm stop <svc>` - stop a service
|
||||
- `rsm start <svc>` - start a service
|
||||
- `rsm restart <svc>` - restart a service, or start service right after `rsm enable <svc>`
|
||||
- `rsm enable <svc>` - enable a service (autostart at boot)
|
||||
- `rsm disable <svc>` - disable a service (no autostart at boot)
|
||||
- `rsm hup <svc>` - refresh a service (`SIGHUP`)
|
||||
- `rsm logs <svc>` or `rsm alllogs <svc>` - lists all logs for a service (access and error)
|
||||
- `rsm errorlogs <svc>` - lists all error logs for a service
|
||||
|
||||
Status:
|
||||
|
||||
The `status` subcommand has the following fields:
|
||||
|
||||
- `SERVICE` - the service (directory) name.
|
||||
- `STATE` - the service state: output from `.../$service/supervise/stat`.
|
||||
- `ENABLED` - if the service is enabled (lacks the `.../$service/down` file).
|
||||
- `PID` - the pid of the process being monitored.
|
||||
- `COMMAND` - arg0 from the pid being monitored (first field of `/proc/$pid/cmdline`.
|
||||
- `TIME` - time the service has been in whatever state it is in.
|
||||
|
||||
Command Usage:
|
||||
|
||||
[rsm] Manage and view runit services
|
||||
[rsm] Made specifically for Void Linux but should work anywhere
|
||||
[rsm] Author: Dave Eddy <dave@daveeddy.com> (bahamas10)
|
||||
|
||||
USAGE:
|
||||
rsm [OPTIONS] [SUBCOMMAND] [<ARGS>]
|
||||
rsm [-u] [-d <dir>] [-h] [-t] [SUBCOMMAND] [...]
|
||||
|
||||
OPTIONS:
|
||||
-c <yes|no|auto> Enable/disable color output, defaults to auto
|
||||
-d <dir> Directory to look into, defaults to env SVDIR or /var/service if unset
|
||||
-h Print this message and exit
|
||||
-l Show log processes, this is a shortcut for 'status -l'
|
||||
-t Tree view, this is a shortcut for 'status -t'
|
||||
-u User mode, this is a shortcut for '-d ~/runit/service'
|
||||
-v Increase verbosity
|
||||
-V Print the version number and exit
|
||||
|
||||
ENV:
|
||||
SVDIR The directory to use, passed to the 'sv' command, can
|
||||
be overridden with '-d <dir>'
|
||||
|
||||
SUBCOMMANDS:
|
||||
status [-lt] [filter] Default subcommand, show process status
|
||||
'-t' enables tree mode (process tree)
|
||||
'-l' enables log mode (show log processes)
|
||||
'filter' is an optional string to match service names against
|
||||
|
||||
enable <svc> [...] Enable the service(s) (remove the "down" file, does not start service)
|
||||
|
||||
disable <svc> [...] Disable the service(s) (create the "down" file, does not stop service)
|
||||
|
||||
Any other subcommand gets passed directly to the 'sv' command, see sv(1) for the
|
||||
full list of subcommands and information about what each does specifically.
|
||||
Common subcommands:
|
||||
|
||||
start <service> Start the service
|
||||
stop <service> Stop the service
|
||||
restart <service> Restart the service
|
||||
reload <service> Reload the service (send SIGHUP)
|
||||
|
||||
EXAMPLES:
|
||||
rsm Show service status in /var/service
|
||||
rsm status Same as above
|
||||
rsm -t Show service status + pstree output
|
||||
rsm status -t Same as above
|
||||
rsm status tty Show service status for any service that matches tty*
|
||||
rsm check uuidd Check the uuidd svc, wrapper for 'sv check uuidd'
|
||||
rsm restart sshd Restart sshd, wrapper for 'sv restart sshd'
|
||||
rsm -u Show service status in ~/runit/service
|
||||
rsm -u restart ssh-agent Restart ssh-agent in ~/runit/service/ssh-agent
|
||||
|
||||
Syntax
|
||||
------
|
||||
|
||||
This project uses:
|
||||
|
||||
- Bash Style Guide: https://www.daveeddy.com/bash/
|
||||
- `shellcheck`: https://github.com/koalaman/shellcheck
|
||||
|
||||
```
|
||||
$ make check
|
||||
shellcheck rsm
|
||||
```
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
- You'll have to change the `$SVDIR` and `$RUNSVDIR` variables to your distro's
|
||||
configuration to make the autocompletion work properly.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT License
|
||||
|
||||
33
autocompletion/bash/rsm
Normal file
33
autocompletion/bash/rsm
Normal file
@@ -0,0 +1,33 @@
|
||||
#/usr/bin/env bash
|
||||
|
||||
_rsm_completions() {
|
||||
SVDIR='/etc/runit/sv'
|
||||
RUNSVDIR='/etc/runit/runsvdir/default'
|
||||
|
||||
if [ "${#COMP_WORDS[@]}" -eq 3 ]
|
||||
then
|
||||
cmd="${COMP_WORDS[1]}"
|
||||
# notify-send "$cmd"
|
||||
case "$cmd" in
|
||||
status|enable|logs|alllogs|errorlogs)
|
||||
COMPREPLY=($(compgen -W "$(ls -1 $SVDIR | xargs echo)" \
|
||||
"${COMP_WORDS[2]}"))
|
||||
;;
|
||||
disable|start|stop|restart|reload)
|
||||
COMPREPLY=($(compgen -W "$(ls -1 $RUNSVDIR | xargs echo)" \
|
||||
"${COMP_WORDS[2]}"))
|
||||
;;
|
||||
|
||||
esac
|
||||
elif [ "${#COMP_WORDS[@]}" -eq 2 ]
|
||||
then
|
||||
COMPREPLY=($(compgen -W "status enable disable start \
|
||||
stop restart reload logs alllogs errorlogs" "${COMP_WORDS[1]}"))
|
||||
else
|
||||
COMPREPLY=('wtf')
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -F _rsm_completions rsm
|
||||
129
autocompletion/zsh/_rsm
Normal file
129
autocompletion/zsh/_rsm
Normal file
@@ -0,0 +1,129 @@
|
||||
#compdef rsm
|
||||
|
||||
_rsm_all_services() {
|
||||
local IFS=$'\n'
|
||||
# Extract names and email addresses from gpg --list-keys
|
||||
_values 'Active services' $(ls -1 "$SVDIR")
|
||||
}
|
||||
|
||||
_rsm_active_services() {
|
||||
local IFS=$'\n'
|
||||
# Extract names and email addresses from gpg --list-keys
|
||||
_values 'Active services' $(ls -1 "$RUNSVDIR")
|
||||
}
|
||||
|
||||
_rsm_common_args() {
|
||||
_arguments : \
|
||||
'-c[Enable/disable color output, defaults to auto]:Enable color:(yes no auto)' \
|
||||
'-d[Directory to look into, defaults to env SVDIR or /run/runit/service is unset]:directory:_files -/' \
|
||||
'-h[Print this message and exit]' \
|
||||
"-l[Show log processes, this is a shortcut for 'status -l']" \
|
||||
"-t[Tree view, this is a shortcut for 'status -t']" \
|
||||
"-u[User mode, this is a shortcut for '-d ~/runit/service']" \
|
||||
'-v[Increase verbosity]' \
|
||||
'-V[Print the version number and exit]'
|
||||
}
|
||||
|
||||
_rsm_subcommands() {
|
||||
local subcommands=(
|
||||
'status:Default subcommand, show process status'
|
||||
'enable:Enable the service(s) (remove the "down" file, does not start service'
|
||||
'disable:Disable the service(s) (create the "down" file, does not stop service'
|
||||
'start:Start the service'
|
||||
'stop:Stop the service'
|
||||
'restart:Restart the service'
|
||||
'reload:Reload the service (send SIGHUP)'
|
||||
"logs:Outputs the service's logfilenames and their access & error logs from /var/log/<serice>/"
|
||||
'alllogs:The same like logs <service>'
|
||||
"errorlogs:Outputs the service's logfilenames and their errorlogs from /var/log/<service>/"
|
||||
)
|
||||
_describe -t commands 'rsm' subcommands
|
||||
}
|
||||
|
||||
_rsm() {
|
||||
local -a args subcommands cmd havesubcmd tmpwords lastcmd SVDIR RUNSVDIR
|
||||
# NOTE Change there variables to your configuration
|
||||
SVDIR='/etc/runit/sv'
|
||||
RUNSVDIR='/etc/runit/runsvdir/default'
|
||||
havesubcmd=NONE
|
||||
tmpwords=("${words[@]}")
|
||||
|
||||
while true
|
||||
do
|
||||
cmd="${tmpwords[2]}"
|
||||
case "$cmd" in
|
||||
-h|-V)
|
||||
# Help and version options override everything else
|
||||
return
|
||||
;;
|
||||
-c)
|
||||
havesubcmd=OPTARG
|
||||
shift tmpwords
|
||||
;;
|
||||
-d)
|
||||
havesubcmd=OPTARG
|
||||
shift tmpwords
|
||||
;;
|
||||
-*)
|
||||
havesubcmd=OPT
|
||||
shift tmpwords
|
||||
;;
|
||||
"")
|
||||
break
|
||||
;;
|
||||
*)
|
||||
if [ "$havesubcmd" = OPTARG ]
|
||||
then
|
||||
if [ "$lastcmd" = "-d" ]
|
||||
then
|
||||
SVDIR="$cmd"
|
||||
fi
|
||||
havesubcmd=OPT
|
||||
shift tmpwords
|
||||
else
|
||||
havesubcmd=SUBCMD
|
||||
break
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
lastcmd="$cmd"
|
||||
done
|
||||
|
||||
if [ "$havesubcmd" = SUBCMD ]
|
||||
then
|
||||
words=("${tmpwords[@]}")
|
||||
|
||||
cmd="${words[2]}"
|
||||
# CURRENT=$((CURRENT - 1))
|
||||
shift words
|
||||
case "$cmd" in
|
||||
status)
|
||||
_rsm_active_services
|
||||
_arguments : \
|
||||
'-t[Enables tree mode (process tree)]' \
|
||||
'-l[Enables log mode (show log processes)]'
|
||||
;;
|
||||
enable|logs|alllogs|errorlogs)
|
||||
_rsm_all_services
|
||||
;;
|
||||
disable|start|stop|restart|reload)
|
||||
_rsm_active_services
|
||||
;;
|
||||
*)
|
||||
_rsm_subcommands
|
||||
;;
|
||||
esac
|
||||
else
|
||||
if [ "$havesubcmd" = NONE ] || [ "$havesubcmd" = OPT ]
|
||||
then
|
||||
_rsm_subcommands
|
||||
_rsm_common_args
|
||||
elif [ "$havesubcmd" = OPTARG ]
|
||||
then
|
||||
_rsm_common_args
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
_rsm
|
||||
709
rsm
Executable file
709
rsm
Executable file
@@ -0,0 +1,709 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Artix Linux service manager (runit)
|
||||
# Forked and further developed, by: nikolar <nikolar@artixlinux.org>
|
||||
# Fork Date: December 24, 2022
|
||||
#
|
||||
# Forked and further developed, by: linuxer <linuxer@artixlinux.org>
|
||||
# Fork Date: August 15, 2020 as rsv
|
||||
# Renamed and further developed as rsm from: January 10, 2021
|
||||
#
|
||||
# Original Author (vsv): Dave Eddy <dave@daveeddy.com>
|
||||
# Date: August 29, 2018
|
||||
# License: MIT
|
||||
|
||||
RSM_VERSION='v1.4.9'
|
||||
|
||||
export RUNSVDIR=${RUNSVDIR:-/etc/runit/runsvdir}
|
||||
export SVDIR=${SVDIR:-/run/runit/service/}
|
||||
export LOGDIR="/var/log/"
|
||||
export RSVDIR="/run/runit/service/"
|
||||
export FLDIR=${FLDIR:-/etc/runit/sv/}
|
||||
|
||||
|
||||
charup='✔'
|
||||
chardown='X'
|
||||
charunknown='?'
|
||||
progname=${0##*/}
|
||||
num_re='^-?[0-9]+$'
|
||||
svc_re='^[a-zA-Z0-9_\.-]+$'
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
# Get time in a human format, like 1 hour ago, 7 minutes ago, etc.
|
||||
human() {
|
||||
local seconds=$1
|
||||
if ((seconds < 0)); then
|
||||
((seconds *= -1))
|
||||
fi
|
||||
|
||||
local times=(
|
||||
$((seconds / 60 / 60 / 24 / 365)) # years
|
||||
$((seconds / 60 / 60 / 24 / 30)) # months
|
||||
$((seconds / 60 / 60 / 24 / 7)) # weeks
|
||||
$((seconds / 60 / 60 / 24)) # days
|
||||
$((seconds / 60 / 60)) # hours
|
||||
$((seconds / 60)) # minutes
|
||||
$((seconds)) # seconds
|
||||
)
|
||||
local names=(year month week day hour minute second)
|
||||
|
||||
local i
|
||||
for ((i = 0; i < ${#names[@]}; i++)); do
|
||||
if ((${times[$i]} > 1)); then
|
||||
echo "${times[$i]} ${names[$i]}s"
|
||||
return
|
||||
elif ((${times[$i]} == 1)); then
|
||||
echo "${times[$i]} ${names[$i]}"
|
||||
return
|
||||
fi
|
||||
done
|
||||
echo '0 seconds'
|
||||
}
|
||||
|
||||
# enable or disable colors based on the argument given, i.e.:
|
||||
# setcolors on # colors on
|
||||
# setcolors off # colors off
|
||||
# setcolors auto # colors on or off depending on environment
|
||||
setcolors() {
|
||||
local opt=$1
|
||||
local colors
|
||||
|
||||
if [[ $opt == auto ]]; then
|
||||
# no colors if stdout is not a TTY
|
||||
if [[ ! -t 1 ]]; then
|
||||
opt='off'
|
||||
else
|
||||
# stdout is a tty, check tput capability for colors
|
||||
colors=$(tput colors 2>/dev/null || echo -1)
|
||||
if ! [[ $colors =~ $num_re ]]; then
|
||||
fatal "failed to parse output of \`tput colors\` ($colors)"
|
||||
fi
|
||||
|
||||
if ((colors >= 8)); then
|
||||
opt='on'
|
||||
else
|
||||
opt='off'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$opt" in
|
||||
on|yes|true)
|
||||
colorred=$(tput setaf 1)
|
||||
colorgreen=$(tput setaf 2)
|
||||
coloryellow=$(tput setaf 3)
|
||||
colorblue=$(tput setaf 4)
|
||||
colormagenta=$(tput setaf 5)
|
||||
colorcyan=$(tput setaf 6)
|
||||
#colorwhite=$(tput setaf 7)
|
||||
colorgray=$(tput setaf 8)
|
||||
colorbold=$(tput bold)
|
||||
colorreset=$(tput sgr0)
|
||||
;;
|
||||
off|no|false)
|
||||
colorred=
|
||||
colorgreen=
|
||||
coloryellow=
|
||||
colormagenta=
|
||||
colorcyan=
|
||||
#colorwhite=
|
||||
colorgray=
|
||||
colorbold=
|
||||
colorreset=
|
||||
;;
|
||||
*)
|
||||
echo "unknown color option: '$opt'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
usage() {
|
||||
local cr=$colorreset
|
||||
local logo
|
||||
|
||||
logo=$(getlogo)
|
||||
|
||||
cat <<EOF
|
||||
$colormagenta ______ ____ __ __
|
||||
$colormagenta | | \ \ / ___\ | \/ | $colorgreen Runit Service Manager for Artix Linux ($RSM_VERSION)
|
||||
$colormagenta | |_/ / \____ | || | $colorgreen Source: https://gitea.artixlinux.org/nikolar/Runit-Service-Manager
|
||||
$colormagenta | | \ \ \____/ | || | $colorgreen MIT License
|
||||
|
||||
$logo $colorblue Manage and view runit services
|
||||
$logo $colorblue Made specifically for Void Linux but should work anywhere
|
||||
$logo $colorblue Author: Dave Eddy <dave@daveeddy.com> (bahamas10)
|
||||
$logo $colorblue Forked specifically for Artix Linux and renamed to rsm, for further development
|
||||
$logo $colorblue Maitained by nikolar <nikolar@artixlinux.org> (nikolar in #artix)
|
||||
|
||||
${coloryellow}USAGE:${colorgreen}
|
||||
$progname [OPTIONS] [SUBCOMMAND] [<ARGS>]
|
||||
$progname [-u] [-d <dir>] [-h] [-t] [SUBCOMMAND] [...]
|
||||
|
||||
${coloryellow}OPTIONS:${colorgreen}
|
||||
${colorgreen}-c <yes|no|auto> $cr Enable/disable color output, defaults to auto
|
||||
${colorgreen}-d <dir> $cr Directory to look into, defaults to env SVDIR or /run/runit/service is unset
|
||||
${colorgreen}-h $cr Print this message and exit
|
||||
${colorgreen}-l $cr Show log processes, this is a shortcut for 'status -l'
|
||||
${colorgreen}-t $cr Tree view, this is a shortcut for 'status -t'
|
||||
${colorgreen}-u $cr User mode, this is a shortcut for '-d ~/runit/service'
|
||||
${colorgreen}-v $cr Increase verbosity
|
||||
${colorgreen}-V $cr Print the version number and exit
|
||||
|
||||
${coloryellow}ENV:${colorgreen}
|
||||
SVDIR $cr The directory to use, passed to the 'sv' command, can
|
||||
be overridden with '-d <dir>'
|
||||
|
||||
${coloryellow}SUBCOMMANDS:${colorgreen}
|
||||
status [-lt] [filter] $cr Default subcommand, show process status
|
||||
$cr '-t' enables tree mode (process tree)
|
||||
$cr '-l' enables log mode (show log processes)
|
||||
$cr 'filter' is an optional string to match service names against
|
||||
${colorgreen}
|
||||
enable <svc> [...] $cr Enable the service(s) (remove the "down" file, does not start service)
|
||||
${colorgreen}
|
||||
disable <svc> [...] $cr Disable the service(s) (create the "down" file, does not stop service)
|
||||
|
||||
Any other subcommand gets passed directly to the 'sv' command, see sv(1) for the
|
||||
full list of subcommands and information about what each does specifically.
|
||||
Common subcommands:
|
||||
|
||||
${colorgreen}start <service> $cr Start the service
|
||||
${colorgreen}stop <service> $cr Stop the service
|
||||
${colorgreen}restart <service> $cr Restart the service
|
||||
${colorgreen}reload <service> $cr Reload the service (send SIGHUP)
|
||||
${colorgreen}logs <service> $cr Outputs the service's logfilenames and their access & error logs from /var/log/<serice>/
|
||||
${colorgreen}alllogs <service> $cr The same like logs <service>
|
||||
${colorgreen}errorlogs <service> $cr Outputs the service's logfilenames and their errorlogs from /var/log/<serice>/
|
||||
|
||||
|
||||
${coloryellow}EXAMPLES:${colorgreen}
|
||||
${colorgreen}$progname $cr Show service status in /var/service
|
||||
${colorgreen}$progname status $cr Same as above
|
||||
${colorgreen}$progname -t $cr Show service status + pstree output
|
||||
${colorgreen}$progname status -t $cr Same as above
|
||||
${colorgreen}$progname status tty $cr Show service status for any service that matches tty*
|
||||
${colorgreen}$progname check uuidd $cr Check the uuidd svc, wrapper for 'sv check uuidd'
|
||||
${colorgreen}$progname restart sshd $cr Restart sshd, wrapper for 'sv restart sshd'
|
||||
${colorgreen}$progname -u $cr Show service status in ~/runit/service
|
||||
${colorgreen}$progname -u restart ssh-agent $cr Restart ssh-agent in ~/runit/service/ssh-agent
|
||||
EOF
|
||||
}
|
||||
|
||||
verbose() {
|
||||
if ((verbosity > 0)); then
|
||||
echo '>' "$colorgray" "$@" "$colorreset" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
# print the logo with brackets colorized
|
||||
getlogo() {
|
||||
printf '%s[%s%s%s]%s' \
|
||||
"$colorcyan" \
|
||||
"$colormagenta" "$progname" \
|
||||
"$colorcyan" \
|
||||
"$colorreset"
|
||||
}
|
||||
|
||||
# prints a message
|
||||
msg() {
|
||||
local logo
|
||||
|
||||
logo=$(getlogo)
|
||||
|
||||
echo "$logo" "$colorblue$*$colorreset"
|
||||
}
|
||||
|
||||
# prints a fatal message and exists
|
||||
fatal() {
|
||||
echo "${colorred}FATAL:" "$@" "$colorreset"
|
||||
exit 2
|
||||
}
|
||||
|
||||
# rmsg - same as msg but colorized based on return status passed via $1
|
||||
rmsg() {
|
||||
local code=$1
|
||||
local logo
|
||||
local statuscolor
|
||||
|
||||
shift
|
||||
|
||||
logo=$(getlogo)
|
||||
|
||||
if ((code == 0)); then
|
||||
statuscolor=$colorgreen
|
||||
else
|
||||
statuscolor=$colorred
|
||||
fi
|
||||
|
||||
echo "$logo" "$statuscolor$*$colorreset"
|
||||
}
|
||||
|
||||
disable_message() {
|
||||
local svc=$1
|
||||
|
||||
echo "service $svc disabled by user $USER on $(date)"
|
||||
}
|
||||
|
||||
# process the status of a single service
|
||||
process_service() {
|
||||
local svc=$1
|
||||
local now=$2
|
||||
local pid when up msg char err enabled msgcolor enabledcolor \
|
||||
statecolor code islog prog down
|
||||
|
||||
islog=false
|
||||
if [[ $svc == */log ]]; then
|
||||
islog=true
|
||||
fi
|
||||
|
||||
# check permissions effectively
|
||||
err=$(sv status "$svc" 2>&1)
|
||||
code=$?
|
||||
|
||||
# get service state, or set error messages
|
||||
if ((code == 0)); then
|
||||
err=
|
||||
state=$(< "$svc/supervise/stat")
|
||||
pid=$(< "$svc/supervise/pid")
|
||||
when=$(stat --printf %Y "$svc/supervise/pid")
|
||||
up=$((now - when))
|
||||
msg=$(human "$up")
|
||||
|
||||
# if the service is enabled (wants up or wants down)
|
||||
if down=$(cat "$svc/down" 2>&1); then
|
||||
verbose "service disabled: $down"
|
||||
enabled='false'
|
||||
else
|
||||
enabled='true'
|
||||
fi
|
||||
|
||||
# color time if the service hasn't been up long
|
||||
if ((up < 5)); then
|
||||
msgcolor=$colorred
|
||||
elif ((up < 30)); then
|
||||
msgcolor=$coloryellow
|
||||
else
|
||||
msgcolor=$colorgray
|
||||
fi
|
||||
else
|
||||
pid=
|
||||
enabled=
|
||||
state='n/a'
|
||||
msg=${err##*: }
|
||||
msgcolor=$colorred
|
||||
fi
|
||||
|
||||
# sanity check pid
|
||||
if [[ -n $pid ]] && ! [[ $pid =~ $num_re ]]; then
|
||||
fatal "invalid pid: '$pid'"
|
||||
fi
|
||||
|
||||
# figure out character and color to use for status
|
||||
if [[ -n $err ]]; then
|
||||
char=$charunknown
|
||||
statecolor=$coloryellow
|
||||
elif [[ $state == 'run' ]]; then
|
||||
char=$charup
|
||||
statecolor=$colorgreen
|
||||
else
|
||||
char=$chardown
|
||||
statecolor=$colorred
|
||||
fi
|
||||
|
||||
# figure out enabled color
|
||||
if [[ $enabled == 'true' ]]; then
|
||||
enabledcolor=$colorgreen
|
||||
elif [[ $enabled == 'false' ]]; then
|
||||
enabledcolor=$colorred
|
||||
else
|
||||
enabledcolor=$coloryellow
|
||||
fi
|
||||
|
||||
# msg color
|
||||
if [[ -z $msgcolor ]]; then
|
||||
msgcolor=$colorgray
|
||||
fi
|
||||
|
||||
# format service name if it is a log service
|
||||
if $log && $islog && ! $tree; then
|
||||
svc='- log'
|
||||
fi
|
||||
|
||||
# figure out program name
|
||||
if [[ -n $pid ]]; then
|
||||
IFS= read -d $'\0' -r prog _ < /proc/$pid/cmdline
|
||||
prog=${prog##*/}
|
||||
prog=${prog:0:17}
|
||||
fi
|
||||
|
||||
# print service line
|
||||
printf ' %s%s%s %s%-20s%s %s%-7s%s %s%-9s%s %s%-8s%s %s%-17s%s %s%s%s\n' \
|
||||
"$statecolor" "$char" "$colorreset" \
|
||||
"$colorreset" "$svc" "$colorreset" \
|
||||
"$statecolor" "$state" "$colorreset" \
|
||||
"$enabledcolor" "${enabled:----}" "$colorreset" \
|
||||
"$colormagenta" "${pid:----}" "$colorreset" \
|
||||
"$colorgreen" "${prog:----}" "$colorreset" \
|
||||
"$msgcolor" "$msg" "$colorreset"
|
||||
|
||||
# optionally print the pstree
|
||||
if $tree; then
|
||||
if [[ -n $pid ]] && ((pid > 0)); then
|
||||
echo "$colorgray"
|
||||
pstree -ac "$pid"
|
||||
fi
|
||||
echo "$colorreset"
|
||||
fi
|
||||
}
|
||||
|
||||
# handle the status subcommand
|
||||
do_status() {
|
||||
local OPTIND option
|
||||
local d
|
||||
local logo
|
||||
local now
|
||||
local svcs=()
|
||||
|
||||
logo=$(getlogo)
|
||||
while getopts 'hlt' option; do
|
||||
case "$option" in
|
||||
h) usage; exit 0;;
|
||||
l) log=true;;
|
||||
t) tree=true;;
|
||||
*) usage; exit 1;;
|
||||
esac
|
||||
done
|
||||
shift "$((OPTIND - 1))"
|
||||
|
||||
local filter=$1
|
||||
|
||||
# loop service directories
|
||||
for d in ./*/; do
|
||||
d=${d%/}
|
||||
svc=${d##*/}
|
||||
|
||||
# this is us being a little over-protective here
|
||||
if ! [[ $svc =~ $svc_re ]]; then
|
||||
rmsg -1 "unexpected characters in name: '$svc'" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ ! -d $svc/supervise ]]; then
|
||||
verbose "skipping $svc - '$svc/supervise' not found"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ -n $filter && $svc != *"$filter"* ]]; then
|
||||
if [[ $verbosity != 1 ]]; then
|
||||
verbose "filtering out '$svc' because it does not match '$filter'"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
svcs+=("$svc")
|
||||
$log && svcs+=("$svc/log")
|
||||
done
|
||||
|
||||
|
||||
# print title if verbose
|
||||
if ((verbosity > 0)); then
|
||||
# service count
|
||||
local services
|
||||
local count=${#svcs[@]}
|
||||
|
||||
if ((count == 1)); then
|
||||
services='service'
|
||||
else
|
||||
services='services'
|
||||
fi
|
||||
|
||||
printf '%s> %s %s-%s %s%s %s(%s%s%s)%s %s-%s %s%d %s%s\n' \
|
||||
"$colorgray" "$logo" \
|
||||
"$colorgray" "$colorreset" \
|
||||
"$colorblue" "$HOSTNAME" \
|
||||
"$colorcyan" "$colorgreen" "${PWD/#$HOME/\~}" \
|
||||
"$colorcyan" "$colorreset" \
|
||||
"$colorgray" "$colorreset" \
|
||||
"$colorblue" "$count" "$services" "$colorreset"
|
||||
fi
|
||||
echo
|
||||
|
||||
# table header
|
||||
printf '%s %-20s %-7s %-9s %-8s %-17s %s%s\n' \
|
||||
"$colorbold" \
|
||||
'SERVICE' 'STATE' 'ENABLED' 'PID' 'COMMAND' 'TIME' \
|
||||
"$colorreset"
|
||||
|
||||
# loop services
|
||||
printf -v now '%(%s)T' -1
|
||||
for svc in "${svcs[@]}"; do
|
||||
process_service "$svc" "$now"
|
||||
done
|
||||
echo
|
||||
}
|
||||
|
||||
# handle the enable and disable subcommands
|
||||
do_enable_disable() {
|
||||
local cmd=$1
|
||||
local svc
|
||||
local ret=0
|
||||
local file
|
||||
shift
|
||||
|
||||
if (($# < 1)); then
|
||||
rmsg -1 "Argument expected for '$cmd'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Loop all arguments as services
|
||||
msg "Running $progname $cmd $*"
|
||||
|
||||
for svc in "$@"; do
|
||||
# Validate service name
|
||||
if ! [[ $svc =~ $svc_re ]]; then
|
||||
rmsg -1 "unexpected characters in name: '$svc'" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
# ensure service exists
|
||||
if ! [[ -d ${FLDIR}${svc} ]]; then
|
||||
rmsg -1 "service directory '$svc' does not exist" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
file=$svc/down
|
||||
|
||||
case "$cmd" in
|
||||
enable)
|
||||
verbose "enable '$svc': rm -f '$file'"
|
||||
if ! rm -f "$file"; then
|
||||
rmsg 1 "failed to enable '$svc'"
|
||||
ret=1
|
||||
else
|
||||
if [ -L "${SVDIR}" ]
|
||||
then
|
||||
ln -s "${FLDIR}${svc}" "${SVDIR}"
|
||||
else
|
||||
ln -s "${FLDIR}${svc}" "${RUNSVDIR}/default" # default runlevel
|
||||
fi
|
||||
do_status
|
||||
fi
|
||||
;;
|
||||
disable)
|
||||
verbose "disabling '$svc': creating '$file'"
|
||||
if ! disable_message "$svc" > "$file"; then
|
||||
rmsg 1 "failed to disable '$svc'"
|
||||
ret=1
|
||||
else
|
||||
if [ -L "${SVDIR}" ]
|
||||
then
|
||||
unlink "${SVDIR}${svc}"
|
||||
else
|
||||
unlink "${RUNSVDIR}/default/${svc}" # default runlevel
|
||||
fi
|
||||
do_status
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
rmsg 2 "unknown command: $cmd" >&2
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
rmsg "$ret" "[$progname $cmd $*], exit code: $ret"
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
# show logs
|
||||
do_show_logs() {
|
||||
local cmd=$1
|
||||
local svc
|
||||
local ret=0
|
||||
local file
|
||||
shift
|
||||
|
||||
# Loop all arguments as services
|
||||
msg "Running $progname $cmd $*"
|
||||
|
||||
for svc in "$@"; do
|
||||
# Validate service name
|
||||
if ! [[ $svc =~ $svc_re ]]; then
|
||||
rmsg -1 "unexpected characters in name: '$svc'" >&2
|
||||
continue
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
if [ -h "${RSVDIR}${cmd}" ]
|
||||
then
|
||||
if [ -d "${RSVDIR}${cmd}" ]
|
||||
then
|
||||
# TODO check for logs before globing non-existent directories
|
||||
printf "\n%20s\n" "${colorgreen}The following log files found:"
|
||||
local logs_files_array=($(ls /var/log/$cmd/{*.*,current}))
|
||||
printf "\n$colorblue"
|
||||
printf '%s\n' "${logs_files_array[@]}"
|
||||
|
||||
printf "\n$colormagenta"
|
||||
read -n 1 -s -r -p "Press any key to continue"
|
||||
|
||||
printf "\n"
|
||||
printf "\n${colorcyan}Log files full output:\n"
|
||||
printf "${coloryellow}\n"
|
||||
printf "${coloryellow}${opt}"
|
||||
|
||||
tail -n 10 ${LOGDIR}${cmd}/{*.*,current} | less
|
||||
printf "\n"
|
||||
fi
|
||||
else
|
||||
printf "\n%20s\n" "${colorred}The service's ${cmd} log files have not been found or do not exist"
|
||||
fi
|
||||
|
||||
rmsg "$ret" "[$progname $cmd $*], exit code: $ret"
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
# show error logs
|
||||
do_show_err_logs() {
|
||||
local cmd=$1
|
||||
local svc
|
||||
local ret=0
|
||||
local file
|
||||
shift
|
||||
|
||||
# Loop all arguments as services
|
||||
msg "Running $progname $cmd $*"
|
||||
|
||||
for svc in "$@"; do
|
||||
# Validate service name
|
||||
if ! [[ $svc =~ $svc_re ]]; then
|
||||
rmsg -1 "unexpected characters in name: '$svc'" >&2
|
||||
continue
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -h "${RSVDIR}${cmd}" ]
|
||||
then
|
||||
if ! [ -d ${RSVDIR}${cmd} ]
|
||||
then
|
||||
printf "\n%20s\n" "${colorred}The following error log files found:"
|
||||
local logs_files_array=($(ls /var/log/$cmd/*error*.*))
|
||||
printf "\n$colorblue"
|
||||
printf '%s\n' "${logs_files_array[@]}"
|
||||
|
||||
printf "\n$colormagenta"
|
||||
read -n 1 -s -r -p "Press any key to continue"
|
||||
|
||||
printf "\n"
|
||||
printf "\n${colorcyan}Log files full output:\n"
|
||||
printf "${coloryellow}\n"
|
||||
printf "${coloryellow}${opt}"
|
||||
|
||||
tail -n 10 ${LOGDIR}${cmd}/*error*.* | more
|
||||
printf "\n"
|
||||
fi
|
||||
else
|
||||
printf "\n%20s\n" "${colorred}The service's ${cmd} error log files have not been found or do not exist"
|
||||
fi
|
||||
|
||||
rmsg "$ret" "[$progname $cmd $*], exit code: $ret"
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
# handle any other subcommand
|
||||
do_sv_cmd() {
|
||||
if (($# < 2)); then
|
||||
rmsg -1 "Argument expected for 'sv $1'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
msg "Running sv command (SVDIR=$SVDIR sv $*):"
|
||||
sv "$@"
|
||||
local ret=$?
|
||||
rmsg "$ret" "[sv $*], exit code: $ret"
|
||||
return "$ret"
|
||||
}
|
||||
|
||||
color_arg=
|
||||
tree=false
|
||||
log=false
|
||||
do_usage=-1
|
||||
verbosity=1
|
||||
while getopts 'c:d:hltuvV' option; do
|
||||
case "$option" in
|
||||
c) color_arg="$OPTARG";;
|
||||
d) SVDIR=$OPTARG;;
|
||||
h) do_usage=0;;
|
||||
l) log=true; cmd='status';;
|
||||
t) tree=true; cmd='status';;
|
||||
u) SVDIR=~/runit/service;;
|
||||
v) ((verbosity++));;
|
||||
V) echo "$RSM_VERSION"; exit 0;;
|
||||
*) do_usage=1;;
|
||||
esac
|
||||
done
|
||||
shift "$((OPTIND - 1))"
|
||||
|
||||
if [ -n "$NO_COLOR" ] && [ -z "$color_arg" ]
|
||||
then
|
||||
setcolors off
|
||||
elif [ -n "$color_arg" ]
|
||||
then
|
||||
setcolors "$color_arg"
|
||||
else
|
||||
setcolors auto
|
||||
fi
|
||||
|
||||
|
||||
# we wait until the colors are optionally set to output the usage message
|
||||
if ((do_usage > -1)); then
|
||||
usage
|
||||
exit "$do_usage"
|
||||
fi
|
||||
|
||||
# move to the service directory
|
||||
if [ -L "$SVDIR" ]
|
||||
then
|
||||
cd "$SVDIR" || fatal "failed to enter dir: $SVDIR"
|
||||
else
|
||||
cd "$RUNSVDIR/default" || fatal "failed to enter dir: $FLDIR"
|
||||
fi
|
||||
|
||||
# figure out 'cmd' command
|
||||
if [[ -z $cmd ]]; then
|
||||
cmd=${1:-status}
|
||||
shift
|
||||
fi
|
||||
|
||||
case "$cmd" in
|
||||
status)
|
||||
do_status "$@"
|
||||
;;
|
||||
enable|disable)
|
||||
do_enable_disable "$cmd" "$@"
|
||||
;;
|
||||
logs)
|
||||
do_show_logs "$@"
|
||||
;;
|
||||
alllogs)
|
||||
do_show_logs "$@"
|
||||
;;
|
||||
errorlogs)
|
||||
do_show_err_logs "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
if $tree; then
|
||||
rmsg -1 "-t can only be specified with 'status'"
|
||||
exit 1
|
||||
fi
|
||||
if $log; then
|
||||
rmsg -1 "-l can only be specified with 'status'"
|
||||
exit 1
|
||||
fi
|
||||
do_sv_cmd "$cmd" "$@"
|
||||
;;
|
||||
esac
|
||||
8
rsv
8
rsv
@@ -115,10 +115,10 @@ usage() {
|
||||
logo=$(getlogo)
|
||||
|
||||
cat <<EOF
|
||||
$colormagenta ____ ___ __ __
|
||||
$colormagenta || \\ / __\ \ \/ / $colorgreen Runit Service Manager ($RSV_VERSION)
|
||||
$colormagenta ||_// \__ \ \ / $colorgreen Source: https://github.com/bahamas10/vsv
|
||||
$colormagenta || \\ \___/ \/ $colorgreen MIT License
|
||||
$colormagenta ______ ____ __ __
|
||||
$colormagenta | | \ \ / ___\ \ \/ / $colorgreen Runit Service Manager ($RSV_VERSION)
|
||||
$colormagenta | |_/ / \____ \ / $colorgreen Source: https://github.com/bahamas10/vsv
|
||||
$colormagenta | | \ \ \____/ \/ $colorgreen MIT License
|
||||
|
||||
$logo $colorblue Manage and view runit services
|
||||
$logo $colorblue Made specifically for Void Linux but should work anywhere
|
||||
|
||||
Reference in New Issue
Block a user