|
@@ -1,8 +1,8 @@
|
|
|
#!/usr/bin/env bash
|
|
|
+# shellcheck disable=SC2317
|
|
|
# @file installJRMC
|
|
|
# @brief Install JRiver Media Center and associated services
|
|
|
# @description See installJRMC --help or print_help() below for usage
|
|
|
-#
|
|
|
# Copyright (c) 2021-2024 Bryan C. Roessler
|
|
|
# This software is released under the Apache License.
|
|
|
# https://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -18,12 +18,13 @@
|
|
|
# * Be careful with tabs in heredocs
|
|
|
shopt -s extglob
|
|
|
|
|
|
-declare -g SCRIPT_VERSION="1.4.5"
|
|
|
+declare -g SCRIPT_VERSION="1.4.6"
|
|
|
declare -g MC_REPO="bullseye" # should match the MC_VERSION
|
|
|
-declare -g MC_VERSION="33.0.37" # Do find all replace
|
|
|
+declare -g MC_VERSION="33.0.49" # Do find all replace
|
|
|
declare -g BOARD_URL="https://yabb.jriver.com/interact/index.php/board,86.0.html" # MC33
|
|
|
-declare -ig UPDATE_SWITCH=1 # set to 0 to disable automatic self-update
|
|
|
+declare -gi UPDATE_SWITCH=1 # set to 0 to disable automatic self-update
|
|
|
declare -g SCRIPT_URL="https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC"
|
|
|
+declare -gi DEBUG=${DEBUG:-0} # det default debug and allow DEBUG env override (default: disabled)
|
|
|
|
|
|
# @description Print help text
|
|
|
print_help() {
|
|
@@ -113,9 +114,10 @@ print_help() {
|
|
|
# @arg $@ User input
|
|
|
parse_input() {
|
|
|
debug "Running: ${FUNCNAME[0]} $*"
|
|
|
- declare -g BUILD_SWITCH REPO_INSTALL_SWITCH LOCAL_INSTALL_SWITCH \
|
|
|
- CONTAINER_INSTALL_SWITCH COMPAT_SWITCH CREATEREPO_SWITCH UNINSTALL_SWITCH \
|
|
|
- YES_SWITCH USER_MC_VERSION USER_MC_REPO MJR_FILE \
|
|
|
+ declare -gi BUILD_SWITCH=0 REPO_INSTALL_SWITCH=0 LOCAL_INSTALL_SWITCH=0 \
|
|
|
+ CONTAINER_INSTALL_SWITCH=0 COMPAT_SWITCH=0 CREATEREPO_SWITCH=0 UNINSTALL_SWITCH=0 \
|
|
|
+ YES_SWITCH=0 DEBUG=0
|
|
|
+ declare -g USER_MC_VERSION USER_MC_REPO MJR_FILE \
|
|
|
BETAPASS SERVICE_TYPE VNCPASS USER_DISPLAY BUILD_TARGET CREATEREPO_TARGET
|
|
|
local long_opts short_opts input
|
|
|
long_opts="install:,build::,outputdir:,mcversion:,arch:,mcrepo:,compat,"
|
|
@@ -126,9 +128,6 @@ parse_input() {
|
|
|
long_opts+="vncpass:,display:,container:"
|
|
|
short_opts="+i:b::s:c:uyvdh"
|
|
|
|
|
|
- # Reset DEBUG and recatch properly with getopt
|
|
|
- declare -g DEBUG=0
|
|
|
-
|
|
|
if input=$(getopt -o $short_opts -l $long_opts -- "$@"); then
|
|
|
eval set -- "$input"
|
|
|
while true; do
|
|
@@ -195,7 +194,7 @@ parse_input() {
|
|
|
shift
|
|
|
done
|
|
|
else
|
|
|
- err "Incorrect options provided"; print_help; exit 1
|
|
|
+ err "Incorrect option provided, see installJRMC --help"; exit 1
|
|
|
fi
|
|
|
|
|
|
# Print some warnings for unsupported argument combinations
|
|
@@ -288,24 +287,31 @@ init() {
|
|
|
;;
|
|
|
*)
|
|
|
err "Auto-detecting distro, this is unreliable and --compat may be required"
|
|
|
- if command -v dnf &>/dev/null; then
|
|
|
- ID="fedora"
|
|
|
- elif command -v yum &>/dev/null; then
|
|
|
- ID="centos"
|
|
|
- COMPAT_SWITCH=1
|
|
|
- elif command -v apt-get &>/dev/null; then
|
|
|
- ID="ubuntu"
|
|
|
- elif command -v pacman &>/dev/null; then
|
|
|
- ID="arch"
|
|
|
- else
|
|
|
+ for cmd in dnf yum apt-get pacman; do
|
|
|
+ if command -v "$cmd" &>/dev/null; then
|
|
|
+ case "$cmd" in
|
|
|
+ dnf) ID="fedora" ;;
|
|
|
+ yum) ID="centos"; COMPAT_SWITCH=1 ;;
|
|
|
+ apt-get) ID="ubuntu" ;;
|
|
|
+ pacman) ID="arch" ;;
|
|
|
+ esac
|
|
|
+ break
|
|
|
+ fi
|
|
|
+ done
|
|
|
+
|
|
|
+ if [[ -z $ID ]]; then
|
|
|
err "OS detection failed!"
|
|
|
- ask_ok "Continue with manual installation?" || exit 1
|
|
|
- debug "Automatically using --install=local for unknown distro"
|
|
|
- ID="unknown"
|
|
|
- REPO_INSTALL_SWITCH=0
|
|
|
- BUILD_SWITCH=1
|
|
|
- LOCAL_INSTALL_SWITCH=1
|
|
|
+ if ask_ok "Continue with manual installation?"; then
|
|
|
+ debug "Automatically using --install=local for unknown distro"
|
|
|
+ ID="unknown"
|
|
|
+ REPO_INSTALL_SWITCH=0
|
|
|
+ BUILD_SWITCH=1
|
|
|
+ LOCAL_INSTALL_SWITCH=1
|
|
|
+ else
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
fi
|
|
|
+ ;;
|
|
|
esac
|
|
|
|
|
|
# Set default targets
|
|
@@ -366,6 +372,7 @@ init() {
|
|
|
PKG_UPDATE=(:)
|
|
|
PKG_QUERY=(:)
|
|
|
PKG_INSTALL_LOCAL() { install_mc_generic; }
|
|
|
+ ;;
|
|
|
esac
|
|
|
|
|
|
# Don't check for latest MC version if set by user or using --install=repo only
|
|
@@ -386,12 +393,8 @@ init() {
|
|
|
if [[ -n $USER_MC_VERSION ]]; then
|
|
|
# Append explicit package version when user provides --mcversion
|
|
|
case $ID in
|
|
|
- fedora|centos|suse)
|
|
|
- MC_PKG+="-$MC_VERSION"
|
|
|
- ;;
|
|
|
- debian|ubuntu)
|
|
|
- MC_PKG+="=$MC_VERSION"
|
|
|
- ;;
|
|
|
+ fedora|centos|suse) MC_PKG+="-$MC_VERSION" ;;
|
|
|
+ debian|ubuntu) MC_PKG+="=$MC_VERSION" ;;
|
|
|
esac
|
|
|
fi
|
|
|
|
|
@@ -442,8 +445,8 @@ install_package() {
|
|
|
local -a pkg_array install_flags
|
|
|
local -A pkg_aliases
|
|
|
local input pkg _pkg
|
|
|
- local no_install_check=0 allow_downgrades=0 silent=0 refresh=0 no_gpg_check=0
|
|
|
- local long_opts="no-install-check,allow-downgrades,no-gpg-check,refresh,silent"
|
|
|
+ local -i no_install_check=0 allow_downgrades=0 silent=0 refresh=0 no_gpg_check=0 reinstall=0
|
|
|
+ local long_opts="no-install-check,allow-downgrades,no-gpg-check,refresh,reinstall,silent"
|
|
|
|
|
|
input=$(getopt -o +s -l "$long_opts" -- "$@") || { err "Incorrect options provided"; exit 1; }
|
|
|
eval set -- "$input"
|
|
@@ -454,6 +457,7 @@ install_package() {
|
|
|
--allow-downgrades) allow_downgrades=1 ;;
|
|
|
--no-gpg-check) no_gpg_check=1 ;;
|
|
|
--refresh) refresh=1 ;;
|
|
|
+ --reinstall) reinstall=1 ;;
|
|
|
--silent|-s) silent=1 ;;
|
|
|
--) shift; break ;;
|
|
|
esac
|
|
@@ -502,7 +506,8 @@ install_package() {
|
|
|
# Generate installation flags based on the distribution
|
|
|
case $ID in
|
|
|
debian|ubuntu)
|
|
|
- ((allow_downgrades)) && install_flags+=(--allow-downgrades) ;;
|
|
|
+ ((allow_downgrades)) && install_flags+=(--allow-downgrades)
|
|
|
+ ((reinstall)) && install_flags+=(--reinstall) ;;
|
|
|
fedora|centos)
|
|
|
((allow_downgrades)) && install_flags+=(--allowerasing)
|
|
|
((no_gpg_check)) && install_flags+=(--nogpgcheck)
|
|
@@ -557,7 +562,7 @@ install_external_repos() {
|
|
|
# Install mesa-va-drivers-freeworld separately from the RPM using dnf swap
|
|
|
install_mesa_freeworld
|
|
|
;;
|
|
|
- suse) # TODO may eventually be needed if X11_XOrg is not available by default
|
|
|
+ suse) : # TODO may eventually be needed if X11_XOrg is not available by default
|
|
|
# if ! zypper repos | grep -q "X11_XOrg"; then
|
|
|
# echo "Installing the X11 repository"
|
|
|
# execute sudo zypper --non-interactive --quiet addrepo \
|
|
@@ -919,10 +924,12 @@ install_mc_deb() {
|
|
|
execute rm -rf "$extract_dir"
|
|
|
fi
|
|
|
|
|
|
+ # Use --reinstall to make sure local package is installed over repo package
|
|
|
if ! install_package \
|
|
|
--no-install-check \
|
|
|
--no-gpg-check \
|
|
|
--allow-downgrades \
|
|
|
+ --reinstall \
|
|
|
"$MC_DEB"; then
|
|
|
err "Local MC DEB installation failed"
|
|
|
err "Only the default MC repo can be used for --install=local"
|
|
@@ -946,7 +953,6 @@ install_mc_rhel() {
|
|
|
# @description Installs Media Center RPM package on SUSE
|
|
|
install_mc_suse() {
|
|
|
debug "Running: ${FUNCNAME[0]}"
|
|
|
-
|
|
|
install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_RPM"
|
|
|
}
|
|
|
|
|
@@ -1021,8 +1027,7 @@ install_mc_arch() {
|
|
|
--force \
|
|
|
--noconfirm \
|
|
|
-p mediacenter.pkgbuild; then
|
|
|
- echo "makepkg failed"
|
|
|
- exit 1
|
|
|
+ err "makepkg failed"; exit 1
|
|
|
fi
|
|
|
|
|
|
popd &>/dev/null || return
|
|
@@ -1038,8 +1043,8 @@ run_createrepo() {
|
|
|
# Ensure the webroot exists
|
|
|
if [[ ! -d $CREATEREPO_WEBROOT ]]; then
|
|
|
if ! execute sudo -u "$CREATEREPO_USER" mkdir -p "$CREATEREPO_WEBROOT"; then
|
|
|
- if ! execute sudo mkdir -p "$CREATEREPO_WEBROOT" &&
|
|
|
- ! execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"; then
|
|
|
+ if ! (execute sudo mkdir -p "$CREATEREPO_WEBROOT" \
|
|
|
+ || execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"); then
|
|
|
err "Could not create the createrepo-webroot path!"
|
|
|
err "Make sure that the webroot $CREATEREPO_WEBROOT is writable by user $CREATEREPO_USER"
|
|
|
err "Or change the repo ownership with --createrepo-user"
|
|
@@ -1049,8 +1054,8 @@ run_createrepo() {
|
|
|
fi
|
|
|
|
|
|
# Copy built RPMs to webroot
|
|
|
- if ! execute sudo cp -nf "$MC_RPM" "$CREATEREPO_WEBROOT" ||
|
|
|
- ! execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"; then
|
|
|
+ if ! execute sudo cp -nf "$MC_RPM" "$CREATEREPO_WEBROOT" \
|
|
|
+ || ! execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"; then
|
|
|
err "Could not copy $MC_RPM to $CREATEREPO_WEBROOT"
|
|
|
return 1
|
|
|
fi
|
|
@@ -1063,8 +1068,8 @@ run_createrepo() {
|
|
|
cr_cmd=(sudo createrepo -q "$CREATEREPO_WEBROOT")
|
|
|
[[ -d $CREATEREPO_WEBROOT/repodata ]] && cr_cmd+=(--update)
|
|
|
|
|
|
- if ! execute "${cr_cmd[@]}" ||
|
|
|
- ! execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"; then
|
|
|
+ if ! (execute "${cr_cmd[@]}" \
|
|
|
+ || execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"); then
|
|
|
err "createrepo failed"
|
|
|
return 1
|
|
|
fi
|
|
@@ -1078,20 +1083,21 @@ link_ssl_certs() {
|
|
|
local mc_cert_link="$MC_ROOT/ca-certificates.crt"
|
|
|
local -a source_certs=(
|
|
|
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"
|
|
|
- "/var/lib/ca-certificates/ca-bundle.pem")
|
|
|
+ "/var/lib/ca-certificates/ca-bundle.pem"
|
|
|
+ "$MC_ROOT/local-ca-certificates.crt")
|
|
|
|
|
|
target_cert=$(readlink -f "$mc_cert_link")
|
|
|
[[ -f $target_cert ]] && return 0
|
|
|
|
|
|
for f in "${source_certs[@]}"; do
|
|
|
if [[ -f $f ]]; then
|
|
|
- if ! execute sudo ln -fs "$f" "$mc_cert_link"; then
|
|
|
- err "Symlinking certificate failed"
|
|
|
- return 1
|
|
|
+ if execute sudo ln -fs "$f" "$mc_cert_link"; then
|
|
|
+ debug "Symlinked $mc_cert_link to $f"
|
|
|
+ return 0
|
|
|
fi
|
|
|
- break
|
|
|
fi
|
|
|
done
|
|
|
+ err "Certificate symlinking failed"; return 1
|
|
|
}
|
|
|
|
|
|
# @description Restore the mjr license file from MJR_FILE or other common locations
|
|
@@ -1137,13 +1143,13 @@ restore_license() {
|
|
|
# @arg $2 array List of ports in firewall-cmd format
|
|
|
open_firewall() {
|
|
|
debug "Running: ${FUNCNAME[0]}" "$*"
|
|
|
- local port
|
|
|
local service="$1"
|
|
|
shift
|
|
|
local -a f_ports=("$@") # for firewall-cmd
|
|
|
local u_ports="$*"
|
|
|
u_ports="${u_ports// /|}" # concatenate
|
|
|
u_ports="${u_ports//-/\:}" # for ufw
|
|
|
+ local port
|
|
|
|
|
|
if command -v firewall-cmd &>/dev/null; then
|
|
|
if ! sudo firewall-cmd --get-services | grep -q "$service"; then
|
|
@@ -1197,7 +1203,7 @@ set_vnc_pass() {
|
|
|
fi
|
|
|
return
|
|
|
else
|
|
|
- declare -g NOVNCAUTH=1
|
|
|
+ declare -gi NOVNCAUTH=1
|
|
|
fi
|
|
|
}
|
|
|
|
|
@@ -1494,13 +1500,13 @@ disable_btrfs_cow() {
|
|
|
# @description Completely uninstalls MC, services, and firewall rules
|
|
|
uninstall() {
|
|
|
debug "Running: ${FUNCNAME[0]}"
|
|
|
- local service unit f i
|
|
|
+ local service type unit f
|
|
|
|
|
|
echo "Stopping and removing all Media Center services"
|
|
|
for service in $(compgen -A "function" "service"); do
|
|
|
service="${service##service_}"
|
|
|
- for i in user system; do
|
|
|
- set_service_vars "$service" "$i";
|
|
|
+ for type in user system; do
|
|
|
+ set_service_vars "$service" "$type";
|
|
|
for unit in "$SERVICE_NAME" "$TIMER_NAME"; do
|
|
|
if "${IS_ACTIVE[@]}" "$unit" ||
|
|
|
"${IS_ENABLED[@]}" "$unit"; then
|
|
@@ -1508,16 +1514,10 @@ uninstall() {
|
|
|
fi
|
|
|
done
|
|
|
for f in "$SERVICE_FNAME" "$TIMER_FNAME"; do
|
|
|
- [[ -f $f ]] &&
|
|
|
- execute sudo rm -f "$f"
|
|
|
+ [[ -f $f ]] && execute sudo rm -f "$f"
|
|
|
done
|
|
|
"${RELOAD[@]}"
|
|
|
- unset f
|
|
|
- done
|
|
|
- for f in /etc/systemd/system/jriver-*; do
|
|
|
- execute sudo rm -f "$f"
|
|
|
done
|
|
|
- unset f
|
|
|
done
|
|
|
|
|
|
echo "Removing MC repositories"
|
|
@@ -1530,15 +1530,17 @@ uninstall() {
|
|
|
fi
|
|
|
|
|
|
echo "Removing firewall rules"
|
|
|
- if command -v firewall-cmd &>/dev/null; then
|
|
|
- execute sudo firewall-cmd --permanent --remove-service=jriver
|
|
|
- execute sudo firewall-cmd --permanent --delete-service=jriver
|
|
|
- execute sudo firewall-cmd --reload
|
|
|
- elif command -v ufw &>/dev/null; then
|
|
|
- execute sudo ufw delete allow jriver
|
|
|
- [[ -f "/etc/ufw/applications.d/jriver" ]] &&
|
|
|
- execute sudo rm -f /etc/ufw/applications.d/jriver
|
|
|
- fi
|
|
|
+ for service in jriver-mediacenter jriver-xvnc jriver-x11vnc; do
|
|
|
+ if command -v firewall-cmd &>/dev/null; then
|
|
|
+ execute sudo firewall-cmd --permanent --remove-service=$service
|
|
|
+ execute sudo firewall-cmd --permanent --delete-service=$service
|
|
|
+ execute sudo firewall-cmd --reload
|
|
|
+ elif command -v ufw &>/dev/null; then
|
|
|
+ execute sudo ufw delete allow $service
|
|
|
+ [[ -f /etc/ufw/applications.d/$service ]] &&
|
|
|
+ execute sudo rm -f /etc/ufw/applications.d/$service
|
|
|
+ fi
|
|
|
+ done
|
|
|
|
|
|
echo "Uninstalling JRiver Media Center package"
|
|
|
if "${PKG_REMOVE[@]}" "${MC_PKG%%=*}"; then # remove version specifier
|
|
@@ -1752,7 +1754,7 @@ main() {
|
|
|
debug() { ((DEBUG)) && echo "Debug: $*"; }
|
|
|
err() { echo "Error: $*" >&2; }
|
|
|
ask_ok() {
|
|
|
- declare response
|
|
|
+ local response
|
|
|
((YES_SWITCH)) && return 0
|
|
|
read -r -p "$* [y/N]: " response
|
|
|
[[ ${response,,} =~ ^(yes|y)$ ]]
|
|
@@ -1798,7 +1800,9 @@ download() {
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
-# Roughly turn debugging on, reparse in parse_input() with getopt
|
|
|
-[[ " $* " =~ ( --debug | -d ) ]] && declare -g DEBUG=1
|
|
|
+# Roughly turn debugging on for pre-init
|
|
|
+# Reset and reparse in parse_input() with getopt
|
|
|
+[[ " $* " =~ ( --debug | -d ) ]] && DEBUG=1
|
|
|
|
|
|
main "$@"
|
|
|
+exit
|