Refactor repository install flow

This commit is contained in:
2026-01-15 21:22:30 -05:00
parent e4f6d91bf4
commit 64814842c2

View File

@@ -2,7 +2,7 @@
# @file installJRMC # @file installJRMC
# @brief Installs JRiver Media Center and associated services # @brief Installs JRiver Media Center and associated services
# @description See installJRMC --help or print_help() below for usage # @description See installJRMC --help or print_help() below for usage
# Copyright (c) 2021-2025 Bryan C. Roessler # Copyright (c) 2021-2026 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
# #
@@ -352,35 +352,30 @@ init() {
PKG_REMOVE=(sudo "$rpm_mgr" remove --assumeyes) PKG_REMOVE=(sudo "$rpm_mgr" remove --assumeyes)
PKG_UPDATE=(sudo "$rpm_mgr" makecache --assumeyes) PKG_UPDATE=(sudo "$rpm_mgr" makecache --assumeyes)
PKG_QUERY=(rpm -q) PKG_QUERY=(rpm -q)
PKG_INSTALL_LOCAL() { install_mc_rpm; }
;; ;;
debian|ubuntu) debian|ubuntu)
PKG_INSTALL=(sudo apt-get install --fix-broken --install-recommends --assume-yes) PKG_INSTALL=(sudo apt-get install --fix-broken --install-recommends --assume-yes)
PKG_REMOVE=(sudo apt-get remove --auto-remove --assume-yes) PKG_REMOVE=(sudo apt-get remove --auto-remove --assume-yes)
PKG_UPDATE=(sudo apt-get update --assume-yes) PKG_UPDATE=(sudo apt-get update --assume-yes)
PKG_QUERY=(dpkg -s) PKG_QUERY=(dpkg -s)
PKG_INSTALL_LOCAL() { install_mc_deb "$@"; }
;; ;;
suse) suse)
PKG_INSTALL=(sudo zypper --gpg-auto-import-keys --non-interactive install --force --force-resolution --replacefiles --no-confirm) PKG_INSTALL=(sudo zypper --gpg-auto-import-keys --non-interactive install --force --force-resolution --replacefiles --no-confirm)
PKG_REMOVE=(sudo zypper --non-interactive remove --clean-deps) PKG_REMOVE=(sudo zypper --non-interactive remove --clean-deps)
PKG_UPDATE=(sudo zypper --non-interactive refresh jriver) PKG_UPDATE=(sudo zypper --non-interactive refresh jriver)
PKG_QUERY=(rpm --query) PKG_QUERY=(rpm --query)
PKG_INSTALL_LOCAL() { install_mc_rpm; }
;; ;;
arch) arch)
PKG_INSTALL=(sudo pacman --sync --refresh --noconfirm) PKG_INSTALL=(sudo pacman --sync --refresh --noconfirm)
PKG_REMOVE=(sudo pacman --remove --recursive --noconfirm) PKG_REMOVE=(sudo pacman --remove --recursive --noconfirm)
PKG_UPDATE=(sudo pacman --sync --refresh --refresh) PKG_UPDATE=(sudo pacman --sync --refresh --refresh)
PKG_QUERY=(sudo pacman --query --search) PKG_QUERY=(sudo pacman --query --search)
PKG_INSTALL_LOCAL() { install_mc_arch; }
;; ;;
unknown) unknown)
PKG_INSTALL=(:) PKG_INSTALL=(:)
PKG_REMOVE=(:) PKG_REMOVE=(:)
PKG_UPDATE=(:) PKG_UPDATE=(:)
PKG_QUERY=(:) PKG_QUERY=(:)
PKG_INSTALL_LOCAL() { install_mc_generic; }
;; ;;
esac esac
@@ -546,7 +541,7 @@ install_package() {
return 0 return 0
} }
# @description install host-specific external repos # @description Installs host-specific external repos
install_external_repos() { install_external_repos() {
debug "${FUNCNAME[0]}()" debug "${FUNCNAME[0]}()"
@@ -573,8 +568,6 @@ install_external_repos() {
install_package --no-install-check \ install_package --no-install-check \
"https://download1.rpmfusion.org/free/el/rpmfusion-free-release-${VERSION_ID%%.*}.noarch.rpm" "https://download1.rpmfusion.org/free/el/rpmfusion-free-release-${VERSION_ID%%.*}.noarch.rpm"
fi fi
# Install mesa-va-drivers-freeworld separately from the RPM using dnf swap
# install_mesa_freeworld # no longer provided by RPMFusion for EL9, etc.
;; ;;
fedora) fedora)
if ! "${PKG_QUERY[@]}" rpmfusion-free-release &>/dev/null; then if ! "${PKG_QUERY[@]}" rpmfusion-free-release &>/dev/null; then
@@ -599,12 +592,55 @@ install_external_repos() {
esac esac
} }
# @description Installs host-specific temporary legacy repo for missing dependencies
install_legacy_repo() {
debug "${FUNCNAME[0]}()"
local major_version="${VERSION_ID%%.*}"
local minor_version="${VERSION_ID##*.}"; minor_version="${minor_version#0}" # strip leading zero
local repo_name repo_uri repo_suite repo_key temp_repo_file
case $ID in
ubuntu)
if [[ $major_version -gt 24 || ( $major_version -eq 24 && minor_version -ge 4 ) ]]; then
echo "Temporarily adding jammy repository for libwebkit2gtk-4.0-37, etc."
repo_name="ubuntu-jammy-temp"
repo_uri="https://archive.ubuntu.com/ubuntu"
repo_suite="jammy"
repo_key="/usr/share/keyrings/ubuntu-archive-keyring.gpg"
fi
;;
debian)
if [[ $major_version -ge 13 ]]; then
echo "Temporarily adding bookworm repository for libwebkit2gtk-4.0-37, etc."
repo_name="debian-bookworm-temp"
repo_uri="https://deb.debian.org/debian"
repo_suite="bookworm"
repo_key="/usr/share/keyrings/debian-archive-keyring.gpg"
fi
;;
esac
if [[ -n $repo_name ]]; then
echo "Adding temporary repository: $repo_name"
temp_repo_file="/etc/apt/sources.list.d/$repo_name.sources"
sudo tee "$temp_repo_file" &>/dev/null <<-EOF
Types: deb
URIs: $repo_uri
Suites: $repo_suite
Components: main
Architectures: $MC_ARCH
Signed-By: $repo_key
EOF
# Set a trap to always cleanup legacy repo
# shellcheck disable=SC2064
trap "sudo rm -f $temp_repo_file" EXIT ERR INT
fi
}
# @description Installs mesa-va-drivers-freeworld on Fedora # @description Installs mesa-va-drivers-freeworld on Fedora
install_mesa_freeworld() { install_mesa_freeworld() {
debug "${FUNCNAME[0]}()" debug "${FUNCNAME[0]}()"
local pkg freeworld_pkg local pkg freeworld_pkg
case $ID in
fedora)
for pkg in mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers; do for pkg in mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers; do
freeworld_pkg="${pkg}-freeworld" freeworld_pkg="${pkg}-freeworld"
if ! "${PKG_QUERY[@]}" "$freeworld_pkg" &>/dev/null; then if ! "${PKG_QUERY[@]}" "$freeworld_pkg" &>/dev/null; then
@@ -617,123 +653,7 @@ install_mesa_freeworld() {
fi fi
fi fi
done done
;;
esac
}
# @description Installs JRiver Media Center from a remote repository
install_mc_repo() {
debug "${FUNCNAME[0]}()"
local repo_file repo_text channel
case $ID in
fedora|centos)
repo_file="/etc/yum.repos.d/jriver.repo"
read -r -d '' repo_text <<-EOF
[jriver]
baseurl = https://repos.bryanroessler.com/jriver
enabled = 1
gpgcheck = 0
name = JRiver Media Center by BryanC
EOF
;;
debian|ubuntu)
[[ -n $BETAPASS ]] && channel="beta" || channel="latest"
local major_version="${VERSION_ID%%.*}"
local keyfile="/usr/share/keyrings/jriver-com-archive-keyring.gpg"
if [[ ($ID == "ubuntu" && $major_version -ge 24) ||
($ID == "debian" && (-z $major_version || $major_version -ge 12)) ]]; then
if [[ $channel == "beta" ]]; then
repo_file="/etc/apt/sources.list.d/jriver-beta.sources"
else
repo_file="/etc/apt/sources.list.d/jriver.sources"
fi
# Remove deprecated repo files
old_repo_files=(
"/etc/apt/sources.list.d/jriver.list"
"/etc/apt/sources.list.d/jriver-beta.list"
"/etc/apt/sources.list.d/jriver_beta.list"
)
for f in "${old_repo_files[@]}"; do
[[ -f $f ]] && execute sudo rm -f "$f"
done
read -r -d '' repo_text <<-EOF
Types: deb
URIs: https://dist.jriver.com/$channel/mediacenter/
Signed-By: $keyfile
Suites: $MC_REPO
Components: main
Architectures: amd64 armhf arm64
EOF
else
if [[ $channel == "beta" ]]; then
execute sudo rm -f "/etc/apt/sources.list.d/jriver_beta.list"
repo_file="/etc/apt/sources.list.d/jriver-beta.list"
else
repo_file="/etc/apt/sources.list.d/jriver.list"
fi
repo_text="deb [signed-by=$keyfile arch=amd64,armhf,arm64] https://dist.jriver.com/$channel/mediacenter/ $MC_REPO main"
fi
echo "Installing JRiver Media Center GPG key"
download "https://dist.jriver.com/mediacenter@jriver.com.gpg.key" "-" |
gpg --dearmor | sudo tee "$keyfile" &>/dev/null
;;
*)
err "An MC repository for $ID is not yet available"
err "Use --install=local to install MC on $ID"
return 1
;;
esac
# Remove existing repository file if it exists
[[ -f $repo_file ]] && execute sudo rm -f "$repo_file"
echo "Adding MC repository file: $repo_file"
debug "$repo_text"
sudo tee "$repo_file" &>/dev/null <<< "$repo_text"
# Add older repository for libwebkit2gtk-4.0-37, etc, on newer Debian/Ubuntu
if add_temp_repo; then
debug "Removing temporary repository: $TEMP_REPO_FILE"
trap 'execute sudo rm -f "$TEMP_REPO_FILE"' EXIT
echo "Removed temporary repository"
else
err "Failed to add temporary repository"
return 1
fi
# Update package lists
if ! execute "${PKG_UPDATE[@]}"; then
err "Package update failed!"
if [[ $MC_REPO != "$MC_REPO_HARDCODE" ]] &&
ask_ok "Re-run installJRMC with --mcrepo=$MC_REPO_HARDCODE?"; then
exec "$SCRIPT_PATH" "$@" "--no-update" "--mcrepo=$MC_REPO_HARDCODE"
fi
return 1
fi
echo "Installing $MC_PKG package"
if ! install_package \
--no-install-check \
--allow-downgrades \
--no-gpg-check \
--reinstall \
"$MC_PKG"; then
err "Package install failed!"
return 1
fi
# Unset the trap and remove temporary legacy repository
trap - EXIT
if [[ -f $TEMP_REPO_FILE ]]; then
debug "Removing temporary repository: $TEMP_REPO_FILE"
execute sudo rm -f "$TEMP_REPO_FILE"
echo "Removed temporary repository"
fi
return 0
} }
# @description Acquires the source DEB package from JRiver # @description Acquires the source DEB package from JRiver
@@ -1113,14 +1033,7 @@ install_mc_deb() {
fi fi
# Add older repository for libwebkit2gtk-4.0-37, etc, on newer Debian/Ubuntu # Add older repository for libwebkit2gtk-4.0-37, etc, on newer Debian/Ubuntu
if add_temp_repo; then install_legacy_repo
debug "Removing temporary repo"
trap 'execute sudo rm -f "$TEMP_REPO_FILE"' EXIT
debug "Removed temporary repo"
else
err "Failed to add temporary repository"
return 1
fi
execute "${PKG_UPDATE[@]}" || { err "Package update failed!"; return 1; } execute "${PKG_UPDATE[@]}" || { err "Package update failed!"; return 1; }
# Copy the DEB to a temporary file so _apt can read it # Copy the DEB to a temporary file so _apt can read it
@@ -1138,25 +1051,17 @@ install_mc_deb() {
--reinstall \ --reinstall \
"$temp_deb"; then "$temp_deb"; then
err "Local MC DEB installation failed" err "Local MC DEB installation failed"
execute sudo rm -f "$temp_deb"
if ask_ok "Remove source DEB and retry?"; then if ask_ok "Remove source DEB and retry?"; then
execute sudo rm -f "$MC_DEB" "$temp_deb" execute sudo rm -f "$MC_DEB"
exec "$SCRIPT_PATH" "$@" "--no-update" exec "$SCRIPT_PATH" "$@" "--no-update"
fi fi
return 1
fi fi
# Unset the trap and remove temporary legacy repository
trap - EXIT
[[ -f $TEMP_REPO_FILE ]] && execute sudo rm -f "$TEMP_REPO_FILE"
execute sudo rm -f "$temp_deb" execute sudo rm -f "$temp_deb"
return 0 return 0
} }
# @description Installs MC via RPM package
install_mc_rpm() {
debug "${FUNCNAME[0]}()"
install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_RPM"
}
# @description Installs Media Center generically for unsupported OSes # @description Installs Media Center generically for unsupported OSes
install_mc_generic() { install_mc_generic() {
debug "${FUNCNAME[0]}()" debug "${FUNCNAME[0]}()"
@@ -1869,8 +1774,8 @@ main() {
((UNINSTALL_SWITCH)) && uninstall ((UNINSTALL_SWITCH)) && uninstall
# Exit now if only --uninstall is passed # Exit now if only --uninstall is passed
if ! (( BUILD_SWITCH || CREATEREPO_SWITCH || REPO_INSTALL_SWITCH || LOCAL_INSTALL_SWITCH || if ((UNINSTALL_SWITCH)) &&
CONTAINER_INSTALL_SWITCH || SNAP_INSTALL_SWITCH || APPIMAGE_INSTALL_SWITCH )) && ! ((BUILD_SWITCH || CREATEREPO_SWITCH || REPO_INSTALL_SWITCH || LOCAL_INSTALL_SWITCH)) &&
[[ ${#SERVICES[@]} -eq 0 && ${#CONTAINERS[@]} -eq 0 ]]; then [[ ${#SERVICES[@]} -eq 0 && ${#CONTAINERS[@]} -eq 0 ]]; then
exit 0 exit 0
fi fi
@@ -1879,16 +1784,86 @@ main() {
if ((REPO_INSTALL_SWITCH)); then if ((REPO_INSTALL_SWITCH)); then
echo "Installing JRiver Media Center from remote repository" echo "Installing JRiver Media Center from remote repository"
if install_mc_repo "$@"; then local repo_file
echo "JRiver Media Center installed successfully from remote repository"
case $ID in
fedora|centos)
repo_file="/etc/yum.repos.d/jriver.repo"
echo "Installing repository file: $repo_file"
sudo tee "$repo_file" &>/dev/null <<-EOF
[jriver]
baseurl = https://repos.bryanroessler.com/jriver
enabled = 1
gpgcheck = 0
name = JRiver Media Center hosted by BryanC
EOF
case $ID in
fedora)
install_mesa_freeworld install_mesa_freeworld
;;
esac
;;
debian|ubuntu)
local major_version="${VERSION_ID%%.*}"
local minor_version="${VERSION_ID##*.}"; minor_version="${minor_version#0}" # strip leading zero
local keyfile="/usr/share/keyrings/jriver-com-archive-keyring.gpg"
local channel="latest"
[[ -n $BETAPASS ]] && channel="beta"
if [[ $channel == "beta" ]]; then
repo_file="/etc/apt/sources.list.d/jriver-beta.sources"
else
repo_file="/etc/apt/sources.list.d/jriver.sources"
fi
echo "Installing repository file: $repo_file"
if [[ ($ID == "ubuntu" && $major_version -ge 24) ||
($ID == "debian" && (-z $major_version || $major_version -ge 12)) ]]; then
sudo tee "$repo_file" &>/dev/null <<-EOF
Types: deb
URIs: https://dist.jriver.com/$channel/mediacenter/
Signed-By: $keyfile
Suites: $MC_REPO
Components: main
Architectures: amd64 armhf arm64
EOF
else
sudo tee "$repo_file" &>/dev/null <<-EOF
deb [signed-by=$keyfile arch=amd64,armhf,arm64] https://dist.jriver.com/$channel/mediacenter/ $MC_REPO main
EOF
fi
echo "Installing JRiver Media Center GPG key"
download "https://dist.jriver.com/mediacenter@jriver.com.gpg.key" "-" |
gpg --dearmor | sudo tee "$keyfile" &>/dev/null
install_legacy_repo
;;
*)
err "An MC repository for $ID is not yet available"
err "Use --install=local to install MC on $ID"
return 1
;;
esac
echo "Updating package lists"
if ! execute "${PKG_UPDATE[@]}"; then
err "Package update failed!"
if [[ $MC_REPO != "$MC_REPO_HARDCODE" ]] &&
ask_ok "Re-run installJRMC with --mcrepo=$MC_REPO_HARDCODE?"; then
exec "$SCRIPT_PATH" "$@" "--no-update" "--mcrepo=$MC_REPO_HARDCODE"
fi
return 1
fi
echo "Installing $MC_PKG package"
if ! install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_PKG"; then
err "MC package install failed!"
return 1
fi
link_ssl_certs link_ssl_certs
restore_license restore_license
open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp" open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp"
else
err "JRiver Media Center installation from remote repository failed"
return 1
fi
fi fi
if ((BUILD_SWITCH)); then if ((BUILD_SWITCH)); then
@@ -1923,13 +1898,16 @@ main() {
if ((LOCAL_INSTALL_SWITCH)); then if ((LOCAL_INSTALL_SWITCH)); then
echo "Installing JRiver Media Center from local package" echo "Installing JRiver Media Center from local package"
if PKG_INSTALL_LOCAL "$@"; then
echo "JRiver Media Center installed successfully from local package" # Install MC package
else case $ID in
err "JRiver Media Center local package installation failed" fedora) install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_RPM"; install_mesa_freeworld ;;
return 1 centos|mandriva|suse) install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_RPM" ;;
fi debian|ubuntu) install_mc_deb "$@" ;;
install_mesa_freeworld arch) install_mc_arch ;;
unknown) install_mc_generic ;;
esac
link_ssl_certs link_ssl_certs
restore_license restore_license
open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp" open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp"
@@ -2017,15 +1995,17 @@ create_mc_apt_container() {
debug "${FUNCNAME[0]}()" "$@" debug "${FUNCNAME[0]}()" "$@"
declare -g CNT declare -g CNT
local -a cmds=("$@") local -a cmds=("$@")
local channel="latest"
[[ -n $BETAPASS ]] && channel="beta"
# shellcheck disable=SC2016 # shellcheck disable=SC2016
{ command -v buildah &>/dev/null || install_package buildah; } && { command -v buildah &>/dev/null || install_package buildah; } &&
CNT=$(buildah from --quiet alpine:edge) && CNT=$(buildah from --quiet alpine:edge) &&
buildah run --env MC_REPO="$MC_REPO" --env MC_ARCH="$MC_ARCH" "$CNT" -- sh -c ' buildah run --env MC_REPO="$MC_REPO" --env MC_ARCH="$MC_ARCH" --env CHANNEL="$channel" "$CNT" -- sh -c '
apk add --quiet --no-progress --no-cache apt curl gnupg apk add --quiet --no-progress --no-cache apt curl gnupg
curl -fsSL https://dist.jriver.com/mediacenter@jriver.com.gpg.key | gpg --quiet --dearmor -o /usr/share/keyrings/jriver-com-archive-keyring.gpg curl -fsSL https://dist.jriver.com/mediacenter@jriver.com.gpg.key | gpg --quiet --dearmor -o /usr/share/keyrings/jriver-com-archive-keyring.gpg
cat <<-EOF > /etc/apt/sources.list.d/jriver.sources cat <<-EOF > /etc/apt/sources.list.d/jriver.sources
Types: deb Types: deb
URIs: https://dist.jriver.com/latest/mediacenter/ URIs: https://dist.jriver.com/$CHANNEL/mediacenter/
Signed-By: /usr/share/keyrings/jriver-com-archive-keyring.gpg Signed-By: /usr/share/keyrings/jriver-com-archive-keyring.gpg
Suites: $MC_REPO Suites: $MC_REPO
Components: main Components: main
@@ -2037,51 +2017,6 @@ create_mc_apt_container() {
buildah run "$CNT" -- sh -c "$cmd" || { err "$cmd failed"; return 1; } buildah run "$CNT" -- sh -c "$cmd" || { err "$cmd failed"; return 1; }
done done
} }
add_temp_repo() {
debug "${FUNCNAME[0]}()"
local repo_name repo_uri repo_suite repo_key
if [[ "$ID" == "ubuntu" ]]; then
local major_version="${VERSION_ID%%.*}"
local minor_version="${VERSION_ID##*.}"
minor_version="${minor_version#0}" # strip leading zero
if [[ $major_version -gt 24 || ( $major_version -eq 24 && minor_version -ge 4 ) ]]; then
echo "Temporarily adding jammy repository for libwebkit2gtk-4.0-37, etc."
repo_name="ubuntu-jammy-temp"
repo_uri="https://archive.ubuntu.com/ubuntu"
repo_suite="jammy"
repo_key="/usr/share/keyrings/ubuntu-archive-keyring.gpg"
else
return 0
fi
elif [[ "$ID" == "debian" ]]; then
local major_version="${VERSION_ID%%.*}"
if [[ $major_version -ge 13 ]]; then
echo "Temporarily adding bookworm repository for libwebkit2gtk-4.0-37, etc."
repo_name="debian-bookworm-temp"
repo_uri="https://deb.debian.org/debian"
repo_suite="bookworm"
repo_key="/usr/share/keyrings/debian-archive-keyring.gpg"
else
return 0
fi
else
# For other distributions, do nothing.
return 0
fi
declare -g TEMP_REPO_FILE="/etc/apt/sources.list.d/${repo_name}.sources"
echo "Creating temporary repository file $TEMP_REPO_FILE for $repo_suite"
sudo bash -c "cat <<-EOF > $TEMP_REPO_FILE
Types: deb
URIs: $repo_uri
Suites: $repo_suite
Components: main
Architectures: $MC_ARCH
Signed-By: $repo_key
EOF"
}
# Roughly turn debugging on for pre-init # Roughly turn debugging on for pre-init
# Reset and reparse in parse_input() with getopt # Reset and reparse in parse_input() with getopt