17 Commits 7d0570daff ... 363f67b425

Author SHA1 Message Date
  bryan 363f67b425 1.4.6 release 3 months ago
  bryan a70898f6cc Fix firewall uninstall 3 months ago
  bryan af22dc1aa5 Use --reinstall for local MC deb install 3 months ago
  bryan 63f40b4ca1 Initialize all switches as off in parse_input() 3 months ago
  bryan b1a4069b2e Declare switches as ints 3 months ago
  bryan 6545631890 Declare DEBUG as int 3 months ago
  bryan b0c100c006 Make certificate symlinking more robust 3 months ago
  bryan b9050e37bf Make certificate symlinking more robust 3 months ago
  bryan 83e117616f Make certificate symlinking more robust 3 months ago
  bryan 84cbeda628 Use JRiver provided SSL certs as fallback 3 months ago
  bryan bde01d6f66 Boost default MC_VERSION 3 months ago
  bryan d9e02e430d Remove legacy systemd services from uninstall() 3 months ago
  bryan 2883aed0ac Add empty case command for safety 3 months ago
  bryan 30ab6d9bac Don't print help on input error 3 months ago
  bryan 4dea07222c Allow service functions to be called indirectly 3 months ago
  bryan 148f614e4a Improve a few variable scopes 3 months ago
  bryan 5042ae25c3 Refactor OS auto-detection and fix case statements 3 months ago
2 changed files with 82 additions and 78 deletions
  1. 3 3
      README.md
  2. 79 75
      installJRMC

+ 3 - 3
README.md

@@ -29,7 +29,7 @@ $ installJRMC --help
 --compat
     Build/install MC without minimum dependency version requirements
 --mcversion VERSION
-    Build or install a specific MC version, ex. "33.0.37" or "33" (default: latest)
+    Build or install a specific MC version, ex. "33.0.49" or "33" (default: latest)
 --mcrepo REPO
     Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: latest official)
 --arch ARCH
@@ -122,9 +122,9 @@ Multiple services (but not `--service-types`) can be installed at one time using
 
     Install MC from the repository and start/enable `jriver-mediacenter.service` as a user service.
 
-* `installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 33.0.37`
+* `installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 33.0.49`
 
-    Build and install an MC 33.0.37 compatibility RPM locally and activate it using the `/path/to/license.mjr`
+    Build and install an MC 33.0.49 compatibility RPM locally and activate it using the `/path/to/license.mjr`
 
 * `installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user`
 

+ 79 - 75
installJRMC

@@ -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