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

View File

@@ -8,19 +8,22 @@
# https://www.apache.org/licenses/LICENSE-2.0
#
# TODO (v2)
# 1. Interactive mode
# 2. Additional containerization (createrepo and rpmbuild)
# * Interactive mode
# * Additional containerization (createrepo and rpmbuild)
#
# BUGS
# 1. No createrepo on Mint
# * No createrepo on Mint
#
# NOTES
# * Be careful with tabs in heredocs
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_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 -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
print_help() {
@@ -72,7 +75,7 @@ print_help() {
--uninstall, -u
Uninstall JRiver MC, remove services, containers, and firewall rules (does not remove library files)
--yes, -y, --auto
Always assume yes for questions
Assume yes response to questions
--version, -v
Print this script version and exit
--debug, -d
@@ -110,13 +113,11 @@ print_help() {
# @arg $@ User input
parse_input() {
debug "Running: ${FUNCNAME[0]} $*"
declare -g BUILD_SWITCH REPO_INSTALL_SWITCH LOCAL_INSTALL_SWITCH \
COMPAT_SWITCH CREATEREPO_SWITCH UNINSTALL_SWITCH \
YES_SWITCH 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,"
long_opts+="restorefile:,betapass:,"
@@ -174,10 +175,8 @@ parse_input() {
--betapass) shift; BETAPASS="$1" ;;
--service-type) shift; SERVICE_TYPE="$1" ;;
--service|-s|--services) shift; SERVICES+=("$1") ;;
--createrepo)
BUILD_SWITCH=1; CREATEREPO_SWITCH=1
shift; CREATEREPO_TARGET="$1"; BUILD_TARGET="$1"
;;
--createrepo) shift; CREATEREPO_TARGET="$1"; BUILD_TARGET="$1"
BUILD_SWITCH=1; CREATEREPO_SWITCH=1 ;;
--createrepo-webroot) shift; CREATEREPO_WEBROOT="$1" ;;
--createrepo-user) shift; CREATEREPO_USER="$1" ;;
--vncpass) shift; VNCPASS="$1" ;;
@@ -197,13 +196,17 @@ parse_input() {
else
err "Incorrect options provided"; print_help; exit 1
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
# @see parse_input
init() {
debug "Running: ${FUNCNAME[0]}"
declare -g USER
declare -g SCRIPT_PATH; SCRIPT_PATH=$(readlink -f "${BASH_SOURCE[0]}")
declare -g SCRIPT_DIR; SCRIPT_DIR=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
@@ -264,18 +267,13 @@ init() {
*suse*)
ID="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
if [[ $# -le 2 ]]; then
case "$1" in
--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
BUILD_SWITCH=1
LOCAL_INSTALL_SWITCH=1
;;
esac
if ((REPO_INSTALL_SWITCH)); then
debug "Automatically using --install=local for SUSE"
REPO_INSTALL_SWITCH=0
BUILD_SWITCH=1
LOCAL_INSTALL_SWITCH=1
fi
;;
*)
@@ -292,7 +290,7 @@ init() {
else
err "OS detection failed!"
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"
REPO_INSTALL_SWITCH=0
BUILD_SWITCH=1
@@ -315,8 +313,7 @@ init() {
# Use the correct repo for legacy MC versions
if [[ -n $USER_MC_VERSION ]]; then
# Get MVERSION from user input
case ${USER_MC_VERSION%%.*} in
case ${USER_MC_VERSION%%.*} in # get MVERSION from user input
2[0-6]) USER_MC_REPO="jessie" ;;
2[7-9]|30) USER_MC_REPO="buster" ;;
31) USER_MC_REPO="bullseye" ;;
@@ -325,6 +322,46 @@ init() {
esac
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
if [[ -z $USER_MC_VERSION ]] \
&& ((BUILD_SWITCH || LOCAL_INSTALL_SWITCH || CREATEREPO_SWITCH)); then
@@ -352,57 +389,17 @@ init() {
esac
fi
debug "Using host platform: $ID $VERSION_ID"
debug "Using 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
debug "Host platform: $ID $VERSION_ID"
debug "MC repository: $MC_REPO"
}
# @description Determines the latest JRiver MC version using several methods
# @arg $1 string MC repository name
get_latest_mc_version() {
debug "Running: ${FUNCNAME[0]}" "$*"
local cnt mc_version_source
# Use generalized containerized package manager to determine latest MC version
if install_package --silent buildah \
&& cnt=$(buildah from --quiet alpine:edge 2>/dev/null) \
&& buildah run "$cnt" -- sh -c \
@@ -415,12 +412,11 @@ get_latest_mc_version() {
&& [[ $MC_VERSION =~ ([0-9]+.[0-9]+.[0-9]+) ]]; then
mc_version_source="containerized package manager"
execute buildah rm "$cnt"
# Webscrape
elif install_package --silent wget \
&& MC_VERSION=$(wget -qO- "$BOARD_URL" | grep -o "[0-9][0-9]\.[0-9]\.[0-9]\+" | head -n 1) \
# Fallback to webscrape
elif MC_VERSION=$(download "$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_source="webscrape"
# Hardcoded
# Fallback to hardcoded value
else
mc_version_source="hardcoded"
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)
install_package() {
debug "Running: ${FUNCNAME[0]}" "$@"
local -a pkg_array install_flags
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 long_opts="no-install-check,allow-downgrades,no-gpg-check,refresh,silent"
@@ -463,47 +458,58 @@ install_package() {
case $ID in
debian|ubuntu)
pkg_aliases=(
["rpm-build"]="rpm"
["createrepo_c"]="createrepo"
["tigervnc-server"]="tigervnc-standalone-server"
)
;;
[rpm-build]="rpm"
[createrepo_c]="createrepo"
[tigervnc-server]="tigervnc-standalone-server"
) ;;
suse)
pkg_aliases=(
[buildah]="buildah fuse-overlayfs"
) ;;
esac
# Filter out already installed packages
# Filter out already installed packages to create pkg_array
for pkg in "$@"; do
if [[ -v pkg_aliases[$pkg] ]]; then
debug "Aliasing $pkg to ${pkg_aliases[$pkg]}"
pkg=${pkg_aliases[$pkg]}
fi
if (( no_install_check )) \
|| ! { command -v "$pkg" &>/dev/null \
|| "${PKG_QUERY[@]}" "$pkg" &>/dev/null; }; then
pkg_array+=("$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
done
else
debug "$pkg already installed, skipping installation"
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
done
# Generate installation flags based on the distribution
case $ID in
debian|ubuntu)
(( allow_downgrades )) && install_flags+=(--allow-downgrades)
;;
((allow_downgrades)) && install_flags+=(--allow-downgrades) ;;
fedora|centos)
(( allow_downgrades )) && install_flags+=(--allowerasing)
(( no_gpg_check )) && install_flags+=(--nogpgcheck)
(( refresh )) && install_flags+=(--refresh)
((allow_downgrades)) && install_flags+=(--allowerasing)
((no_gpg_check)) && install_flags+=(--nogpgcheck)
((refresh)) && install_flags+=(--refresh)
;;
suse)
(( no_gpg_check )) && install_flags+=(--allow-unsigned-rpm)
;;
((no_gpg_check)) && install_flags+=(--allow-unsigned-rpm) ;;
esac
# Install packages if any need installation
if [[ ${#pkg_array[@]} -gt 0 ]]; 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
fi
fi
@@ -545,7 +551,7 @@ install_external_repos() {
# Install mesa-va-drivers-freeworld separately from the RPM using dnf swap
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
# echo "Installing the X11 repository"
# execute sudo zypper --non-interactive --quiet addrepo \
@@ -570,7 +576,7 @@ install_mesa_freeworld() {
err "Package swap failed for $pkg!"
fi
else
execute "${PKG_INSTALL[@]}" "$freeworld_pkg"
"${PKG_INSTALL[@]}" "$freeworld_pkg"
fi
fi
}
@@ -582,7 +588,6 @@ install_mesa_freeworld() {
# @description Installs JRiver Media Center from a remote repository
install_mc_repo() {
debug "Running: ${FUNCNAME[0]}"
local repo_file repo_text
case $ID in
@@ -602,6 +607,8 @@ install_mc_repo() {
if [[ $ID == "ubuntu" ]] \
&& [[ $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
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
Types: deb
URIs: http://dist.jriver.com/latest/mediacenter/
@@ -613,9 +620,8 @@ install_mc_repo() {
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"
fi
install_package wget
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
;;
*)
@@ -625,8 +631,8 @@ install_mc_repo() {
;;
esac
echo "Adding MC repository to $repo_file"
sudo tee "$repo_file" > /dev/null <<< "$repo_text"
echo "Adding MC repository file: $repo_file"
sudo tee "$repo_file" &>/dev/null <<< "$repo_text"
if ! "${PKG_UPDATE[@]}"; then
err "Package update failed!"
@@ -646,12 +652,9 @@ install_mc_repo() {
# @description Acquires the source DEB package from JRiver
acquire_deb() {
debug "Running: ${FUNCNAME[0]}"
local fname="MediaCenter-$MC_VERSION-$ARCH.deb"
declare -g MC_DEB="$OUTPUT_DIR/SOURCES/$fname"
debug "MC_DEB=$MC_DEB"
# If deb file already exists, skip download
if [[ -f $MC_DEB ]]; then
if [[ $(stat -c%s "$MC_DEB") -lt 10000000 ]]; then
@@ -673,7 +676,7 @@ acquire_deb() {
# Loop through the repositories and attempt to download
for repo in "${repos[@]}"; do
echo "Checking $repo for DEB package"
if execute wget --quiet --output-document "$MC_DEB" "$repo"; then
if download "$repo" "$MC_DEB"; then
echo "Found"
break
fi
@@ -783,7 +786,7 @@ build_rpm() {
requires="${requires%?}"
recommends="${recommends%?}"
if (( COMPAT_SWITCH )); then
if ((COMPAT_SWITCH)); then
# Strip minimum versions
requires=$(echo "$requires" | awk -F" " 'NF == 4 {print $1 " " $2} NF != 4 {print $0}')
fi
@@ -815,7 +818,7 @@ build_rpm() {
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/
%define __provides_exclude_from ^%{_libdir}/jriver/.*/.*\\.so.*$
@@ -856,8 +859,7 @@ build_rpm() {
echo "Build successful. The RPM file is located at: $MC_RPM"
else
err "Build failed"
# For automation, let's remove the source DEB and reaquire it on next
# run after failure in case it is corrupted or buggy
# After failire, remove the source DEB and reaquire it on next run
[[ -f $MC_DEB ]] && echo "Removing source DEB" && execute rm -f "$MC_DEB"
exit 1
fi
@@ -867,21 +869,20 @@ build_rpm() {
install_mc_deb() {
debug "Running: ${FUNCNAME[0]}"
if (( COMPAT_SWITCH )); then
declare extract_dir && extract_dir="$(mktemp -d)"
if ((COMPAT_SWITCH)); then
local extract_dir; extract_dir="$(mktemp -d)"
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 tar xJf "control.tar.xz"
# Remove minimum version specifiers from control file
sed -i 's/ ([^)]*)//g' "control"
# Remove libwebkit2gtk and their fantastic package versioning strategy
sed -i 's/,\s*libwebkit2gtk[^,]*,\?|libwebkit2gtk[^,]*,\?//g' "control"
# TODO ugly ZorinOS workaround
# TODO workaround for ZorinOS
[[ $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"
execute tar -cJf "control.tar.xz" "control" "postinst"
@@ -891,21 +892,27 @@ install_mc_deb() {
execute rm -rf "$extract_dir"
fi
install_package \
if ! install_package \
--no-install-check \
--no-gpg-check \
--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
install_mc_rhel() {
debug "Running: ${FUNCNAME[0]}"
# Swap in freeworld hardware acceleration separately from the RPM
install_mesa_freeworld
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
install_mc_generic() {
debug "Running: ${FUNCNAME[0]}"
local -a raw_files
local extract_dir
local -a raw_files
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
run_createrepo() {
debug "Running: ${FUNCNAME[0]}"
local -a cr_cmd
install_package createrepo_c
@@ -1042,7 +1047,6 @@ run_createrepo() {
# @description Symlink certificates if they do not exist in default location
link_ssl_certs() {
debug "Running: ${FUNCNAME[0]}"
local target_cert f
local mc_cert_link="$MC_ROOT/ca-certificates.crt"
local -a source_certs=(
@@ -1066,8 +1070,7 @@ link_ssl_certs() {
# @description Restore the mjr license file from MJR_FILE or other common locations
restore_license() {
debug "Running: ${FUNCNAME[0]}"
local f newest
local newest f
local -a mjrfiles
# Glob mjr files from common directories
@@ -1107,7 +1110,6 @@ restore_license() {
# @arg $2 array List of ports in firewall-cmd format
open_firewall() {
debug "Running: ${FUNCNAME[0]}" "$*"
local port
local service="$1"
shift
@@ -1146,7 +1148,6 @@ open_firewall() {
# @arg $1 string Service type (xvnc, x11vnc)
set_vnc_pass() {
debug "Running: ${FUNCNAME[0]}"
local vncpassfile="$HOME/.vnc/jrmc_passwd"
[[ -d ${vncpassfile%/*} ]] || execute mkdir -p "${vncpassfile%/*}"
@@ -1167,7 +1168,7 @@ set_vnc_pass() {
elif [[ $1 == "x11vnc" ]]; then
execute x11vnc -storepasswd "$VNCPASS" "$vncpassfile"
fi
return $?
return
else
declare -g NOVNCAUTH=1
fi
@@ -1176,7 +1177,6 @@ set_vnc_pass() {
# @description Set display and port variables
set_display_vars() {
debug "Running: ${FUNCNAME[0]}"
declare -g THIS_DISPLAY THIS_DISPLAY_NUM NEXT_DISPLAY
# 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_NUM%%.*}" # strip suffix
# Increment each time we run this
if (( NEXT_DISPLAY_NUM )); then
declare -g NEXT_DISPLAY_NUM=$(( NEXT_DISPLAY_NUM + 1 ))
if ((NEXT_DISPLAY_NUM)); then
declare -g NEXT_DISPLAY_NUM=$((NEXT_DISPLAY_NUM + 1))
else
declare -g NEXT_DISPLAY_NUM=$(( THIS_DISPLAY_NUM + 1 ))
declare -g NEXT_DISPLAY_NUM=$((THIS_DISPLAY_NUM + 1))
fi
NEXT_DISPLAY=":$NEXT_DISPLAY_NUM"
}
@@ -1196,7 +1196,6 @@ set_display_vars() {
# @arg $1 string Service name
set_service_vars() {
debug "Running: ${FUNCNAME[0]}" "$*"
declare -g SERVICE_NAME SERVICE_FNAME TIMER_NAME TIMER_FNAME
declare -g USER_STRING GRAPHICAL_TARGET
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
service_jriver-mediaserver() {
debug "Running: ${FUNCNAME[0]}"
set_service_vars "${FUNCNAME[0]##*_}" "user"
service_jriver-mediacenter "/MediaServer"
}
@@ -1289,14 +1286,13 @@ service_jriver-mediaserver() {
# TODO https://github.com/TigerVNC/tigervnc/blob/master/unix/vncserver/HOWTO.md
service_jriver-xvnc() {
debug "Running: ${FUNCNAME[0]}"
local -a start_cmd
set_service_vars "${FUNCNAME[0]##*_}" "system"
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
set_vnc_pass xvnc
start_cmd=(
@@ -1307,7 +1303,7 @@ service_jriver-xvnc() {
-xstartup "/usr/bin/mediacenter$MC_MVERSION"
)
if (( NOVNCAUTH )); then
if ((NOVNCAUTH)); then
start_cmd+=(
-name "jriver$NEXT_DISPLAY"
-SecurityTypes None)
@@ -1338,7 +1334,7 @@ service_jriver-xvnc() {
if ! "${ENABLE[@]}" "$SERVICE_NAME"; then
err "vncserver failed to start on DISPLAY $NEXT_DISPLAY"
# Allow to increment 10 times before breaking
max=$(( THIS_DISPLAY_NUM + 10 ))
max=$((THIS_DISPLAY_NUM + 10))
while [[ $NEXT_DISPLAY_NUM -lt $max ]]; do
echo "Incrementing DISPLAY and retrying"
service_jriver-xvnc && return
@@ -1355,15 +1351,11 @@ service_jriver-xvnc() {
# @description Starts and enables (at startup) x11vnc screen sharing for the local desktop
service_jriver-x11vnc() {
debug "Running: ${FUNCNAME[0]}"
local -a start_cmd
set_service_vars "${FUNCNAME[0]##*_}" "user"
set_display_vars
local -a start_cmd
declare -g PORT=$(( THIS_DISPLAY_NUM + 5900 ))
declare -g PORT=$((THIS_DISPLAY_NUM + 5900))
install_package x11vnc
set_vnc_pass x11vnc
# If .Xauthority file is missing, generate a dummy for x11vnc -auth guess
@@ -1386,7 +1378,7 @@ service_jriver-x11vnc() {
-bg
)
if (( NOVNCAUTH )); then
if ((NOVNCAUTH)); then
start_cmd+=(-nopw)
else
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
disable_btrfs_cow() {
debug "Running: ${FUNCNAME[0]}"
local dir
local mc_user_path="$HOME/.jriver"
@@ -1476,7 +1467,6 @@ disable_btrfs_cow() {
# @description Completely uninstalls MC, services, and firewall rules
uninstall() {
debug "Running: ${FUNCNAME[0]}"
local service unit f i
echo "Stopping and removing all Media Center services"
@@ -1503,10 +1493,11 @@ uninstall() {
unset f
done
echo "Removing repo files"
echo "Removing MC repositories"
execute sudo rm -rf \
"/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
execute sudo zypper --non-interactive removerepo jriver
fi
@@ -1523,11 +1514,11 @@ uninstall() {
fi
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 "To remove your MC library: rm -rf $HOME/.jriver"
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
err "Could not remove Media Center package"
fi
@@ -1546,13 +1537,9 @@ uninstall() {
# @description Checks for installJRMC update and re-executes, if necessary
update() {
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"
# Function to extract and normalize version from a script
# Extract and normalize version from a script
extract_version() {
local version_line
version_line=$(grep -m 1 'SCRIPT_VERSION=' "$1")
@@ -1563,51 +1550,77 @@ update() {
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
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
debug "installJRMC git repository detected. Running git pull..."
&& [[ "$(git -C "$SCRIPT_DIR" config --get remote.origin.url)" == *"installJRMC"* ]]; then
debug "installJRMC git repository detected. Running git pull"
# 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)
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
fi
local after_pull_hash
# Get the new commit hash after pull
after_pull_hash=$(git -C "$SCRIPT_DIR" rev-parse HEAD)
# If the commit hash has changed, an update occurred
if [[ "$before_pull_hash" != "$after_pull_hash" ]]; then
echo "installJRMC repository updated. Restarting script..."
echo "Detected installJRMC update, restarting"
exec "$SCRIPT_PATH" "$@" "--no-update"
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
fi
# Extract the latest version number
local remote_version
remote_version=$(extract_version "$tmp")
if [[ -z "$remote_version" ]]; then
err "Failed to extract version from the downloaded script."
execute rm -f "$tmp"
return 1
fi
# 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
# Download the latest version of the script
install_package --silent wget
if command -v wget &>/dev/null; then
execute wget -q -O "$tmp" "$script_url"
elif command -v curl &>/dev/null; then
execute curl -s -L -o "$tmp" "$script_url"
else
return 1
fi
# Get latest version number
local remote_version
remote_version=$(extract_version "$tmp")
[[ -z $remote_version ]] && { rm -f "$tmp"; return 1; }
# Compare versions and update if necessary
if [[ $SCRIPT_VERSION < $remote_version ]]; then
echo "Updating installJRMC $SCRIPT_VERSION to $remote_version"
execute mv "$tmp" "$SCRIPT_PATH"
execute chmod +x "$SCRIPT_PATH"
exec "$SCRIPT_PATH" "$@" "--no-update"
fi
rm -f "$tmp"
}
# @description installJRMC main function
@@ -1615,7 +1628,7 @@ main() {
debug "Running: ${FUNCNAME[0]} $*"
echo "Starting installJRMC $SCRIPT_VERSION"
if (( DEBUG )); then
if ((DEBUG)); then
echo "Debugging on"
else
echo "To enable debugging output, use --debug or -d"
@@ -1624,7 +1637,7 @@ main() {
# Parse input, set default/host variables, and MC version
init "$@"
if (( UNINSTALL_SWITCH )); then
if ((UNINSTALL_SWITCH)); then
if ask_ok "Do you really want to uninstall JRiver Media Center?"; then
uninstall
else
@@ -1635,7 +1648,7 @@ main() {
install_external_repos
if (( REPO_INSTALL_SWITCH )); then
if ((REPO_INSTALL_SWITCH)); then
echo "Installing JRiver Media Center from remote repository"
if install_mc_repo; then
echo "JRiver Media Center installed successfully from remote repository"
@@ -1649,20 +1662,19 @@ main() {
fi
fi
if (( BUILD_SWITCH )) && [[ $ID != "arch" ]]; then
install_package "wget"
if ((BUILD_SWITCH)) && [[ $ID != "arch" ]]; then
[[ -d $OUTPUT_DIR/SOURCES ]] || execute mkdir -p "$OUTPUT_DIR/SOURCES"
acquire_deb || { err "Could not download Media Center DEB package"; return 1; }
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"
build_rpm
fi
fi
if (( LOCAL_INSTALL_SWITCH )); then
if PKG_INSTALL_LOCAL; then
if ((LOCAL_INSTALL_SWITCH)); then
if PKG_INSTALL_LOCAL "$@"; then
echo "JRiver Media Center installed successfully from local package"
else
err "JRiver Media Center local package installation failed"
@@ -1674,7 +1686,7 @@ main() {
disable_btrfs_cow
fi
if (( CREATEREPO_SWITCH )); then
if ((CREATEREPO_SWITCH)); then
if run_createrepo; then
echo "Successfully updated repo"
else
@@ -1710,11 +1722,11 @@ main() {
}
# @section Helper functions
debug() { (( DEBUG )) && echo "Debug: $*"; }
debug() { ((DEBUG)) && echo "Debug: $*"; }
err() { echo "Error: $*" >&2; }
ask_ok() {
declare response
(( YES_SWITCH )) && return 0
((YES_SWITCH)) && return 0
read -r -p "$* [y/N]: " response
[[ ${response,,} =~ ^(yes|y)$ ]]
}
@@ -1725,6 +1737,39 @@ execute() {
"$@" &>/dev/null
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
[[ " $* " =~ ( --debug | -d ) ]] && declare -g DEBUG=1