7 Commits

Author SHA1 Message Date
ae4a3d3d25 Improve host detection 2022-02-11 19:40:07 -05:00
654213f73e Fix systemd service targets and start Arch plumbing 2022-01-18 16:03:07 -05:00
35d488430a Combine setvncpass commands 2022-01-17 12:24:35 -05:00
ed247281f4 Remove duplicate blocks 2022-01-17 12:08:17 -05:00
82ba1f98e0 Remove duplicate blocks 2022-01-17 12:07:08 -05:00
ba20e0cece Cleanup legacy systemd services 2022-01-17 12:02:48 -05:00
949b6d2bf7 Update README 2022-01-17 12:02:28 -05:00
2 changed files with 128 additions and 126 deletions

View File

@@ -78,7 +78,7 @@ jriver-createrepo
MC helper services are installed as system-level services (`--service-type system`) by default and are manipulable as admin: `sudo systemctl stop jriver-servicename@username.service`. It is also possible to create user-level services using `--service-type user` that can be manipulated by the unprivileged user: `systemctl --user stop jriver-mediacenter`. MC helper services are installed as system-level services (`--service-type system`) by default and are manipulable as admin: `sudo systemctl stop jriver-servicename@username.service`. It is also possible to create user-level services using `--service-type user` that can be manipulated by the unprivileged user: `systemctl --user stop jriver-mediacenter`.
Multiple services (but not `--service-types`) can be installed at one time using multiple `--service` blocks: `installJRMC --repo --service jriver-x11vnc --service jriver-mediacenter` Multiple services (but not `--service-types`) can be installed at one time using multiple `--service` blocks: `installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter`
### `jriver-x11vnc` versus `jriver-xvnc` ### `jriver-x11vnc` versus `jriver-xvnc`

View File

@@ -1,8 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# This script will install JRiver Media Center and associated services # This script will install JRiver Media Center and associated services on most major distros
# on Fedora, CentOS, Debian, and Ubuntu
# #
# Copyright (c) 2021 Bryan C. Roessler # Copyright (c) 2021-2022 Bryan C. Roessler
# This software is released under the Apache License. # This software is released under the Apache License.
# https://www.apache.org/licenses/LICENSE-2.0 # https://www.apache.org/licenses/LICENSE-2.0
# #
@@ -19,7 +18,7 @@
shopt -s extglob shopt -s extglob
declare -g SCRIPTVERSION="1.0b7" declare -g SCRIPTVERSION="1.0b8"
declare -g OUTPUTDIR="$PWD/output" declare -g OUTPUTDIR="$PWD/output"
declare -g CREATEREPO_WEBROOT="/var/www/jriver" declare -g CREATEREPO_WEBROOT="/var/www/jriver"
declare -g USER="${SUDO_USER:-$USER}" declare -g USER="${SUDO_USER:-$USER}"
@@ -109,48 +108,6 @@ askOk() {
} }
#######################################
# Parses /etc/os-release and provide a compatability layer for unrecognzied distros
#######################################
getOS() {
debug "Running: ${FUNCNAME[0]}"
declare -g ID
if [[ -e "/etc/os-release" ]]; then
source "/etc/os-release"
else
err "/etc/os-release not found"
err "Your OS is unsupported"
printHelp && exit 1
fi
debug "Platform: $ID $VERSION_ID"
case "$ID" in
centos|fedora|debian|ubuntu)
return 0
;;
linuxmint|neon)
ID="ubuntu"
;;
*suse*)
ID="suse"
;;
*)
echo "Autodetecting distro, this may be unreliable and --compat may also be required"
if hash dnf &>/dev/null || hash yum &>/dev/null; then
ID="fedora"
elif hash apt &>/dev/null; then
ID="ubuntu"
fi
;;
esac
debug "Using compatability platform: $ID"
}
####################################### #######################################
# Parses user input and sets sensible defaults # Parses user input and sets sensible defaults
####################################### #######################################
@@ -342,7 +299,8 @@ installPackage() {
skip_check_installed=1 skip_check_installed=1
;; ;;
--allow-downgrades) --allow-downgrades)
[[ "$ID" =~ (debian|ubuntu) ]] && install_flags+=(--allow-downgrades) [[ "$ID" =~ ^(debian|ubuntu)$ ]] &&
install_flags+=(--allow-downgrades)
;; ;;
--nogpgcheck) --nogpgcheck)
if [[ "$ID" =~ ^(fedora|centos)$ ]]; then if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
@@ -430,6 +388,11 @@ addRepo() {
wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | sudo apt-key add - &>/dev/null wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | sudo apt-key add - &>/dev/null
elif [[ "$ID" == "suse" ]]; then elif [[ "$ID" == "suse" ]]; then
sudo zypper addrepo --no-gpgcheck "https://repos.bryanroessler.com/jriver" jriver &>/dev/null sudo zypper addrepo --no-gpgcheck "https://repos.bryanroessler.com/jriver" jriver &>/dev/null
elif [[ "$ID" == "arch" ]]; then
sudo bash -c "cat <<- EOF >
EOF"
fi fi
} }
@@ -707,6 +670,12 @@ buildRPM() {
} }
installMCArch() {
debug "Running: ${FUNCNAME[0]}"
echo "Arch install under construction"
}
####################################### #######################################
# Copy the RPM to createrepo-webroot and runs createrepo as the createrepo-user # Copy the RPM to createrepo-webroot and runs createrepo as the createrepo-user
####################################### #######################################
@@ -784,7 +753,7 @@ symlinkCerts() {
####################################### #######################################
# Rstore the mjr license file if it is next to installJRMC or RESTOREFILE is set # Restore the mjr license file if it is next to installJRMC or RESTOREFILE is set
####################################### #######################################
restoreLicense() { restoreLicense() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
@@ -819,12 +788,16 @@ openFirewall() {
# Create OS-specific port rules based on argument (service) name # Create OS-specific port rules based on argument (service) name
declare -a f_ports # for firewall-cmd declare -a f_ports # for firewall-cmd
declare u_ports # for ufw declare u_ports # for ufw
if [[ "$1" == "jriver" ]]; then declare -a n_ports # for nftables
declare port
if [[ "$1" == "jriver-mediacenter" ]]; then
f_ports=(52100-52200/tcp 1900/udp) f_ports=(52100-52200/tcp 1900/udp)
u_ports="52100:52200/tcp|1900/udp" u_ports="52100:52200/tcp|1900/udp"
n_ports=("tcp dport 52100-52200 accept" "udp dport 1900 accept")
elif [[ "$1" =~ ^(jriver-x11vnc|jriver-xvnc)$ ]]; then elif [[ "$1" =~ ^(jriver-x11vnc|jriver-xvnc)$ ]]; then
f_ports=("$PORT"/tcp 1900/udp) f_ports=("$PORT"/tcp 1900/udp)
u_ports="$PORT/tcp|1900/udp" u_ports="$PORT/tcp|1900/udp"
n_ports=("tcp dport $PORT accept" "udp dport 1900 accept")
fi fi
# Open the ports # Open the ports
@@ -834,8 +807,8 @@ openFirewall() {
firewall_cmd --permanent --new-service="$1" &>/dev/null firewall_cmd --permanent --new-service="$1" &>/dev/null
firewall_cmd --permanent --service="$1" --set-description="$1 installed by installJRMC" &>/dev/null firewall_cmd --permanent --service="$1" --set-description="$1 installed by installJRMC" &>/dev/null
firewall_cmd --permanent --service="$1" --set-short="$1" &>/dev/null firewall_cmd --permanent --service="$1" --set-short="$1" &>/dev/null
for f_port in "${f_ports[@]}"; do for port in "${f_ports[@]}"; do
firewall_cmd --permanent --service="$1" --add-port="$f_port" &>/dev/null firewall_cmd --permanent --service="$1" --add-port="$port" &>/dev/null
done done
firewall_cmd --add-service "$1" --permanent &>/dev/null firewall_cmd --add-service "$1" --permanent &>/dev/null
firewall_cmd --reload &>/dev/null firewall_cmd --reload &>/dev/null
@@ -853,6 +826,13 @@ openFirewall() {
fi fi
firewall_cmd app update "$1" &>/dev/null firewall_cmd app update "$1" &>/dev/null
firewall_cmd allow "$1" &>/dev/null firewall_cmd allow "$1" &>/dev/null
elif [[ "$ID" == "arch" ]]; then
sysctl -w net.ipv4.ip_forward = 1
sudo nft create table inet "jriver"
sudo nft create chain inet "jriver" "$1" '{ type filter hook input priority 0; policy accept; }'
for port in "${n_ports[@]}"; do
sudo nft add rule inet jriver "$1" handle tcp dport "$port"
done
fi fi
# shellcheck disable=SC2181 # More concise # shellcheck disable=SC2181 # More concise
@@ -864,43 +844,15 @@ openFirewall() {
####################################### #######################################
# Create the x11vnc password file # Create the xvnc or x11vnc password file
####################################### # Arguments:
setX11VNCPass() { # Service type (xvnc, x11vnc)
debug "Running: ${FUNCNAME[0]}"
declare vncpassfile="$HOME/.vnc/jrmc_passwd"
[[ ! -d "${vncpassfile%/*}" ]] && mkdir -p "${vncpassfile%/*}"
if [[ -f "$vncpassfile" ]]; then
if [[ ! -v VNCPASS ]]; then
err "Refusing to overwrite existing $vncpassfile with an empty password"
err "Remove existing $vncpassfile or set --vncpass to use an empty password"
exit 1
else
rm -f "$vncpassfile"
fi
fi
if [[ -v VNCPASS ]]; then
if ! x11vnc -storepasswd "$VNCPASS" "$vncpassfile"; then
err "Could not create VNC password file"
return 1
fi
else
declare -g NOVNCAUTH=1
fi
}
#######################################
# Create the Xvnc password file
####################################### #######################################
setVNCPass() { setVNCPass() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare vncpassfile="$HOME/.vnc/jrmc_passwd" declare vncpassfile="$HOME/.vnc/jrmc_passwd"
declare vnc_pass_cmd
[[ ! -d "${vncpassfile%/*}" ]] && mkdir -p "${vncpassfile%/*}" [[ ! -d "${vncpassfile%/*}" ]] && mkdir -p "${vncpassfile%/*}"
@@ -915,7 +867,12 @@ setVNCPass() {
fi fi
if [[ -v VNCPASS ]]; then if [[ -v VNCPASS ]]; then
if ! echo "$VNCPASS" | vncpasswd -f > "$vncpassfile"; then if [[ $1 == "xvnc" ]]; then
vnc_pass_cmd="echo $VNCPASS | vncpasswd -f > $vncpassfile"
elif [[ $1 == "x11vnc" ]]; then
vnc_pass_cmd="x11vnc -storepasswd $VNCPASS $vncpassfile"
fi
if ! eval "$vnc_pass_cmd"; then
err "Could not create VNC password file" err "Could not create VNC password file"
return 1 return 1
fi fi
@@ -950,7 +907,7 @@ setDisplay() {
setServiceVars() { setServiceVars() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare -g SERVICE_NAME SERVICE_FNAME TIMER_NAME TIMER_FNAME USER_STRING declare -g SERVICE_NAME SERVICE_FNAME TIMER_NAME TIMER_FNAME USER_STRING GRAPHICAL_TARGET
declare -g SERVICE_TYPE="${SERVICE_TYPE:-system}" declare -g SERVICE_TYPE="${SERVICE_TYPE:-system}"
declare service_dir="/usr/lib/systemd/$SERVICE_TYPE" declare service_dir="/usr/lib/systemd/$SERVICE_TYPE"
@@ -966,12 +923,14 @@ setServiceVars() {
systemctl_disable_cmd(){ sudo systemctl disable --now "$@"; } systemctl_disable_cmd(){ sudo systemctl disable --now "$@"; }
systemctl_is_enabled_cmd(){ sudo systemctl is-enabled -q "$@"; } systemctl_is_enabled_cmd(){ sudo systemctl is-enabled -q "$@"; }
systemctl_is_active_cmd(){ sudo systemctl is-active -q "$@"; } systemctl_is_active_cmd(){ sudo systemctl is-active -q "$@"; }
GRAPHICAL_TARGET="graphical.target"
elif [[ "$SERVICE_TYPE" == "user" ]]; then elif [[ "$SERVICE_TYPE" == "user" ]]; then
systemctl_reload_cmd(){ systemctl --user daemon-reload; } systemctl_reload_cmd(){ systemctl --user daemon-reload; }
systemctl_enable_cmd(){ systemctl --user enable --now "$@"; } systemctl_enable_cmd(){ systemctl --user enable --now "$@"; }
systemctl_disable_cmd(){ systemctl --user disable --now "$@"; } systemctl_disable_cmd(){ systemctl --user disable --now "$@"; }
systemctl_is_enabled_cmd(){ systemctl --user is-enabled -q "$@"; } systemctl_is_enabled_cmd(){ systemctl --user is-enabled -q "$@"; }
systemctl_is_active(){ sudo systemctl is-active -q "$@"; } systemctl_is_active(){ sudo systemctl is-active -q "$@"; }
GRAPHICAL_TARGET="default.target"
fi fi
[[ ! -d "$service_dir" ]] && sudo mkdir -p "$service_dir" [[ ! -d "$service_dir" ]] && sudo mkdir -p "$service_dir"
@@ -1005,7 +964,7 @@ service_jriver-mediacenter() {
sudo bash -c "cat <<- EOF > $SERVICE_FNAME sudo bash -c "cat <<- EOF > $SERVICE_FNAME
[Unit] [Unit]
Description=JRiver Media Center $MVERSION Description=JRiver Media Center $MVERSION
After=graphical.target After=$GRAPHICAL_TARGET
[Service] [Service]
$USER_STRING $USER_STRING
@@ -1019,12 +978,12 @@ service_jriver-mediacenter() {
TimeoutStopSec=30 TimeoutStopSec=30
[Install] [Install]
WantedBy=graphical.target WantedBy=$GRAPHICAL_TARGET
EOF" EOF"
systemctl_reload_cmd && systemctl_reload_cmd &&
systemctl_enable_cmd "$SERVICE_NAME" && systemctl_enable_cmd "$SERVICE_NAME" &&
openFirewall "jriver" openFirewall "jriver-mediacenter"
} }
@@ -1053,7 +1012,7 @@ service_jriver-xvnc() {
installPackage tigervnc-server installPackage tigervnc-server
setVNCPass setVNCPass xvnc
if (( NOVNCAUTH )); then if (( NOVNCAUTH )); then
start_cmd="/usr/bin/vncserver $NEXT_DISPLAY -geometry 1440x900 -alwaysshared -name jriver$NEXT_DISPLAY -SecurityTypes None -autokill -xstartup /usr/bin/mediacenter$MVERSION" start_cmd="/usr/bin/vncserver $NEXT_DISPLAY -geometry 1440x900 -alwaysshared -name jriver$NEXT_DISPLAY -SecurityTypes None -autokill -xstartup /usr/bin/mediacenter$MVERSION"
@@ -1084,7 +1043,7 @@ service_jriver-xvnc() {
systemctl_enable_cmd "$SERVICE_NAME" && systemctl_enable_cmd "$SERVICE_NAME" &&
echo "Xvnc running on localhost:$PORT" && echo "Xvnc running on localhost:$PORT" &&
openFirewall "jriver-xvnc" && openFirewall "jriver-xvnc" &&
openFirewall "jriver" openFirewall "jriver-mediacenter"
} }
@@ -1102,7 +1061,7 @@ service_jriver-x11vnc() {
installPackage x11vnc installPackage x11vnc
setX11VNCPass setVNCPass x11vnc
# Get current desktop resolution # Get current desktop resolution
# TODO: may need to break this out into its own function and get smarter at identifying multi-monitors # TODO: may need to break this out into its own function and get smarter at identifying multi-monitors
@@ -1130,7 +1089,7 @@ service_jriver-x11vnc() {
sudo bash -c "cat <<-EOF > $SERVICE_FNAME sudo bash -c "cat <<-EOF > $SERVICE_FNAME
[Unit] [Unit]
Description=x11vnc Description=x11vnc
After=graphical.target After=$GRAPHICAL_TARGET
[Service] [Service]
$USER_STRING $USER_STRING
@@ -1141,7 +1100,7 @@ service_jriver-x11vnc() {
RestartSec=10 RestartSec=10
[Install] [Install]
WantedBy=graphical.target WantedBy=$GRAPHICAL_TARGET
EOF" EOF"
systemctl_reload_cmd && systemctl_reload_cmd &&
@@ -1352,7 +1311,7 @@ service_jriver-createrepo() {
uninstall() { uninstall() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare service unit f declare service unit f i
if ! askOk "Do you really want to uninstall JRiver Media Center"; then if ! askOk "Do you really want to uninstall JRiver Media Center"; then
echo "Uninstall canceled" echo "Uninstall canceled"
@@ -1362,29 +1321,23 @@ uninstall() {
echo "Stopping and removing all Media Center services" echo "Stopping and removing all Media Center services"
for service in $(compgen -A "function" "service"); do for service in $(compgen -A "function" "service"); do
service="${service##service_}" service="${service##service_}"
SERVICE_TYPE=system setServiceVars "$service"; for i in user system; do
for unit in "$SERVICE_NAME" "$TIMER_NAME"; do SERVICE_TYPE="$i" setServiceVars "$service";
if systemctl_is_active_cmd "$unit" &>/dev/null || for unit in "$SERVICE_NAME" "$TIMER_NAME"; do
systemctl_is_enabled_cmd "$unit" &>/dev/null; then if systemctl_is_active_cmd "$unit" &>/dev/null ||
debug "Disabling $unit" systemctl_is_enabled_cmd "$unit" &>/dev/null; then
systemctl_disable_cmd "$unit" debug "Disabling $unit"
fi systemctl_disable_cmd "$unit"
fi
done
for f in "$SERVICE_FNAME" "$TIMER_FNAME"; do
[[ -f "$f" ]] && debug "Removing $f" && sudo rm -f "$f"
done
systemctl_reload_cmd
done done
for f in "$SERVICE_FNAME" "$TIMER_FNAME"; do for f in /etc/systemd/system/jriver-*; do
[[ -f "$f" ]] && debug "Removing $f" && sudo rm -f "$f" sudo rm -f "$f"
done done
SERVICE_TYPE=user setServiceVars "$service";
for unit in "$SERVICE_NAME" "$TIMER_NAME"; do
if systemctl_is_active_cmd "$unit" &>/dev/null ||
systemctl_is_enabled_cmd "$unit" &>/dev/null; then
debug "Disabling $unit"
systemctl_disable_cmd "$unit"
fi
done
for f in "$SERVICE_FNAME" "$TIMER_FNAME"; do
[[ -f "$f" ]] && debug "Removing $f" && sudo rm -f "$f"
done
systemctl_reload_cmd
done done
echo "Removing repo files" echo "Removing repo files"
@@ -1415,6 +1368,8 @@ uninstall() {
eval "$firewall_cmd" eval "$firewall_cmd"
[[ -f "/etc/ufw/applications.d/jriver" ]] && [[ -f "/etc/ufw/applications.d/jriver" ]] &&
sudo rm -f /etc/ufw/applications.d/jriver sudo rm -f /etc/ufw/applications.d/jriver
elif hash nft 2>/dev/null; then
sudo nft delete table inet jriver
fi fi
echo "Uninstalling JRiver Media Center package" echo "Uninstalling JRiver Media Center package"
@@ -1441,15 +1396,55 @@ tests() {
main() { main() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
getOS declare -g ID
if [[ -e "/etc/os-release" ]]; then
source "/etc/os-release"
else
err "/etc/os-release not found"
err "Your OS is unsupported"
printHelp && exit 1
fi
debug "Host platform: $ID $VERSION_ID"
case "$ID" in
centos|fedora)
if hash dnf &>/dev/null; then
declare mgr="dnf"
elif hash yum &>/dev/null; then
declare mgr="yum"
fi
;;
debian|ubuntu|arch)
return 0
;;
linuxmint|neon)
ID="ubuntu"
;;
*suse*)
ID="suse"
;;
*)
echo "Autodetecting distro, this may be unreliable and --compat may also be required"
if hash dnf &>/dev/null; then
ID="fedora"
declare mgr="dnf"
elif hash yum &>/dev/null; then
ID="centos"
declare mgr="yum"
elif hash apt &>/dev/null; then
ID="ubuntu"
elif hash pacman &>/dev/null; then
ID="arch"
fi
;;
esac
debug "Host compatability platform: $ID $VERSION_ID"
# Distro-specific commands # Distro-specific commands
if [[ "$ID" =~ ^(fedora|centos)$ ]]; then if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
if hash dnf &>/dev/null; then
declare mgr="dnf"
elif hash yum &>/dev/null; then
declare mgr="yum"
fi
pkg_install(){ sudo "$mgr" install -y "$@"; } pkg_install(){ sudo "$mgr" install -y "$@"; }
pkg_remove(){ sudo "$mgr" remove -y "$@"; } pkg_remove(){ sudo "$mgr" remove -y "$@"; }
pkg_update(){ sudo "$mgr" makecache; } pkg_update(){ sudo "$mgr" makecache; }
@@ -1468,6 +1463,12 @@ main() {
pkg_update(){ sudo zypper --non-interactive -q refresh jriver; } pkg_update(){ sudo zypper --non-interactive -q refresh jriver; }
pkg_query(){ rpm -q "$@"; } pkg_query(){ rpm -q "$@"; }
firewall_cmd(){ sudo firewall-cmd "$@"; } firewall_cmd(){ sudo firewall-cmd "$@"; }
elif [[ "$ID" == "arch" ]]; then
pkg_install(){ sudo pacman -Sy --noconfirm "$@"; }
pkg_remove(){ sudo pacman -Rs --noconfirm "$@"; }
pkg_update(){ sudo pacman -Syy ; }
pkg_query(){ sudo pacman -Qs "$@"; }
firewall_cmd(){ sudo nft -A INPUT "$@"; }
fi fi
parseInput "$@" parseInput "$@"
@@ -1487,7 +1488,7 @@ main() {
if (( UNINSTALL_SWITCH )); then if (( UNINSTALL_SWITCH )); then
uninstall uninstall
exit $? exit
fi fi
# Some distros need external repos installed for MC libraries # Some distros need external repos installed for MC libraries
@@ -1506,7 +1507,7 @@ main() {
echo "JRiver Media Center installed successfully from repo" echo "JRiver Media Center installed successfully from repo"
symlinkCerts symlinkCerts
restoreLicense restoreLicense
openFirewall "jriver" openFirewall "jriver-mediacenter"
else else
err "JRiver Media Center installation from repo failed" err "JRiver Media Center installation from repo failed"
exit 1 exit 1
@@ -1525,7 +1526,8 @@ main() {
if (( LOCAL_INSTALL_SWITCH )); then if (( LOCAL_INSTALL_SWITCH )); then
if ([[ "$TARGET" =~ (debian|ubuntu) ]] && installMCDEB) || if ([[ "$TARGET" =~ (debian|ubuntu) ]] && installMCDEB) ||
([[ "$TARGET" =~ (fedora|centos|suse) ]] && ([[ "$TARGET" =~ (fedora|centos|suse) ]] &&
installPackage --skip-check-installed --nogpgcheck "$MCRPM"); then installPackage --skip-check-installed --nogpgcheck "$MCRPM") ||
([[ "$TARGET" == "arch" ]] && installMCArch); then
echo "JRiver Media Center installed successfully from local package" echo "JRiver Media Center installed successfully from local package"
else else
err "JRiver Media Center local package installation failed" err "JRiver Media Center local package installation failed"
@@ -1533,7 +1535,7 @@ main() {
fi fi
symlinkCerts symlinkCerts
restoreLicense restoreLicense
openFirewall "jriver" openFirewall "jriver-mediacenter"
fi fi
if (( CREATEREPO_SWITCH )); then if (( CREATEREPO_SWITCH )); then