Skip to content

Instantly share code, notes, and snippets.

@Archenoth
Last active April 19, 2024 01:22
Show Gist options
  • Save Archenoth/25fb168edd899bd5398b18a65c280664 to your computer and use it in GitHub Desktop.
Save Archenoth/25fb168edd899bd5398b18a65c280664 to your computer and use it in GitHub Desktop.
Termux service management script, because convenience, and also because I wanna have fewer runit watchers running all the time
#!/bin/sh
# This script 100% requires termux-services to be installed
if ! dpkg -L termux-services 2>&1 >/dev/null; then
echo "Requires termux-services package to be installed." >&2
read -r -p "Would you like me to install that now? (y/n) " INSTALL >&2
if [ "$INSTALL" != "y" ]; then
echo "Aborting..." >&2
exit 1
fi
apt update && apt install termux-services
if [ $? -eq "0" ]; then
echo 'Failed to install package! Quitting.' >&2
exit 1
fi
fi
if [ -z "$SVDIR" ]; then
echo 'Warning! $SVDIR not set! Assuming default termux location.' >&2
export SVDIR="$PREFIX/var/service"
fi
# Where the real service folders will live
SVREPO="$SVDIR/../services-available"
# To verify and start the services daemon if it isn't already.
# That way we don't need to rely on an existing terminal session
# existing to run the services we want
ensure_sv_started() {
if ! ps aux | grep -v grep | grep runsvdir 2>&1 >/dev/null; then
export LOGDIR="$PREFIX/var/log"
(service-daemon start >/dev/null 2>&1 & )
fi
}
# Checks if the service dir, "$1" exists
dir_exists(){
[ -d "$SVREPO/$1" -o -d "$SVDIR/$1" ]
return $?
}
# Checks if the service passed in:
# 1) Exists
# 2) Is valid
# It also outright exits the script with a status of 1 if either are untrue
check_service(){
if [ -z "$1" ]; then
echo Needs service name too >&2
exit 1
elif ! dir_exists "$1"; then
echo Service not found: "$1" >&2
exit 1
fi
return 0
}
# Checks if a service is enabled in the "has a folder in the service
# directory" sense
service_enabled(){
[ -d "$SVDIR/$1" ]
return $?
}
# Lists all available services, all enabled services, and the status
# of all the enabled services out to stdout
services_overview(){
echo "Available services:"
ls "$SVREPO"
echo
echo "Enabled services:"
ls "$SVDIR"
echo
echo "Details:"
for service in `ls "$SVDIR"`; do
sv status "$service"
done
}
# Uninstaller option has priority over everything else
if [ "$1" = "uninstall" -a -z "$2" ]; then
if dir_exists "uninstall"; then
cat <<-EOF
Note: "uninstall" is a service. If you are attempting to get the status
of that, please run "$0 status uninstall" instead.
EOF
fi
cat <<-EOF
This will attempt to remove the changes made by this script that allow
it to manage your services so you can go back to how it was before
using it.
In order to do this, it will run the following commands:
rm -f "$SVDIR"/*
mv "$SVREPO"/* "$SVDIR"/
rmdir "$SVREPO"
EOF
read -r -p "Allow? (y/n) " ALLOWED
if [ "$ALLOWED" = "y" ]; then
echo "rm -f \"$SVDIR\"/*"
rm -f "$SVDIR"/* && echo 'Succeeded!' || echo 'Failed...'
echo "mv \"$SVREPO\"/* \"$SVDIR\"/"
mv "$SVREPO"/* "$SVDIR"/ && echo 'Succeeded!' || echo 'Failed...'
echo "rmdir \"$SVREPO\""
rmdir "$SVREPO" && echo 'Succeeded!' || echo 'Failed...'
cat <<-EOF
Uninstall complete!
If anything above failed, your service files should all still be in one
of the following places:
- $SVREPO
- $SVDIR
To complete the uninstall, you want to:
1) Move all of the folders into $SVDIR
2) Remove the $SVREPO folder once it's empty
If all is well though? Good luck! And seeya 'round!
EOF
exit 0
else
echo "Exiting..."
exit 1
fi
fi
# If we have this, we are definintely being called wrong, act like we
# have no parameters whatsoever to show usage, summary, and quit
if [ -n "$3" ]; then
$0
fi
# No service repo? Run initial setup
if [ ! -d "$SVREPO" ]; then
cat <<-EOF
Services are not currently managed by this script.
To do this, it needs to make another folder where it can move your
existing services, this will allow this script to manage them using
symlinks. (Which is important because it will let us disable and enable
your services instead of always having runit processes watching their
folders)
To do this, this script will run these commands:
mkdir -p "$SVREPO"
mv "$SVDIR"/* "$SVREPO"
ln -s "$SVREPO"/* "$SVDIR"
EOF
read -r -p "Allow? (y/n) " ALLOWED
if [ "$ALLOWED" = "y" ]; then
echo "mkdir -p \"$SVREPO\""
mkdir -p "$SVREPO" && echo 'Succeeded!' || echo 'Failed...'
echo "mv \"$SVDIR\"/* \"$SVREPO\""
mv "$SVDIR"/* "$SVREPO" && echo 'Succeeded!' || echo 'Failed...'
echo "ln -s \"$SVREPO\"/* \"$SVDIR\""
ln -s "$SVREPO"/* "$SVDIR" && echo 'Succeeded!' || echo 'Failed...'
cat <<-EOF
Initialization steps performed, try running me again!
If anything failed, or you wish to go back to how the services used to
be managed, you can run "$0 uninstall" to attempt to revert the above.
EOF
else
echo "Exiting..."
exit 1
fi
fi
case "$1" in
start)
check_service "$2" && sv up "$2" && ensure_sv_started
;;
stop)
check_service "$2" && sv down "$2"
;;
restart)
check_service "$2" && sv down "$2" && sv up "$2" && ensure_sv_started
;;
status)
if [ -n "$2" ]; then
if service_enabled "$2"; then
sv status "$2"
exit $?
elif dir_exists "$2"; then
echo "Status: disabled"
exit 1
else
echo "Invalid service: $2"
exit 1
fi
fi
services_overview
;;
enable)
if check_service "$2"; then
echo "Enabling $2!"
ln -s "$SVREPO/$2" "$SVDIR/"
rm -f "$SVDIR/$2/down" 2>/dev/null
sv up "$2"
ensure_sv_started
fi
;;
disable)
if check_service "$2"; then
echo "Disabling $2!"
touch "$SVDIR/$2/down"
sv down "$2"
rm "$SVDIR/$2"
fi
;;
edit)
check_service "$2" && editor "$SVREPO/$2/run"
;;
list)
# In case there is a "list" service to manage
if [ -n "$2" ]; then
$0 "$2" "$1" "$3"
return $?
fi
ls "$SVREPO"
;;
*)
if [ -n "$1" ]; then
# Is the first argument a service name?
if dir_exists "$1"; then
# Likely called in the form $0 <service> <command>, swap operands
if [ -n "$2" ]; then
$0 "$2" "$1"
else # Just a service name, get the status of the service and exit
$0 status "$1"
fi
exit $?
else
echo "Unrecognized option: $1" >&2
fi
fi
# No operands will still give us a summary, because that's pleasant!
echo "Usage: $0 <service> {start|stop|restart|enable|disable|status|edit}"
echo "or $0 {start|stop|restart|enable|disable|status|edit} <service>"
echo "or $0 {status|list|uninstall}"
echo
$0 status
exit 1
esac
exit $?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment