43 Commits

Author SHA1 Message Date
6fd257963d 1.4.0 release 2024-11-04 14:50:11 -05:00
4fd2901628 Formatting 2024-11-04 14:47:43 -05:00
fe56081a51 Alias fuse-overlayfs and buildah on SUSE 2024-11-04 14:42:27 -05:00
c6dfd62036 Test commit for refactored update() 2024-11-04 14:22:36 -05:00
322c65e191 Test commit for refactored update() 2024-11-04 14:21:06 -05:00
09031480c2 Add some debug output 2024-11-04 14:06:20 -05:00
711ee5621a Formatting 2024-11-04 14:01:11 -05:00
f53e883b96 Set distro-specific commands before get_latest_mc_version() 2024-11-04 13:55:07 -05:00
8998a6d02e Test commit for silencing buildah not found error 2024-11-04 13:49:12 -05:00
6aba702eb6 Test commit for silencing buildah not found error 2024-11-04 13:48:04 -05:00
011c9e06a8 Test commit for silencing buildah not found error 2024-11-04 13:46:31 -05:00
31abe6385c Test commit for silencing buildah not found error 2024-11-04 13:44:58 -05:00
ce81c689df Test commit for silencing buildah not found error 2024-11-04 13:43:31 -05:00
da5f765168 Test commit for silencing buildah not found error 2024-11-04 13:42:51 -05:00
37d30420fc Test commit for silencing buildah not found error 2024-11-04 13:41:59 -05:00
7058475232 Test commit for silencing buildah not found error 2024-11-04 13:33:20 -05:00
5bf62dc9d9 Test commit for silencing buildah not found error 2024-11-04 13:29:59 -05:00
5259bbaf99 Test commit for silencing buildah not found error 2024-11-04 13:12:42 -05:00
b0f31ed3f0 Fix --install=local on SUSE 2024-11-04 13:07:31 -05:00
f29945d681 Improve formatting 2024-11-04 13:02:00 -05:00
c31b20ccce Improve formatting 2024-11-04 12:58:07 -05:00
57768c9dfb Match uninstall() output 2024-11-04 12:51:44 -05:00
413580f4ef For uninstall() strip package version specifier 2024-11-04 12:44:38 -05:00
7b924710b4 Add sanity warnings 2024-11-04 12:39:58 -05:00
98f898f0e3 Add return code to local deb install failure 2024-11-04 12:02:56 -05:00
76370a8be8 Remove and reacquire broken DEB 2024-11-04 11:51:41 -05:00
d9b5657c67 use --silent for install_package() 2024-11-04 11:40:21 -05:00
2566491f82 Formatting 2024-11-04 11:37:35 -05:00
d1fb17b86e Revert to dev and fix comments 2024-11-04 11:33:54 -05:00
d68e4c7587 Invert ZorinOS workaround 2024-11-04 11:31:31 -05:00
f16d3ac096 Fix download_cmd declaration 2024-11-04 11:21:10 -05:00
161652f7b6 Formatting 2024-11-04 11:16:16 -05:00
b41b75ff64 Use exit codes, don't wrap download() with execute() 2024-11-04 11:09:06 -05:00
a130da3e26 Catch download failures in download() 2024-11-04 11:07:19 -05:00
2c53ec9f41 Fix download argument ordering 2024-11-04 10:56:20 -05:00
1a656322e2 Add download() helper function 2024-11-04 10:50:16 -05:00
407cd61710 More formatting fixes 2024-11-04 09:42:16 -05:00
cac81be1d4 Formatting 2024-11-04 09:38:40 -05:00
840e7f3b8e 1.3.10 test release 2024-11-04 09:30:15 -05:00
49ae5879be Stash changes before git self-update 2024-11-04 09:27:38 -05:00
0a451a1ad1 Stash changes before git self-update 2024-11-04 09:26:09 -05:00
a2ed872f15 Fix semantic version comaprison in self-update 2024-11-04 09:19:25 -05:00
c2af8fef1b Remove legacy repos on latest Ubuntu 2024-11-04 08:55:19 -05:00
2 changed files with 255 additions and 208 deletions

View File

