Update user service script to check for non-root use and for PipeWire or PulseAudio services/ [skip ci]
This commit is contained in:
+122
-24
@@ -7,6 +7,7 @@ SERVICE_SOURCE="./scripts/shairport-sync.user.service"
|
||||
USER_SYSTEMD_DIR="$HOME/.config/systemd/user"
|
||||
SERVICE_DEST="$USER_SYSTEMD_DIR/$SERVICE_NAME"
|
||||
APP_NAME="shairport-sync"
|
||||
APP_DISPLAY_NAME="Shairport Sync"
|
||||
|
||||
DRY_RUN=0
|
||||
|
||||
@@ -40,16 +41,24 @@ while [ $# -gt 0 ]; do
|
||||
shift
|
||||
done
|
||||
|
||||
# Check we are not running as root or under sudo
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
echo "[FAIL] This script must not be run as root or with sudo." >&2
|
||||
echo " [ADVICE] Please run it as the regular user who will own the service." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "--------------------------------------------------"
|
||||
echo "Systemd User Service Installer for $APP_NAME"
|
||||
echo "Systemd User Service Installer for $APP_DISPLAY_NAME"
|
||||
echo "This script will:"
|
||||
echo " - Check for system/initd conflicts"
|
||||
echo " - Verify the app is not already running"
|
||||
echo " - Check for systemd/initd conflicts"
|
||||
echo " - Verify that Shairport Sync is not already running"
|
||||
echo " - Detect PipeWire or PulseAudio"
|
||||
echo " - Install the user service"
|
||||
echo " - Enable it to run at login"
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
echo ""
|
||||
echo "Dry-run mode: no changes will be made."
|
||||
echo "Note: Dry-run mode: no changes will be made."
|
||||
fi
|
||||
echo "--------------------------------------------------"
|
||||
echo ""
|
||||
@@ -64,8 +73,9 @@ fi
|
||||
|
||||
# Check for system-level service
|
||||
if systemctl is-enabled "$APP_NAME" >/dev/null 2>&1; then
|
||||
echo "[FAIL] A system-level systemd service for '$APP_NAME' is currently enabled." >&2
|
||||
echo " [ADVICE] Please disable it before installing a user-level service." >&2
|
||||
echo "[FAIL] A system-level systemd service (\"$APP_NAME\") for $APP_DISPLAY_NAME is currently enabled." >&2
|
||||
echo " [ADVICE] Please disable it before installing a user-level service. For example, try:" >&2
|
||||
echo " [ADVICE] $ sudo systemctl disable --now $APP_NAME" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "[OK] No conflicting system-level systemd service enabled."
|
||||
@@ -73,8 +83,9 @@ fi
|
||||
|
||||
# Check for init.d service
|
||||
if [ -x "/etc/init.d/$APP_NAME" ]; then
|
||||
echo "[FAIL] An init.d script for '$APP_NAME' exists at /etc/init.d/$APP_NAME." >&2
|
||||
echo " [ADVICE] Please remove or disable the init.d version before proceeding." >&2
|
||||
echo "[FAIL] An init.d script for $APP_DISPLAY_NAME exists at /etc/init.d/$APP_NAME." >&2
|
||||
echo " [ADVICE] Please remove or disable the init.d version before proceeding. For example, try:" >&2
|
||||
echo " [ADVICE] $ sudo rm /etc/init.d/$APP_NAME" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "[OK] No conflicting init.d service found."
|
||||
@@ -82,16 +93,78 @@ fi
|
||||
|
||||
# Note if the user-level service is already running
|
||||
if systemctl --user is-enabled "$APP_NAME" >/dev/null 2>&1; then
|
||||
echo "[NOTE] A user-level systemd service for '$APP_NAME' is currently enabled."
|
||||
echo "[NOTE] A user-level systemd service -- \"$APP_NAME\" -- for $APP_DISPLAY_NAME is currently enabled."
|
||||
fi
|
||||
|
||||
# Check if the application is already running
|
||||
if pgrep -x "$APP_NAME" >/dev/null 2>&1; then
|
||||
echo "[FAIL] $APP_NAME is already running." >&2
|
||||
if pgrep -f "$APP_NAME" >/dev/null 2>&1; then
|
||||
echo "[FAIL] $APP_DISPLAY_NAME is already running." >&2
|
||||
echo " [ADVICE] Please stop $APP_NAME before proceeding." >&2
|
||||
exit 1
|
||||
else
|
||||
echo "[OK] $APP_NAME is not currently running."
|
||||
echo "[OK] $APP_DISPLAY_NAME is not running."
|
||||
fi
|
||||
|
||||
# Detect PipeWire or PulseAudio (prefer PipeWire)
|
||||
AUDIO_BACKEND=""
|
||||
AUDIO_REQUIRES=""
|
||||
AUDIO_AFTER=""
|
||||
AUDIO_OUTPUT_FLAG=""
|
||||
|
||||
detect_pipewire() {
|
||||
# Check if pipewire is running as a user service
|
||||
if systemctl --user is-active pipewire >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
# Also check if the process is running
|
||||
if pgrep -x pipewire >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
detect_pulseaudio() {
|
||||
# Check if pulseaudio is running as a user service
|
||||
if systemctl --user is-active pulseaudio >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
# Also check if the process is running
|
||||
if pgrep -x pulseaudio >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check whether shairport-sync was built with support for a given backend
|
||||
# Usage: built_with_support <backend> e.g. built_with_support pipewire
|
||||
built_with_support() {
|
||||
shairport-sync -V 2>&1 | grep -qi "$1"
|
||||
}
|
||||
|
||||
if detect_pipewire; then
|
||||
echo "[OK] PipeWire is running."
|
||||
if built_with_support pipewire; then
|
||||
echo "[OK] $APP_DISPLAY_NAME was built with PipeWire support -- it will be configured to use it."
|
||||
AUDIO_BACKEND="pipewire"
|
||||
AUDIO_REQUIRES="Requires=pipewire.service"
|
||||
AUDIO_AFTER="After=pipewire.service"
|
||||
AUDIO_OUTPUT_FLAG="-o pipewire"
|
||||
else
|
||||
echo "[NOTE] PipeWire is active, but $APP_DISPLAY_NAME was not built with PipeWire support -- falling back to the default ALSA audio output device."
|
||||
fi
|
||||
elif detect_pulseaudio; then
|
||||
echo "[OK] PulseAudio is running."
|
||||
if built_with_support pulseaudio; then
|
||||
echo "[OK] $APP_DISPLAY_NAME was built with PulseAudio support -- it will be configured to use it."
|
||||
AUDIO_BACKEND="pulseaudio"
|
||||
AUDIO_REQUIRES="Requires=pulseaudio.service"
|
||||
AUDIO_AFTER="After=pulseaudio.service"
|
||||
AUDIO_OUTPUT_FLAG="-o pulseaudio"
|
||||
else
|
||||
echo "[NOTE] PulseAudio is active, but $APP_DISPLAY_NAME was not built with PulseAudio support -- falling back to the default ALSA audio output device."
|
||||
fi
|
||||
else
|
||||
echo "[NOTE] Neither PipeWire nor PulseAudio detected -- $APP_DISPLAY_NAME will use the default ALSA audio output device."
|
||||
fi
|
||||
|
||||
# Create directory
|
||||
@@ -105,7 +178,6 @@ if [ ! -d "$USER_SYSTEMD_DIR" ]; then
|
||||
echo "[FAIL] Failed to create directory $USER_SYSTEMD_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fi
|
||||
else
|
||||
echo "[OK] User systemd directory already exists."
|
||||
@@ -117,30 +189,52 @@ if [ -d "$USER_SYSTEMD_DIR" ] && [ ! -w "$USER_SYSTEMD_DIR" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# If the service file already exists, check that we can replace it
|
||||
|
||||
if [ -f "$SERVICE_DEST" ] && [ ! -w "$SERVICE_DEST" ]; then
|
||||
echo "[FAIL] The existing $SERVICE_DEST can not be replaced due to its ownership or permissions." >&2
|
||||
echo " [ADVICE] Please delete $SERVICE_DEST or ensure it is owned and writable by user \"$(whoami)\" before proceeding." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create the service file
|
||||
|
||||
if [ "$DRY_RUN" -eq 0 ]; then
|
||||
echo "Creating service file at $SERVICE_DEST..."
|
||||
cat > "$SERVICE_DEST" <<EOF
|
||||
[Unit]
|
||||
|
||||
# Build the service file content from a single source
|
||||
if [ -n "$AUDIO_REQUIRES" ]; then
|
||||
UNIT_SECTION="[Unit]
|
||||
Description=Shairport Sync - AirPlay Audio Receiver
|
||||
After=sound.target
|
||||
$AUDIO_REQUIRES
|
||||
$AUDIO_AFTER"
|
||||
else
|
||||
UNIT_SECTION="[Unit]
|
||||
Description=Shairport Sync - AirPlay Audio Receiver
|
||||
After=sound.target"
|
||||
fi
|
||||
|
||||
if [ -n "$AUDIO_OUTPUT_FLAG" ]; then
|
||||
EXEC_START="ExecStart=shairport-sync --log-to-syslog $AUDIO_OUTPUT_FLAG"
|
||||
else
|
||||
EXEC_START="ExecStart=shairport-sync --log-to-syslog"
|
||||
fi
|
||||
|
||||
SERVICE_CONTENT="$UNIT_SECTION
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/shairport-sync --log-to-syslog
|
||||
$EXEC_START
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
WantedBy=default.target"
|
||||
|
||||
# Show the service file in dry-run mode, or write it for real
|
||||
if [ "$DRY_RUN" -eq 1 ]; then
|
||||
echo ""
|
||||
echo "[DRY-RUN] Would write the following service file to $SERVICE_DEST:"
|
||||
echo ""
|
||||
echo "$SERVICE_CONTENT" | sed 's/^/ /'
|
||||
echo ""
|
||||
else
|
||||
echo "Creating service file at $SERVICE_DEST..."
|
||||
printf '%s\n' "$SERVICE_CONTENT" > "$SERVICE_DEST"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "[OK] Service file created."
|
||||
else
|
||||
@@ -179,5 +273,9 @@ if [ "$DRY_RUN" -eq 1 ]; then
|
||||
echo "Dry run completed successfully."
|
||||
else
|
||||
echo "Installation complete."
|
||||
echo "The user-level systemd service for $APP_NAME is now installed and enabled."
|
||||
if [ -n "$AUDIO_BACKEND" ]; then
|
||||
echo "The user-level systemd service for $APP_DISPLAY_NAME is now installed and enabled, using $AUDIO_BACKEND."
|
||||
else
|
||||
echo "The user-level systemd service for $APP_DISPLAY_NAME is now installed and enabled."
|
||||
fi
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user