Last active
April 19, 2024 01:22
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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