@@ -1,14 +1,16 @@
# installJRMC # installJRMC
This self-contained program will install [JRiver Media Center](https://www.jriver.com/) and associated services on most major Linux distros. This self-contained program will install [JRiver Media Center](https://www.jriver.com/) and associated services on most Linux distributions.
You can always find the latest version of installJRMC, changelog, and documentation in [my repository](https://git.bryanroessler.com/bryan/installJRMC). You can find the latest version of installJRMC, changelog, and documentation in [my repository](https://git.bryanroessler.com/bryan/installJRMC).
## Executing ## Executing
`installJRMC [--option [ARGUMENT]]` `installJRMC [--option [ARGUMENT]]`
Running `installJRMC` without any options implies `--install repo` and will install the latest version of JRiver Media Center (MC) from the official JRiver repository (Ubuntu/Debian) or my [unofficial repository](https://repos.bryanroessler.com/jriver/) (Fedora/CentOS) using the system package manager. If any other option is passed, then the default install method (i.e. `--install repo` or `--install local`) must be specified (to allow services and containers to be installed independent of MC). Running `installJRMC` without any options implies `--install repo` (on SUSE: `--install local`) and will install the latest version of Media Center from the official JRiver repository (Ubuntu/Debian) or my [unofficial repository](https://repos.bryanroessler.com/jriver/) (Fedora/CentOS) using the system package manager. If `--service` or `--container` is passed then the default install method (`--install repo` or `--install local`) must be specified (to allow services and containers to be installed independent of MC).
Recent versions of installJRMC will automatically self-update to the latest installJRMC release.
## tl;dr ## tl;dr

View File

@@ -8,19 +8,22 @@
# https://www.apache.org/licenses/LICENSE-2.0 # https://www.apache.org/licenses/LICENSE-2.0
# #
# TODO (v2) # TODO (v2)
# 1. Interactive mode # * Interactive mode
# 2. Additional containerization (createrepo and rpmbuild) # * Additional containerization (createrepo and rpmbuild)
# #
# BUGS # BUGS
# 1. No createrepo on Mint # * No createrepo on Mint
#
# NOTES
# * Be careful with tabs in heredocs
shopt -s extglob shopt -s extglob
declare -g SCRIPT_VERSION="1.3.9" declare -g SCRIPT_VERSION="1.4.0"
declare -g MC_REPO="bullseye" # should match the MC_VERSION 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.37" # Do find all replace
declare -g BOARD_URL="https://yabb.jriver.com/interact/index.php/board,86.0.html" # MC33 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 -ig UPDATE_SWITCH=1 # set to 0 to disable automatic self-update
declare -g SCRIPT_URL="https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC"
# @description Print help text # @description Print help text
print_help() { print_help() {
@@ -72,7 +75,7 @@ print_help() {
--uninstall, -u --uninstall, -u
Uninstall JRiver MC, remove services, containers, and firewall rules (does not remove library files) Uninstall JRiver MC, remove services, containers, and firewall rules (does not remove library files)
--yes, -y, --auto --yes, -y, --auto
Always assume yes for questions Assume yes response to questions
--version, -v --version, -v
Print this script version and exit Print this script version and exit
--debug, -d --debug, -d
@@ -110,13 +113,11 @@ print_help() {
# @arg $@ User input # @arg $@ User input
parse_input() { parse_input() {
debug "Running: ${FUNCNAME[0]} $*" debug "Running: ${FUNCNAME[0]} $*"
declare -g BUILD_SWITCH REPO_INSTALL_SWITCH LOCAL_INSTALL_SWITCH \ declare -g BUILD_SWITCH REPO_INSTALL_SWITCH LOCAL_INSTALL_SWITCH \
COMPAT_SWITCH CREATEREPO_SWITCH UNINSTALL_SWITCH \ COMPAT_SWITCH CREATEREPO_SWITCH UNINSTALL_SWITCH \
YES_SWITCH USER_MC_VERSION USER_MC_REPO MJR_FILE \ YES_SWITCH USER_MC_VERSION USER_MC_REPO MJR_FILE \
BETAPASS SERVICE_TYPE VNCPASS USER_DISPLAY \ BETAPASS SERVICE_TYPE VNCPASS USER_DISPLAY \
BUILD_TARGET CREATEREPO_TARGET BUILD_TARGET CREATEREPO_TARGET
local long_opts short_opts input local long_opts short_opts input
long_opts="install:,build::,outputdir:,mcversion:,arch:,mcrepo:,compat," long_opts="install:,build::,outputdir:,mcversion:,arch:,mcrepo:,compat,"
long_opts+="restorefile:,betapass:," long_opts+="restorefile:,betapass:,"
@@ -174,10 +175,8 @@ parse_input() {
--betapass) shift; BETAPASS="$1" ;; --betapass) shift; BETAPASS="$1" ;;
--service-type) shift; SERVICE_TYPE="$1" ;; --service-type) shift; SERVICE_TYPE="$1" ;;
--service|-s|--services) shift; SERVICES+=("$1") ;; --service|-s|--services) shift; SERVICES+=("$1") ;;
--createrepo) --createrepo) shift; CREATEREPO_TARGET="$1"; BUILD_TARGET="$1"
BUILD_SWITCH=1; CREATEREPO_SWITCH=1 BUILD_SWITCH=1; CREATEREPO_SWITCH=1 ;;
shift; CREATEREPO_TARGET="$1"; BUILD_TARGET="$1"
;;
--createrepo-webroot) shift; CREATEREPO_WEBROOT="$1" ;; --createrepo-webroot) shift; CREATEREPO_WEBROOT="$1" ;;
--createrepo-user) shift; CREATEREPO_USER="$1" ;; --createrepo-user) shift; CREATEREPO_USER="$1" ;;
--vncpass) shift; VNCPASS="$1" ;; --vncpass) shift; VNCPASS="$1" ;;
@@ -197,13 +196,17 @@ parse_input() {
else else
err "Incorrect options provided"; print_help; exit 1 err "Incorrect options provided"; print_help; exit 1
fi fi
# Print some warnings for unsupported argument combinations
if [[ -n $USER_MC_REPO ]] && ((LOCAL_INSTALL_SWITCH)); then
err "--install=local is not compatible with --mcrepo as only the default ($MC_REPO) DEB is available"
fi
} }
# @description Perform OS detection and generate OS-specific functions # @description Perform OS detection and generate OS-specific functions
# @see parse_input # @see parse_input
init() { init() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare -g USER declare -g USER
declare -g SCRIPT_PATH; SCRIPT_PATH=$(readlink -f "${BASH_SOURCE[0]}") declare -g SCRIPT_PATH; SCRIPT_PATH=$(readlink -f "${BASH_SOURCE[0]}")
declare -g SCRIPT_DIR; SCRIPT_DIR=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")") declare -g SCRIPT_DIR; SCRIPT_DIR=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
@@ -264,18 +267,13 @@ init() {
*suse*) *suse*)
ID="suse" ID="suse"
# Currently there is no remote repository for SUSE # Currently there is no remote repository for SUSE
# installJRMC can easily build one but I'd rather a SUSEian provide it # installJRMC can easily create one but I'd rather a SUSEian provide it
# So use local rpmbuild method by default for SUSE # So use local rpmbuild method by default for SUSE
if [[ $# -le 2 ]]; then if ((REPO_INSTALL_SWITCH)); then
case "$1" in debug "Automatically using --install=local for SUSE"
--debug| -d| --verbose| -y| --yes| --auto| --mcrepo| --mcversion| \
--arch| --betapass| --restorefile| --outputdir| --no-update)
debug "Automatically using --install local for SUSE"
REPO_INSTALL_SWITCH=0 REPO_INSTALL_SWITCH=0
BUILD_SWITCH=1 BUILD_SWITCH=1
LOCAL_INSTALL_SWITCH=1 LOCAL_INSTALL_SWITCH=1
;;
esac
fi fi
;; ;;
*) *)
@@ -292,7 +290,7 @@ init() {
else else
err "OS detection failed!" err "OS detection failed!"
ask_ok "Continue with manual installation?" || exit 1 ask_ok "Continue with manual installation?" || exit 1
debug "Automatically using --install local for unknown distro" debug "Automatically using --install=local for unknown distro"
ID="unknown" ID="unknown"
REPO_INSTALL_SWITCH=0 REPO_INSTALL_SWITCH=0
BUILD_SWITCH=1 BUILD_SWITCH=1
@@ -315,8 +313,7 @@ init() {
# Use the correct repo for legacy MC versions # Use the correct repo for legacy MC versions
if [[ -n $USER_MC_VERSION ]]; then if [[ -n $USER_MC_VERSION ]]; then
# Get MVERSION from user input case ${USER_MC_VERSION%%.*} in # get MVERSION from user input
case ${USER_MC_VERSION%%.*} in
2[0-6]) USER_MC_REPO="jessie" ;; 2[0-6]) USER_MC_REPO="jessie" ;;
2[7-9]|30) USER_MC_REPO="buster" ;; 2[7-9]|30) USER_MC_REPO="buster" ;;
31) USER_MC_REPO="bullseye" ;; 31) USER_MC_REPO="bullseye" ;;
@@ -325,6 +322,46 @@ init() {
esac esac
fi fi
# Set distro-specific package manager commands for normalized IDs
case $ID in
fedora|centos)
local rpm_mgr
rpm_mgr=$(command -v dnf &>/dev/null && echo "dnf" || echo "yum")
PKG_INSTALL=(execute sudo "$rpm_mgr" install -y)
PKG_REMOVE=(execute sudo "$rpm_mgr" remove -y)
PKG_UPDATE=(execute sudo "$rpm_mgr" makecache)
PKG_QUERY=(rpm -q)
PKG_INSTALL_LOCAL() { install_mc_rhel; }
;;
debian|ubuntu)
PKG_INSTALL=(execute sudo apt-get -f install -y -q0)
PKG_REMOVE=(execute sudo apt-get remove --auto-remove -y -q0)
PKG_UPDATE=(execute sudo apt-get update -y -q0)
PKG_QUERY=(dpkg -s)
PKG_INSTALL_LOCAL() { install_mc_deb "$@"; }
;;
suse)
PKG_INSTALL=(execute sudo zypper --gpg-auto-import-keys --non-interactive --quiet install --force --no-confirm)
PKG_REMOVE=(execute sudo zypper --non-interactive --quiet remove --clean-deps)
PKG_UPDATE=(execute sudo zypper --non-interactive --quiet refresh jriver)
PKG_QUERY=(rpm -q)
PKG_INSTALL_LOCAL() { install_mc_suse; }
;;
arch)
PKG_INSTALL=(execute sudo pacman -Sy --noconfirm)
PKG_REMOVE=(execute sudo pacman -Rs --noconfirm)
PKG_UPDATE=(execute sudo pacman -Syy)
PKG_QUERY=(sudo pacman -Qs)
PKG_INSTALL_LOCAL() { install_mc_arch; }
;;
unknown)
PKG_INSTALL=(:)
PKG_REMOVE=(:)
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 # Don't check for latest MC version if set by user or using --install=repo only
if [[ -z $USER_MC_VERSION ]] \ if [[ -z $USER_MC_VERSION ]] \
&& ((BUILD_SWITCH || LOCAL_INSTALL_SWITCH || CREATEREPO_SWITCH)); then && ((BUILD_SWITCH || LOCAL_INSTALL_SWITCH || CREATEREPO_SWITCH)); then
@@ -352,57 +389,17 @@ init() {
esac esac
fi fi
debug "Using host platform: $ID $VERSION_ID" debug "Host platform: $ID $VERSION_ID"
debug "Using MC repository: $MC_REPO" debug "MC repository: $MC_REPO"
# Set distro-specific package manager commands for normalized IDs
case $ID in
fedora|centos)
local rpm_mgr
rpm_mgr=$(command -v dnf &>/dev/null && echo "dnf" || echo "yum")
PKG_INSTALL=(execute sudo "$rpm_mgr" install -y)
PKG_REMOVE=(execute sudo "$rpm_mgr" remove -y)
PKG_UPDATE=(execute sudo "$rpm_mgr" makecache)
PKG_QUERY=(rpm -q)
PKG_INSTALL_LOCAL() { install_mc_rhel; }
;;
debian|ubuntu)
PKG_INSTALL=(execute sudo apt-get -f install -y -q0)
PKG_REMOVE=(execute sudo apt-get remove --auto-remove -y -q0)
PKG_UPDATE=(execute sudo apt-get update -y -q0)
PKG_QUERY=(dpkg -s)
PKG_INSTALL_LOCAL() { install_mc_deb; }
;;
suse)
PKG_INSTALL=(execute sudo zypper --gpg-auto-import-keys --non-interactive --quiet install --force --no-confirm)
PKG_REMOVE=(execute sudo zypper --non-interactive --quiet remove --clean-deps)
PKG_UPDATE=(execute sudo zypper --non-interactive --quiet refresh jriver)
PKG_QUERY=(rpm -q)
PKG_INSTALL_LOCAL() { install_mc_suse; }
;;
arch)
PKG_INSTALL=(execute sudo pacman -Sy --noconfirm)
PKG_REMOVE=(execute sudo pacman -Rs --noconfirm)
PKG_UPDATE=(execute sudo pacman -Syy)
PKG_QUERY=(sudo pacman -Qs)
PKG_INSTALL_LOCAL() { install_mc_arch; }
;;
unknown)
PKG_INSTALL=(:)
PKG_REMOVE=(:)
PKG_UPDATE=(:)
PKG_QUERY=(:)
PKG_INSTALL_LOCAL() { install_mc_generic; }
esac
} }
# @description Determines the latest JRiver MC version using several methods # @description Determines the latest JRiver MC version using several methods
# @arg $1 string MC repository name # @arg $1 string MC repository name
get_latest_mc_version() { get_latest_mc_version() {
debug "Running: ${FUNCNAME[0]}" "$*" debug "Running: ${FUNCNAME[0]}" "$*"
local cnt mc_version_source local cnt mc_version_source
# Use generalized containerized package manager to determine latest MC version
if install_package --silent buildah \ if install_package --silent buildah \
&& cnt=$(buildah from --quiet alpine:edge 2>/dev/null) \ && cnt=$(buildah from --quiet alpine:edge 2>/dev/null) \
&& buildah run "$cnt" -- sh -c \ && buildah run "$cnt" -- sh -c \
@@ -415,12 +412,11 @@ get_latest_mc_version() {
&& [[ $MC_VERSION =~ ([0-9]+.[0-9]+.[0-9]+) ]]; then && [[ $MC_VERSION =~ ([0-9]+.[0-9]+.[0-9]+) ]]; then
mc_version_source="containerized package manager" mc_version_source="containerized package manager"
execute buildah rm "$cnt" execute buildah rm "$cnt"
# Webscrape # Fallback to webscrape
elif install_package --silent wget \ elif MC_VERSION=$(download "$BOARD_URL" | grep -o "[0-9][0-9]\.[0-9]\.[0-9]\+" | head -n 1) \
&& MC_VERSION=$(wget -qO- "$BOARD_URL" | grep -o "[0-9][0-9]\.[0-9]\.[0-9]\+" | head -n 1) \
&& [[ $MC_VERSION =~ ([0-9]+.[0-9]+.[0-9]+) ]]; then && [[ $MC_VERSION =~ ([0-9]+.[0-9]+.[0-9]+) ]]; then
mc_version_source="webscrape" mc_version_source="webscrape"
# Hardcoded # Fallback to hardcoded value
else else
mc_version_source="hardcoded" mc_version_source="hardcoded"
err "Warning! Using hardcoded version number" err "Warning! Using hardcoded version number"
@@ -437,10 +433,9 @@ get_latest_mc_version() {
# @option --silent | -s Do not print errors (useful for optional packages) # @option --silent | -s Do not print errors (useful for optional packages)
install_package() { install_package() {
debug "Running: ${FUNCNAME[0]}" "$@" debug "Running: ${FUNCNAME[0]}" "$@"
local -a pkg_array install_flags local -a pkg_array install_flags
local -A pkg_aliases local -A pkg_aliases
local input pkg local input pkg _pkg
local no_install_check=0 allow_downgrades=0 silent=0 refresh=0 no_gpg_check=0 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 long_opts="no-install-check,allow-downgrades,no-gpg-check,refresh,silent"
@@ -463,47 +458,58 @@ install_package() {
case $ID in case $ID in
debian|ubuntu) debian|ubuntu)
pkg_aliases=( pkg_aliases=(
["rpm-build"]="rpm" [rpm-build]="rpm"
["createrepo_c"]="createrepo" [createrepo_c]="createrepo"
["tigervnc-server"]="tigervnc-standalone-server" [tigervnc-server]="tigervnc-standalone-server"
) ) ;;
;; suse)
pkg_aliases=(
[buildah]="buildah fuse-overlayfs"
) ;;
esac esac
# Filter out already installed packages # Filter out already installed packages to create pkg_array
for pkg in "$@"; do for pkg in "$@"; do
if [[ -v pkg_aliases[$pkg] ]]; then if [[ -v pkg_aliases[$pkg] ]]; then
debug "Aliasing $pkg to ${pkg_aliases[$pkg]}" debug "Aliasing $pkg to ${pkg_aliases[$pkg]}"
pkg=${pkg_aliases[$pkg]} IFS=' ' read -ra pkgs <<< "${pkg_aliases[$pkg]}"
for _pkg in "${pkgs[@]}"; do
if ((no_install_check)) \
|| ! { command -v "$_pkg" &>/dev/null \
|| "${PKG_QUERY[@]}" "$_pkg" &>/dev/null; }; then
pkg_array+=("$_pkg")
else
debug "$_pkg is already installed, skipping installation"
fi fi
if (( no_install_check )) \ done
else
if ((no_install_check)) \
|| ! { command -v "$pkg" &>/dev/null \ || ! { command -v "$pkg" &>/dev/null \
|| "${PKG_QUERY[@]}" "$pkg" &>/dev/null; }; then || "${PKG_QUERY[@]}" "$pkg" &>/dev/null; }; then
pkg_array+=("$pkg") pkg_array+=("$pkg")
else else
debug "$pkg already installed, skipping installation" debug "$pkg is already installed, skipping installation"
fi
fi fi
done done
# Generate installation flags based on the distribution # Generate installation flags based on the distribution
case $ID in case $ID in
debian|ubuntu) debian|ubuntu)
(( allow_downgrades )) && install_flags+=(--allow-downgrades) ((allow_downgrades)) && install_flags+=(--allow-downgrades) ;;
;;
fedora|centos) fedora|centos)
(( allow_downgrades )) && install_flags+=(--allowerasing) ((allow_downgrades)) && install_flags+=(--allowerasing)
(( no_gpg_check )) && install_flags+=(--nogpgcheck) ((no_gpg_check)) && install_flags+=(--nogpgcheck)
(( refresh )) && install_flags+=(--refresh) ((refresh)) && install_flags+=(--refresh)
;; ;;
suse) suse)
(( no_gpg_check )) && install_flags+=(--allow-unsigned-rpm) ((no_gpg_check)) && install_flags+=(--allow-unsigned-rpm) ;;
;;
esac esac
# Install packages if any need installation # Install packages if any need installation
if [[ ${#pkg_array[@]} -gt 0 ]]; then if [[ ${#pkg_array[@]} -gt 0 ]]; then
if ! "${PKG_INSTALL[@]}" "${install_flags[@]}" "${pkg_array[@]}"; then if ! "${PKG_INSTALL[@]}" "${install_flags[@]}" "${pkg_array[@]}"; then
(( silent )) || err "Failed to install ${pkg_array[*]}." ((silent)) || err "Failed to install ${pkg_array[*]}"
return 1 return 1
fi fi
fi fi
@@ -545,7 +551,7 @@ install_external_repos() {
# Install mesa-va-drivers-freeworld separately from the RPM using dnf swap # Install mesa-va-drivers-freeworld separately from the RPM using dnf swap
install_mesa_freeworld install_mesa_freeworld
;; ;;
suse) suse) # TODO may eventually be needed if X11_XOrg is not available by default
# if ! zypper repos | grep -q "X11_XOrg"; then # if ! zypper repos | grep -q "X11_XOrg"; then
# echo "Installing the X11 repository" # echo "Installing the X11 repository"
# execute sudo zypper --non-interactive --quiet addrepo \ # execute sudo zypper --non-interactive --quiet addrepo \
@@ -570,7 +576,7 @@ install_mesa_freeworld() {
err "Package swap failed for $pkg!" err "Package swap failed for $pkg!"
fi fi
else else
execute "${PKG_INSTALL[@]}" "$freeworld_pkg" "${PKG_INSTALL[@]}" "$freeworld_pkg"
fi fi
fi fi
} }
@@ -582,7 +588,6 @@ install_mesa_freeworld() {
# @description Installs JRiver Media Center from a remote repository # @description Installs JRiver Media Center from a remote repository
install_mc_repo() { install_mc_repo() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local repo_file repo_text local repo_file repo_text
case $ID in case $ID in
@@ -602,6 +607,8 @@ install_mc_repo() {
if [[ $ID == "ubuntu" ]] \ if [[ $ID == "ubuntu" ]] \
&& [[ $major_version -gt 24 || ($major_version -eq 24 && $minor_version -ge 10) ]]; then && [[ $major_version -gt 24 || ($major_version -eq 24 && $minor_version -ge 10) ]]; then
repo_file="/etc/apt/sources.list.d/jriver.sources" # TODO new Ubuntu sources file format repo_file="/etc/apt/sources.list.d/jriver.sources" # TODO new Ubuntu sources file format
local old_repo_file="/etc/apt/sources.list.d/jriver.list"
[[ -f $old_repo_file ]] && execute rm -f "$old_repo_file"
read -r -d '' repo_text <<-EOF read -r -d '' repo_text <<-EOF
Types: deb Types: deb
URIs: http://dist.jriver.com/latest/mediacenter/ URIs: http://dist.jriver.com/latest/mediacenter/
@@ -613,9 +620,8 @@ install_mc_repo() {
repo_file="/etc/apt/sources.list.d/jriver.list" repo_file="/etc/apt/sources.list.d/jriver.list"
repo_text="deb [signed-by=$keyfile arch=amd64,i386,armhf,arm64] http://dist.jriver.com/latest/mediacenter/ $MC_REPO main" repo_text="deb [signed-by=$keyfile arch=amd64,i386,armhf,arm64] http://dist.jriver.com/latest/mediacenter/ $MC_REPO main"
fi fi
install_package wget
echo "Installing JRiver Media Center RPM key" echo "Installing JRiver Media Center RPM key"
wget --quiet --output-document=- http://dist.jriver.com/mediacenter@jriver.com.gpg.key | download "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" |
gpg --dearmor | sudo tee "$keyfile" &>/dev/null gpg --dearmor | sudo tee "$keyfile" &>/dev/null
;; ;;
*) *)
@@ -625,8 +631,8 @@ install_mc_repo() {
;; ;;
esac esac
echo "Adding MC repository to $repo_file" echo "Adding MC repository file: $repo_file"
sudo tee "$repo_file" > /dev/null <<< "$repo_text" sudo tee "$repo_file" &>/dev/null <<< "$repo_text"
if ! "${PKG_UPDATE[@]}"; then if ! "${PKG_UPDATE[@]}"; then
err "Package update failed!" err "Package update failed!"
@@ -646,12 +652,9 @@ install_mc_repo() {
# @description Acquires the source DEB package from JRiver # @description Acquires the source DEB package from JRiver
acquire_deb() { acquire_deb() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local fname="MediaCenter-$MC_VERSION-$ARCH.deb" local fname="MediaCenter-$MC_VERSION-$ARCH.deb"
declare -g MC_DEB="$OUTPUT_DIR/SOURCES/$fname" declare -g MC_DEB="$OUTPUT_DIR/SOURCES/$fname"
debug "MC_DEB=$MC_DEB"
# If deb file already exists, skip download # If deb file already exists, skip download
if [[ -f $MC_DEB ]]; then if [[ -f $MC_DEB ]]; then
if [[ $(stat -c%s "$MC_DEB") -lt 10000000 ]]; then if [[ $(stat -c%s "$MC_DEB") -lt 10000000 ]]; then
@@ -673,7 +676,7 @@ acquire_deb() {
# Loop through the repositories and attempt to download # Loop through the repositories and attempt to download
for repo in "${repos[@]}"; do for repo in "${repos[@]}"; do
echo "Checking $repo for DEB package" echo "Checking $repo for DEB package"
if execute wget --quiet --output-document "$MC_DEB" "$repo"; then if download "$repo" "$MC_DEB"; then
echo "Found" echo "Found"
break break
fi fi
@@ -783,7 +786,7 @@ build_rpm() {
requires="${requires%?}" requires="${requires%?}"
recommends="${recommends%?}" recommends="${recommends%?}"
if (( COMPAT_SWITCH )); then if ((COMPAT_SWITCH)); then
# Strip minimum versions # Strip minimum versions
requires=$(echo "$requires" | awk -F" " 'NF == 4 {print $1 " " $2} NF != 4 {print $0}') requires=$(echo "$requires" | awk -F" " 'NF == 4 {print $1 " " $2} NF != 4 {print $0}')
fi fi
@@ -815,7 +818,7 @@ build_rpm() {
Provides: mediacenter$MC_MVERSION Provides: mediacenter$MC_MVERSION
License: Copyright 1998-2024, JRiver, Inc. All rights reserved. Protected by U.S. patents #7076468 and #7062468 License: Copyright 1998-$(date +%Y), JRiver, Inc. All rights reserved. Protected by U.S. patents #7076468 and #7062468
URL: http://www.jriver.com/ URL: http://www.jriver.com/
%define __provides_exclude_from ^%{_libdir}/jriver/.*/.*\\.so.*$ %define __provides_exclude_from ^%{_libdir}/jriver/.*/.*\\.so.*$
@@ -856,8 +859,7 @@ build_rpm() {
echo "Build successful. The RPM file is located at: $MC_RPM" echo "Build successful. The RPM file is located at: $MC_RPM"
else else
err "Build failed" err "Build failed"
# For automation, let's remove the source DEB and reaquire it on next # After failire, remove the source DEB and reaquire it on next run
# run after failure in case it is corrupted or buggy
[[ -f $MC_DEB ]] && echo "Removing source DEB" && execute rm -f "$MC_DEB" [[ -f $MC_DEB ]] && echo "Removing source DEB" && execute rm -f "$MC_DEB"
exit 1 exit 1
fi fi
@@ -867,21 +869,20 @@ build_rpm() {
install_mc_deb() { install_mc_deb() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
if (( COMPAT_SWITCH )); then if ((COMPAT_SWITCH)); then
declare extract_dir && extract_dir="$(mktemp -d)" local extract_dir; extract_dir="$(mktemp -d)"
pushd "$extract_dir" &>/dev/null || return pushd "$extract_dir" &>/dev/null || return
command -v ar &>/dev/null || install_package binutils command -v ar &>/dev/null || { install_package binutils || return 1; }
execute ar x "$MC_DEB" execute ar x "$MC_DEB"
execute tar xJf "control.tar.xz" execute tar xJf "control.tar.xz"
# Remove minimum version specifiers from control file # Remove minimum version specifiers from control file
sed -i 's/ ([^)]*)//g' "control" sed -i 's/ ([^)]*)//g' "control"
# Remove libwebkit2gtk and their fantastic package versioning strategy # Remove libwebkit2gtk and their fantastic package versioning strategy
sed -i 's/,\s*libwebkit2gtk[^,]*,\?|libwebkit2gtk[^,]*,\?//g' "control" sed -i 's/,\s*libwebkit2gtk[^,]*,\?|libwebkit2gtk[^,]*,\?//g' "control"
# TODO ugly ZorinOS workaround # TODO workaround for ZorinOS
[[ $ID == "ubuntu" && ${VERSION_ID%.*} -le 16 ]] \ [[ $ID == "ubuntu" && ${VERSION_ID%.*} -le 16 ]] \
&& ! grep -q zorin /etc/os-release \ && grep -q zorin /etc/os-release \
&& sed -i 's/libva2/libva1/g' "control" && sed -i 's/libva2/libva1/g' "control"
execute tar -cJf "control.tar.xz" "control" "postinst" execute tar -cJf "control.tar.xz" "control" "postinst"
@@ -891,21 +892,27 @@ install_mc_deb() {
execute rm -rf "$extract_dir" execute rm -rf "$extract_dir"
fi fi
install_package \ if ! install_package \
--no-install-check \ --no-install-check \
--no-gpg-check \ --no-gpg-check \
--allow-downgrades \ --allow-downgrades \
"$MC_DEB" "$MC_DEB"; then
err "Local MC DEB installation failed"
err "Only the default MC repo can be used for --install=local"
if ask_ok "Remove source DEB and retry"; then
execute rm -f "$MC_DEB"
exec "$SCRIPT_PATH" "$@" "--no-update"
else
return 1
fi
fi
} }
# @description Installs Media Center RPM package on RHEL distros # @description Installs Media Center RPM package on RHEL distros
install_mc_rhel() { install_mc_rhel() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
# Swap in freeworld hardware acceleration separately from the RPM # Swap in freeworld hardware acceleration separately from the RPM
install_mesa_freeworld install_mesa_freeworld
install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_RPM" install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_RPM"
} }
@@ -919,9 +926,8 @@ install_mc_suse() {
# @description Installs Media Center generically for unsupported OSes # @description Installs Media Center generically for unsupported OSes
install_mc_generic() { install_mc_generic() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local -a raw_files
local extract_dir local extract_dir
local -a raw_files
echo "Using generic installation method" echo "Using generic installation method"
@@ -998,7 +1004,6 @@ install_mc_arch() {
# @description Copy the RPM to createrepo-webroot and run createrepo as the createrepo-user # @description Copy the RPM to createrepo-webroot and run createrepo as the createrepo-user
run_createrepo() { run_createrepo() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local -a cr_cmd local -a cr_cmd
install_package createrepo_c install_package createrepo_c
@@ -1042,7 +1047,6 @@ run_createrepo() {
# @description Symlink certificates if they do not exist in default location # @description Symlink certificates if they do not exist in default location
link_ssl_certs() { link_ssl_certs() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local target_cert f local target_cert f
local mc_cert_link="$MC_ROOT/ca-certificates.crt" local mc_cert_link="$MC_ROOT/ca-certificates.crt"
local -a source_certs=( local -a source_certs=(
@@ -1066,8 +1070,7 @@ link_ssl_certs() {
# @description Restore the mjr license file from MJR_FILE or other common locations # @description Restore the mjr license file from MJR_FILE or other common locations
restore_license() { restore_license() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local newest f
local f newest
local -a mjrfiles local -a mjrfiles
# Glob mjr files from common directories # Glob mjr files from common directories
@@ -1107,7 +1110,6 @@ restore_license() {
# @arg $2 array List of ports in firewall-cmd format # @arg $2 array List of ports in firewall-cmd format
open_firewall() { open_firewall() {
debug "Running: ${FUNCNAME[0]}" "$*" debug "Running: ${FUNCNAME[0]}" "$*"
local port local port
local service="$1" local service="$1"
shift shift
@@ -1146,7 +1148,6 @@ open_firewall() {
# @arg $1 string Service type (xvnc, x11vnc) # @arg $1 string Service type (xvnc, x11vnc)
set_vnc_pass() { set_vnc_pass() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local vncpassfile="$HOME/.vnc/jrmc_passwd" local vncpassfile="$HOME/.vnc/jrmc_passwd"
[[ -d ${vncpassfile%/*} ]] || execute mkdir -p "${vncpassfile%/*}" [[ -d ${vncpassfile%/*} ]] || execute mkdir -p "${vncpassfile%/*}"
@@ -1167,7 +1168,7 @@ set_vnc_pass() {
elif [[ $1 == "x11vnc" ]]; then elif [[ $1 == "x11vnc" ]]; then
execute x11vnc -storepasswd "$VNCPASS" "$vncpassfile" execute x11vnc -storepasswd "$VNCPASS" "$vncpassfile"
fi fi
return $? return
else else
declare -g NOVNCAUTH=1 declare -g NOVNCAUTH=1
fi fi
@@ -1176,7 +1177,6 @@ set_vnc_pass() {
# @description Set display and port variables # @description Set display and port variables
set_display_vars() { set_display_vars() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare -g THIS_DISPLAY THIS_DISPLAY_NUM NEXT_DISPLAY declare -g THIS_DISPLAY THIS_DISPLAY_NUM NEXT_DISPLAY
# Check USER_DISPLAY, else environment DISPLAY, else set to :0 # Check USER_DISPLAY, else environment DISPLAY, else set to :0
@@ -1184,10 +1184,10 @@ set_display_vars() {
THIS_DISPLAY_NUM="${THIS_DISPLAY#*:}" # strip prefix THIS_DISPLAY_NUM="${THIS_DISPLAY#*:}" # strip prefix
THIS_DISPLAY_NUM="${THIS_DISPLAY_NUM%%.*}" # strip suffix THIS_DISPLAY_NUM="${THIS_DISPLAY_NUM%%.*}" # strip suffix
# Increment each time we run this # Increment each time we run this
if (( NEXT_DISPLAY_NUM )); then if ((NEXT_DISPLAY_NUM)); then
declare -g NEXT_DISPLAY_NUM=$(( NEXT_DISPLAY_NUM + 1 )) declare -g NEXT_DISPLAY_NUM=$((NEXT_DISPLAY_NUM + 1))
else else
declare -g NEXT_DISPLAY_NUM=$(( THIS_DISPLAY_NUM + 1 )) declare -g NEXT_DISPLAY_NUM=$((THIS_DISPLAY_NUM + 1))
fi fi
NEXT_DISPLAY=":$NEXT_DISPLAY_NUM" NEXT_DISPLAY=":$NEXT_DISPLAY_NUM"
} }
@@ -1196,7 +1196,6 @@ set_display_vars() {
# @arg $1 string Service name # @arg $1 string Service name
set_service_vars() { set_service_vars() {
debug "Running: ${FUNCNAME[0]}" "$*" debug "Running: ${FUNCNAME[0]}" "$*"
declare -g SERVICE_NAME SERVICE_FNAME TIMER_NAME TIMER_FNAME declare -g SERVICE_NAME SERVICE_FNAME TIMER_NAME TIMER_FNAME
declare -g USER_STRING GRAPHICAL_TARGET declare -g USER_STRING GRAPHICAL_TARGET
declare -ga RELOAD ENABLE DISABLE IS_ENABLED IS_ACTIVE declare -ga RELOAD ENABLE DISABLE IS_ENABLED IS_ACTIVE
@@ -1279,9 +1278,7 @@ service_jriver-mediacenter() {
# @description Starts and enables (at startup) a JRiver Media Server service # @description Starts and enables (at startup) a JRiver Media Server service
service_jriver-mediaserver() { service_jriver-mediaserver() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
set_service_vars "${FUNCNAME[0]##*_}" "user" set_service_vars "${FUNCNAME[0]##*_}" "user"
service_jriver-mediacenter "/MediaServer" service_jriver-mediacenter "/MediaServer"
} }
@@ -1289,14 +1286,13 @@ service_jriver-mediaserver() {
# TODO https://github.com/TigerVNC/tigervnc/blob/master/unix/vncserver/HOWTO.md # TODO https://github.com/TigerVNC/tigervnc/blob/master/unix/vncserver/HOWTO.md
service_jriver-xvnc() { service_jriver-xvnc() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local -a start_cmd
set_service_vars "${FUNCNAME[0]##*_}" "system" set_service_vars "${FUNCNAME[0]##*_}" "system"
set_display_vars set_display_vars
local -a start_cmd declare -g PORT=$((NEXT_DISPLAY_NUM + 5900))
declare -g PORT=$(( NEXT_DISPLAY_NUM + 5900 ))
install_package tigervnc-server install_package tigervnc-server
set_vnc_pass xvnc set_vnc_pass xvnc
start_cmd=( start_cmd=(
@@ -1307,7 +1303,7 @@ service_jriver-xvnc() {
-xstartup "/usr/bin/mediacenter$MC_MVERSION" -xstartup "/usr/bin/mediacenter$MC_MVERSION"
) )
if (( NOVNCAUTH )); then if ((NOVNCAUTH)); then
start_cmd+=( start_cmd+=(
-name "jriver$NEXT_DISPLAY" -name "jriver$NEXT_DISPLAY"
-SecurityTypes None) -SecurityTypes None)
@@ -1338,7 +1334,7 @@ service_jriver-xvnc() {
if ! "${ENABLE[@]}" "$SERVICE_NAME"; then if ! "${ENABLE[@]}" "$SERVICE_NAME"; then
err "vncserver failed to start on DISPLAY $NEXT_DISPLAY" err "vncserver failed to start on DISPLAY $NEXT_DISPLAY"
# Allow to increment 10 times before breaking # Allow to increment 10 times before breaking
max=$(( THIS_DISPLAY_NUM + 10 )) max=$((THIS_DISPLAY_NUM + 10))
while [[ $NEXT_DISPLAY_NUM -lt $max ]]; do while [[ $NEXT_DISPLAY_NUM -lt $max ]]; do
echo "Incrementing DISPLAY and retrying" echo "Incrementing DISPLAY and retrying"
service_jriver-xvnc && return service_jriver-xvnc && return
@@ -1355,15 +1351,11 @@ service_jriver-xvnc() {
# @description Starts and enables (at startup) x11vnc screen sharing for the local desktop # @description Starts and enables (at startup) x11vnc screen sharing for the local desktop
service_jriver-x11vnc() { service_jriver-x11vnc() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local -a start_cmd
set_service_vars "${FUNCNAME[0]##*_}" "user" set_service_vars "${FUNCNAME[0]##*_}" "user"
set_display_vars set_display_vars
declare -g PORT=$((THIS_DISPLAY_NUM + 5900))
local -a start_cmd
declare -g PORT=$(( THIS_DISPLAY_NUM + 5900 ))
install_package x11vnc install_package x11vnc
set_vnc_pass x11vnc set_vnc_pass x11vnc
# If .Xauthority file is missing, generate a dummy for x11vnc -auth guess # If .Xauthority file is missing, generate a dummy for x11vnc -auth guess
@@ -1386,7 +1378,7 @@ service_jriver-x11vnc() {
-bg -bg
) )
if (( NOVNCAUTH )); then if ((NOVNCAUTH)); then
start_cmd+=(-nopw) start_cmd+=(-nopw)
else else
start_cmd+=(-rfbauth "$HOME/.vnc/jrmc_passwd") start_cmd+=(-rfbauth "$HOME/.vnc/jrmc_passwd")
@@ -1459,7 +1451,6 @@ service_jriver-createrepo() {
# @description Detects if MC is installed on btrfs and disables CoW # @description Detects if MC is installed on btrfs and disables CoW
disable_btrfs_cow() { disable_btrfs_cow() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local dir local dir
local mc_user_path="$HOME/.jriver" local mc_user_path="$HOME/.jriver"
@@ -1476,7 +1467,6 @@ disable_btrfs_cow() {
# @description Completely uninstalls MC, services, and firewall rules # @description Completely uninstalls MC, services, and firewall rules
uninstall() { uninstall() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
local service unit f i local service unit f i
echo "Stopping and removing all Media Center services" echo "Stopping and removing all Media Center services"
@@ -1503,10 +1493,11 @@ uninstall() {
unset f unset f
done done
echo "Removing repo files" echo "Removing MC repositories"
execute sudo rm -rf \ execute sudo rm -rf \
"/etc/yum.repos.d/jriver.repo" \ "/etc/yum.repos.d/jriver.repo" \
/etc/apt/sources.list.d/{jriver,mediacenter}*.list # also remove legacy repo files /etc/apt/sources.list.d/{jriver,mediacenter}*.{list,sources} # also remove legacy repo files
if [[ $ID == "suse" ]]; then if [[ $ID == "suse" ]]; then
execute sudo zypper --non-interactive removerepo jriver execute sudo zypper --non-interactive removerepo jriver
fi fi
@@ -1523,11 +1514,11 @@ uninstall() {
fi fi
echo "Uninstalling JRiver Media Center package" echo "Uninstalling JRiver Media Center package"
if "${PKG_REMOVE[@]}" "$MC_PKG"; then if "${PKG_REMOVE[@]}" "${MC_PKG%%=*}"; then # remove version specifier
echo "JRiver Media Center has been completely uninstalled" echo "JRiver Media Center has been completely uninstalled"
echo "To remove your MC library: rm -rf $HOME/.jriver" echo "To remove your MC library: rm -rf $HOME/.jriver"
elif [[ $? -eq 100 ]]; then elif [[ $? -eq 100 ]]; then
err "JRiver Media Center package '$MC_PKG' is not present and was not uninstalled" err "JRiver Media Center package '${MC_PKG%%=*}' is not present and was not uninstalled"
else else
err "Could not remove Media Center package" err "Could not remove Media Center package"
fi fi
@@ -1546,13 +1537,9 @@ uninstall() {
# @description Checks for installJRMC update and re-executes, if necessary # @description Checks for installJRMC update and re-executes, if necessary
update() { update() {
debug "Running: ${FUNCNAME[0]} $*" debug "Running: ${FUNCNAME[0]} $*"
local script_url="https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC"
local tmp; tmp=$(mktemp)
debug "Checking for installJRMC update" debug "Checking for installJRMC update"
# Function to extract and normalize version from a script # Extract and normalize version from a script
extract_version() { extract_version() {
local version_line local version_line
version_line=$(grep -m 1 'SCRIPT_VERSION=' "$1") version_line=$(grep -m 1 'SCRIPT_VERSION=' "$1")
@@ -1563,51 +1550,77 @@ update() {
echo "$version_line" echo "$version_line"
} }
# Compare semantic version strings
version_greater() {
[[ "$(echo -e "$1\n$2" | sort -V | head -n 1)" != "$1" ]]
}
# Check if we're in a git directory and if it's the installJRMC repository # Check if we're in a git directory and if it's the installJRMC repository
if git -C "$SCRIPT_DIR" rev-parse --is-inside-work-tree &>/dev/null \ if git -C "$SCRIPT_DIR" rev-parse --is-inside-work-tree &>/dev/null \
&& [[ "$(git -C "$SCRIPT_DIR" config --get remote.origin.url)" == *"bryan/installJRMC"* ]]; then && [[ "$(git -C "$SCRIPT_DIR" config --get remote.origin.url)" == *"installJRMC"* ]]; then
debug "installJRMC git repository detected. Running git pull..." debug "installJRMC git repository detected. Running git pull"
# Get the current commit hash # Get the current commit hash
local before_pull_hash local before_pull_hash after_pull_hash
before_pull_hash=$(git -C "$SCRIPT_DIR" rev-parse HEAD) before_pull_hash=$(git -C "$SCRIPT_DIR" rev-parse HEAD)
if git -C "$SCRIPT_DIR" pull | grep -qv "Already up to date"; then # Stash any local changes
execute git -C "$SCRIPT_DIR" stash --quiet
# Pull the latest changes
debug "Executing git pull in $SCRIPT_DIR"
if git -C "$SCRIPT_DIR" pull | grep -q "Already up to date"; then
debug "No updates found in git repository."
return 0 return 0
fi fi
local after_pull_hash # Get the new commit hash after pull
after_pull_hash=$(git -C "$SCRIPT_DIR" rev-parse HEAD) after_pull_hash=$(git -C "$SCRIPT_DIR" rev-parse HEAD)
if [[ "$before_pull_hash" != "$after_pull_hash" ]]; then
echo "installJRMC repository updated. Restarting script..."
exec "$SCRIPT_PATH" "$@" "--no-update"
fi
fi
# Download the latest version of the script # If the commit hash has changed, an update occurred
install_package --silent wget if [[ "$before_pull_hash" != "$after_pull_hash" ]]; then
if command -v wget &>/dev/null; then echo "Detected installJRMC update, restarting"
execute wget -q -O "$tmp" "$script_url" exec "$SCRIPT_PATH" "$@" "--no-update"
elif command -v curl &>/dev/null; then
execute curl -s -L -o "$tmp" "$script_url"
else else
debug "Git pull did not change the commit hash. No update applied."
return 0
fi
else
debug "Not in a git repository or not the installJRMC repository. Checking for updates via download."
local tmp
tmp=$(mktemp) || { err "Failed to create temporary file."; return 1; }
# Acquire the latest version of the script
if ! download "$SCRIPT_URL" "$tmp"; then
err "Failed to download the latest script."
execute rm -f "$tmp"
return 1 return 1
fi fi
# Get latest version number # Extract the latest version number
local remote_version local remote_version
remote_version=$(extract_version "$tmp") remote_version=$(extract_version "$tmp")
[[ -z $remote_version ]] && { rm -f "$tmp"; return 1; } if [[ -z "$remote_version" ]]; then
err "Failed to extract version from the downloaded script."
# Compare versions and update if necessary execute rm -f "$tmp"
if [[ $SCRIPT_VERSION < $remote_version ]]; then return 1
echo "Updating installJRMC $SCRIPT_VERSION to $remote_version"
execute mv "$tmp" "$SCRIPT_PATH"
execute chmod +x "$SCRIPT_PATH"
exec "$SCRIPT_PATH" "$@" "--no-update"
fi fi
rm -f "$tmp" # Compare versions and update if the remote version is greater
if version_greater "$remote_version" "$SCRIPT_VERSION"; then
execute mv "$tmp" "$SCRIPT_PATH" || { err "Failed to replace the script"; execute rm -f "$tmp"; return 1; }
execute chmod +x "$SCRIPT_PATH" || { err "Failed to make the script executable"; return 1; }
execute rm -f "$tmp"
echo "Detected installJRMC update, restarting"
exec "$SCRIPT_PATH" "$@" "--no-update"
else
debug "Current installJRMC $SCRIPT_VERSION is the latest version"
execute rm -f "$tmp"
return 0
fi
fi
} }
# @description installJRMC main function # @description installJRMC main function
@@ -1615,7 +1628,7 @@ main() {
debug "Running: ${FUNCNAME[0]} $*" debug "Running: ${FUNCNAME[0]} $*"
echo "Starting installJRMC $SCRIPT_VERSION" echo "Starting installJRMC $SCRIPT_VERSION"
if (( DEBUG )); then if ((DEBUG)); then
echo "Debugging on" echo "Debugging on"
else else
echo "To enable debugging output, use --debug or -d" echo "To enable debugging output, use --debug or -d"
@@ -1624,7 +1637,7 @@ main() {
# Parse input, set default/host variables, and MC version # Parse input, set default/host variables, and MC version
init "$@" init "$@"
if (( UNINSTALL_SWITCH )); then if ((UNINSTALL_SWITCH)); then
if ask_ok "Do you really want to uninstall JRiver Media Center?"; then if ask_ok "Do you really want to uninstall JRiver Media Center?"; then
uninstall uninstall
else else
@@ -1635,7 +1648,7 @@ main() {
install_external_repos install_external_repos
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 if install_mc_repo; then
echo "JRiver Media Center installed successfully from remote repository" echo "JRiver Media Center installed successfully from remote repository"
@@ -1649,20 +1662,19 @@ main() {
fi fi
fi fi
if (( BUILD_SWITCH )) && [[ $ID != "arch" ]]; then if ((BUILD_SWITCH)) && [[ $ID != "arch" ]]; then
install_package "wget"
[[ -d $OUTPUT_DIR/SOURCES ]] || execute mkdir -p "$OUTPUT_DIR/SOURCES" [[ -d $OUTPUT_DIR/SOURCES ]] || execute mkdir -p "$OUTPUT_DIR/SOURCES"
acquire_deb || { err "Could not download Media Center DEB package"; return 1; } acquire_deb || { err "Could not download Media Center DEB package"; return 1; }
if [[ $BUILD_TARGET =~ (centos|fedora|suse) || $CREATEREPO_TARGET =~ (centos|fedora|suse) ]]; then if [[ $BUILD_TARGET =~ (centos|fedora|suse) || $CREATEREPO_TARGET =~ (centos|fedora|suse) ]]; then
install_package "dpkg" "rpm-build" install_package dpkg rpm-build
[[ -d $OUTPUT_DIR/SPECS ]] || execute mkdir -p "$OUTPUT_DIR/SPECS" [[ -d $OUTPUT_DIR/SPECS ]] || execute mkdir -p "$OUTPUT_DIR/SPECS"
build_rpm build_rpm
fi fi
fi fi
if (( LOCAL_INSTALL_SWITCH )); then if ((LOCAL_INSTALL_SWITCH)); then
if PKG_INSTALL_LOCAL; then if PKG_INSTALL_LOCAL "$@"; 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"
@@ -1674,7 +1686,7 @@ main() {
disable_btrfs_cow disable_btrfs_cow
fi fi
if (( CREATEREPO_SWITCH )); then if ((CREATEREPO_SWITCH)); then
if run_createrepo; then if run_createrepo; then
echo "Successfully updated repo" echo "Successfully updated repo"
else else
@@ -1710,11 +1722,11 @@ main() {
} }
# @section Helper functions # @section Helper functions
debug() { (( DEBUG )) && echo "Debug: $*"; } debug() { ((DEBUG)) && echo "Debug: $*"; }
err() { echo "Error: $*" >&2; } err() { echo "Error: $*" >&2; }
ask_ok() { ask_ok() {
declare response declare response
(( YES_SWITCH )) && return 0 ((YES_SWITCH)) && return 0
read -r -p "$* [y/N]: " response read -r -p "$* [y/N]: " response
[[ ${response,,} =~ ^(yes|y)$ ]] [[ ${response,,} =~ ^(yes|y)$ ]]
} }
@@ -1725,6 +1737,39 @@ execute() {
"$@" &>/dev/null "$@" &>/dev/null
fi fi
} }
download() {
local url="$1"
local output="${2:-}"
local -a download_cmd
if command -v wget &>/dev/null; then
download_cmd=(wget --quiet)
elif command -v curl &>/dev/null; then
download_cmd=(curl --silent --location)
else
if install_package --silent wget; then
download_cmd=(wget --quiet)
elif install_package --silent curl; then
download_cmd=(curl --silent --location)
else
err "Unable to install wget or curl"
return 1
fi
fi
if [[ ${download_cmd[0]} == "wget" ]]; then
"${download_cmd[@]}" --output-document="${output:--}" "$url"
elif [[ ${download_cmd[0]} == "curl" ]]; then
if [[ -n "$output" ]]; then
"${download_cmd[@]}" --output "$output" "$url"
else
"${download_cmd[@]}" "$url"
fi
else
err "Unsupported download command: ${download_cmd[*]}"
return 1
fi
}
# Roughly turn debugging on, reparse in parse_input() with getopt # Roughly turn debugging on, reparse in parse_input() with getopt
[[ " $* " =~ ( --debug | -d ) ]] && declare -g DEBUG=1 [[ " $* " =~ ( --debug | -d ) ]] && declare -g DEBUG=1