31 Commits

Author SHA1 Message Date
8aa01958ff 1.34.1 release 2025-06-02 20:12:18 -04:00
dc0eaed0f6 Use internal package name 2025-06-02 20:06:51 -04:00
f227050f6c Fix rpm --query lookup for --reinstall 2025-06-02 20:04:20 -04:00
d3c049818a Make install_mesa_freeworld fedora-specific 2025-06-02 19:56:54 -04:00
17512a2c00 Improve recommends for freeworld packages on fedora 2025-06-02 19:49:00 -04:00
444ebbfa25 Improve recommends for freeworld packages on fedora 2025-06-02 19:46:54 -04:00
8de1608a77 Also remove /usr/lib/jriver 2025-06-02 19:25:24 -04:00
361dcb8ce3 Return successfully 2025-06-02 19:17:39 -04:00
8af309488d Re-enable dnf reinstalls 2025-06-02 19:13:46 -04:00
d5aecc6902 Disable CoW recursively in ~/.jriver 2025-06-02 18:51:40 -04:00
82b31361d4 Only disable CoW for ~/.jriver 2025-06-02 18:50:05 -04:00
96d6044c85 Make temp repos more prolific 2025-06-02 18:18:08 -04:00
71c21bf084 Simplify legacy checks 2025-06-02 17:28:26 -04:00
8388a3ab26 Streamline version check 2025-06-02 17:12:21 -04:00
9b978e43b7 Clobber repo file 2025-06-02 17:09:10 -04:00
4b166fd025 use a single suite 2025-06-02 17:03:12 -04:00
de2032d389 Add temp debug 2025-06-02 16:57:58 -04:00
f21e162177 Selectively remove repo files for --uninstall 2025-06-02 16:41:32 -04:00
768e00dff3 Ask to backup and reset library on --uninstall 2025-06-02 16:36:34 -04:00
5e890900f2 Ask to backup and reset library on --uninstall 2025-06-02 16:33:35 -04:00
18a3ae02fa Narrow --uninstall output 2025-06-02 16:20:56 -04:00
c729f1fb9b Allow --uninstall to be used seamlessly before other operations 2025-06-02 16:16:12 -04:00
cc7c1d4c5f Also uninstall installJRMC output 2025-06-02 15:56:27 -04:00
36548581d3 Return on successful license restore 2025-06-02 15:33:10 -04:00
605dc78cf8 Cleanup documentation 2025-06-02 15:26:30 -04:00
8b464fffc7 Add README.bbcode 2025-06-02 13:45:28 -04:00
eb9c9fbf9d Rollup for new minor version, may be buggy 2025-06-02 13:43:23 -04:00
afb9ff6ed5 Make createrepo noisier 2025-05-06 14:55:06 -04:00
dfac619e9d Append dev to version name 2025-04-28 21:21:29 -04:00
005fe17298 Pass --mcrepo to createrepo service 2025-04-28 21:15:25 -04:00
190a6e7b10 Move UID check after parse 2025-04-28 21:07:11 -04:00
4 changed files with 391 additions and 186 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,5 @@
.old/
.vscode/
README.bbcode
installJRMC.zip
README.shdoc.md
output/

136
README.bbcode Normal file
View File

@@ -0,0 +1,136 @@
[size=20pt]installJRMC[/size]
This program will install [url=https://www.jriver.com/]JRiver Media Center[/url] and associated services on most Linux distributions.
You can find the latest version of installJRMC, changelog, and documentation in [url=https://git.bryanroessler.com/bryan/installJRMC]my repository[/url].
[size=18pt]tl;dr One-line MC install[/size]
[code]curl https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC|bash[/code]
[size=18pt]Instructions[/size]
Download and unzip installJRMC from the attachment below or grab the latest stable version directly:
[code]curl -O https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC &&
chmod +x ./installJRMC &&
./installJRMC [--option [ARGUMENT]]
[/code]
[tt]installJRMC[/tt] defaults to [tt]--install=repo[/tt] on distros with MC repositories and [tt]--install=local[/tt] on all others.
Specifying [tt]--build[/tt], [tt]--createrepo[/tt], [tt]--service[/tt], or [tt]--uninstall[/tt] disables the default install method.
[size=18pt]Options[/size]
[code]
$ installJRMC --help
--install, -i repo|local
repo: Install MC from repository, future updates will be handled by the system package manager
local: Build and install MC package from official source package
--build[=suse|fedora|centos]
Build RPM from source DEB but do not install
Optionally, specify a target distro for cross-building (ex. --build=suse, note the '=')
--compat
Build/install MC without minimum dependency version requirements
--mcversion VERSION
Specify the MC version, ex. "33", "34.0.31", or "34.0.31-1" (default: latest)
--arch ARCH
Specify the target MC architecture, ex. "amd64", "arm64", etc (default: host architecture)
--mcrepo REPO
Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: host or official)
--outputdir PATH
Generate reusable installJRMC output in this PATH (default: ./output)
--restorefile RESTOREFILE
Restore file location for automatic license registration
--betapass PASSWORD
Enter beta team password for access to beta builds
--service, -s SERVICE
See SERVICES section below for the list of services to deploy
--service-type user|system
Starts services at boot (system) or user login (user) (default: per-service, see SERVICES)
--container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of containers to deploy
--createrepo[=suse|fedora|centos]
Build rpm, copy to webroot, and run createrepo.
Optionally, specify a target distro for non-native repo (ex. --createrepo=fedora, note the '=')
--createrepo-webroot PATH
The webroot directory to install the repo (default: /var/www/jriver/)
--createrepo-user USER
The web server user if different from the current user
--no-update
Disable the installJRMC update check
--yes, -y, --auto
Always assumes yes for questions
--version, -v
Print installJRMC version and exit
--debug, -d
Print debug output
--help, -h
Print help dialog and exit
--uninstall, -u
Uninstall JRiver MC, service files, and firewall rules (does not remove library or media files)
[/code]
[size=18pt]Services[/size]
[code]jriver-mediaserver (user)
Enable and start a mediaserver systemd service (requires an existing X server)
jriver-mediacenter (user)
Enable and start a mediacenter systemd service (requires an existing X server)
jriver-x11vnc (user)
Enable and start x11vnc for the local desktop (requires an existing X server, does NOT support Wayland)
--vncpass and --display are also valid options (see below)
jriver-xvnc (system)
Enable and start a new Xvnc session running JRiver Media Center
--vncpass PASSWORD
Set vnc password for x11vnc/Xvnc access. If no password is set, the script will either use existing password stored in ~/.vnc/jrmc_passwd or else no password
--display DISPLAY
Manually specify display to use for x11vnc/Xvnc (ex. ':1')
jriver-createrepo (system)
Install hourly service to build latest MC RPM and run createrepo
[/code]
Services use a sane default [tt]--service-type[/tt] listed next to the service name in the Services description.
User services can be manipulated as an unprivileged user, for example: [tt]systemctl --user stop jriver-mediacenter[/tt] and begin at user login.
System services are manipulable as root, for example: [tt]sudo systemctl stop jriver-servicename@username.service[/tt] and begin at system boot.
Note that it is possible to run all services of a particular user at boot using [tt][url=https://www.freedesktop.org/software/systemd/man/loginctl.html]sudo loginctl enable-linger username[/url][/tt].
Multiple services (but not [tt]--service-types[/tt]) can be installed at one time using multiple [tt]--service[/tt] blocks:
[code]installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter[/code]
[size=14pt][tt]jriver-x11vnc[/tt] versus [tt]jriver-xvnc[/tt][/size]
[url=http://www.karlrunge.com/x11vnc/]jriver-x11vnc[/url] shares your existing X display via VNC and can be combined with additional services to start Media Center or Media Server. Conversely, [url=https://tigervnc.org/doc/Xvnc.html]jriver-xvnc[/url] creates a new Xvnc display and starts a JRiver Media Center service in the foreground of the new VNC display.
[size=18pt]Containers[/size]
[b]Coming soon![/b]
[size=18pt]Firewall[/size]
installJRMC automatically creates port forwarding firewall rules for remote access to Media Network (52100-52200/tcp, 1900/udp DLNA) and Xvnc/x11vnc (if selected), using firewall-cmd or ufw.
[size=18pt]Examples[/size]
[code]installJRMC[/code]
Install the latest version of MC from the best available repository.
[code]installJRMC --mcversion 33 --debug[/code]
Install the latest version of MC33 from the best available repository with debugging output.
[code]installJRMC --install local --compat[/code]
Install a more widely-compatible version of the latest MC version.
[code]installJRMC --install repo --service jriver-mediacenter --service-type user[/code]
Install MC from the repository and start/enable jriver-mediacenter.service as a user service.
[code]installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 34.0.31[/code]
Build and install an MC 34.0.31 comptability RPM locally and activate it using the /path/to/license.mjr
[code]installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user[/code]
Build an RPM locally for the current distro, move it to the webroot, and run createrepo as www-user.
[code]installJRMC --service jriver-createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user[/code]
Install the jriver-createrepo timer and service to build the RPM, move it to the webroot, and run createrepo as www-user hourly.
[code]installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"[/code]
Install services to share the existing local desktop via VNC and automatically run MC on startup.
[code]installJRMC --install repo --service jriver-xvnc --display ":2"[/code]
Install an Xvnc server on display ':2' that starts MC.
[code]installJRMC --uninstall[/code]
Uninstall MC, services, and firewall rules. This will [b]not[/b] remove your media, media library/database, or library backups.
[size=18pt]Additional Info[/size]
Did you find installJRMC useful? [url=https://paypal.me/bryanroessler]Buy me a coffee![/url]

View File

@@ -1,6 +1,6 @@
# installJRMC
This self-contained program will install [JRiver Media Center](https://www.jriver.com/) and associated services on most Linux distributions.
This program will install [JRiver Media Center](https://www.jriver.com/) and associated services on most Linux distributions.
You can find the latest version of installJRMC, changelog, and documentation in [my repository](https://git.bryanroessler.com/bryan/installJRMC).
@@ -8,11 +8,10 @@ You can find the latest version of installJRMC, changelog, and documentation in
`installJRMC [--option [ARGUMENT]]`
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).
`installJRMC` defaults to `--install=repo` on distros with MC repositories and `--install=local` on all others.
Specifying `--build`, `--createrepo`, `--service`, or `--uninstall` disables the default install method.
Recent versions of installJRMC will automatically self-update to the latest installJRMC release.
## tl;dr
### tl;dr
`curl https://git.bryanroessler.com/bryan/installJRMC/raw/master/installJRMC|bash`
@@ -29,7 +28,7 @@ $ installJRMC --help
--compat
Build/install MC without minimum dependency version requirements
--mcversion VERSION
Build or install a specific MC version, ex. "34.0.20" or "33" (default: latest)
Build or install a specific MC version, ex. "34.0.31" or "33" (default: latest)
--mcrepo REPO
Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: latest official)
--arch ARCH
@@ -58,7 +57,7 @@ $ installJRMC --help
--yes, -y, --auto
Always assume yes for questions
--version, -v
Print this script version and exit
Print installJRMC version and exit
--debug, -d
Print debug output
--help, -h
@@ -85,14 +84,13 @@ jriver-xvnc [--service-type=system]
Manually specify display to use for x11vnc/Xvnc (ex. ':1')
jriver-createrepo [--service-type=system]
Install hourly service to build latest MC RPM and run createrepo
By default installs as root service to handle www permissions more gracefully
```
#### `--service-type=`
By default, MC services use a sane `--service-type` listed next to the service name in the [`--service=`](#--service) section. User services begin at user login and are managed by the unprivileged user, for example: `systemctl --user stop jriver-mediacenter`. System services begin at boot and are managed by root, for example: `sudo systemctl stop jriver-servicename@username.service`. It is possible to run all services of a particular user at boot using [`sudo loginctl enable-linger username`](https://www.freedesktop.org/software/systemd/man/loginctl.html).
Services use a sane default `--service-type` listed next to the service name in the [`--service=`](#--service) section. User services begin at user login and are managed by the unprivileged user, for example: `systemctl --user stop jriver-mediacenter`. System services begin at boot and are managed by root, for example: `sudo systemctl stop jriver-servicename@username.service`. It is possible to run all services of a particular user at boot using [`sudo loginctl enable-linger username`](https://www.freedesktop.org/software/systemd/man/loginctl.html).
Multiple services (but not `--service-types`) can be installed at one time using multiple `--service` blocks: `installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter`
Multiple services (but not `--service-types`) can be installed at one time using multiple `--service` blocks: `installJRMC --install=repo --service=jriver-x11vnc --service=jriver-mediacenter`
#### `jriver-x11vnc` versus `jriver-xvnc`
@@ -108,15 +106,26 @@ Multiple services (but not `--service-types`) can be installed at one time using
**Note:** `ufw` is not installed by default on Debian but will be installed by `installJRMC`. To prevent SSH lock-out, Debian users that have not already enabled `ufw` will need to `sudo ufw enable` after running `installJRMC` and inspecting their configuration.
## Nicities
Depending on the distribution, `installJRMC` also performs the following tasks during MC installation:
* Automatically updates `installJRMC` to the latest release
* Activates external third-party repositories for improved media playback (hardware decoding, etc.)
* Adds temporary legacy repositories to provide deprecated libraries
* Links non-standard SSL certs
* Disables BTRFS CoW for MC database directories
* Activates MC if a valid license file is found in common locations
## Examples
* `installJRMC`
Install the latest version of MC from the best available repository.
* `installJRMC --mcversion 32 --debug`
* `installJRMC --mcversion 33 --debug`
Install the latest version of MC32 from the best available repository with debugging output.
Install the latest version of MC33 from the best available repository with debugging output.
* `installJRMC --install local --compat`
@@ -126,9 +135,9 @@ Multiple services (but not `--service-types`) can be installed at one time using
Install MC from the repository and start/enable `jriver-mediacenter.service` as a user service.
* `installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 34.0.20`
* `installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 34.0.31`
Build and install an MC 34.0.20 compatibility RPM locally and activate it using the `/path/to/license.mjr`
Build and install an MC 34.0.31 compatibility RPM locally and activate it using the `/path/to/license.mjr`
* `installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user`
@@ -154,4 +163,4 @@ Multiple services (but not `--service-types`) can be installed at one time using
Did you find `installJRMC` useful? [Buy me a coffee!](https://paypal.me/bryanroessler)
Did you find a bug? Let me know on [Interact!](https://yabb.jriver.com/interact/index.php/topic,134152.0.html)
Did you find a bug? [Let me know on Interact!](https://yabb.jriver.com/interact/index.php/topic,141168.0.html)

View File

@@ -1,5 +1,4 @@
#!/usr/bin/env bash
# shellcheck disable=SC2317
# @file installJRMC
# @brief Installs JRiver Media Center and associated services
# @description See installJRMC --help or print_help() below for usage
@@ -17,10 +16,13 @@
# NOTES
# * Be careful with tabs in heredocs
# * Avoid execute() for stdout
#
# We use indirection to match service names to their functions
# shellcheck disable=SC2317
shopt -s extglob
declare -g SCRIPT_VERSION="1.6.5"
declare -g MC_VERSION="34.0.20" # do find all replace
declare -g SCRIPT_VERSION="1.34.1"
declare -g MC_VERSION="34.0.31" # do find all replace
declare -g MC_REPO="bookworm" # should match the MC_VERSION
declare -g BOARD_ID="89.0" # MC34
declare -gi UPDATE_SWITCH=1 # set to 0 to disable automatic self-update
@@ -33,28 +35,32 @@ print_help() {
debug "${FUNCNAME[0]}()"
cat <<-EOF
SEE:
README.md for more information
USAGE:
installJRMC [[OPTION] [VALUE]]...
If no options (excluding -d or --debug) are provided installJRMC defaults to '--install repo'.
installJRMC defaults to --install=repo on platforms with a JRiver repository and --install=local on all others.
Specifying --build, --createrepo, --service, or --uninstall disables the default install method.
OPTIONS
--install, -i repo|local
repo: Install MC from repository, updates are handled by the system package manager
local: Build and install MC package locally from official source release
local: Build and install MC locally from official source package
--build[=suse|fedora|centos]
Build RPM from source DEB but do not install
Optionally, specify a target distro for cross-building (ex. --build=suse, note the '=')
--compat
Build/install MC locally without minimum dependency version requirements
--mcversion VERSION
Specify the MC version, ex. "$MC_VERSION" or "${MC_VERSION%%.*}"
Specify the MC version, ex. "$MC_VERSION" or "${MC_VERSION%%.*}" (default: latest release)
--arch VERSION
Specify the target MC architecture, ex. "amd64", "arm64", etc (default: host)
--mcrepo REPO
Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: auto)
--outputdir PATH
Generate rpmbuild output in this directory (default: ./output)
Generate reusable installJRMC output in this PATH (default: ./output)
--restorefile MJR_FILE
Restore file location for automatic license registration
--betapass PASSWORD
@@ -80,7 +86,7 @@ print_help() {
--yes, -y, --auto
Assume yes response to questions
--version, -v
Print this script version and exit
Print installJRMC version and exit
--debug, -d
Print debug output
--help, -h
@@ -99,16 +105,12 @@ print_help() {
Enable and start a new Xvnc session running JRiver Media Center
--vncpass PASSWORD
Set the vnc password for x11vnc/Xvnc access. If no password is set, installJRMC
will either use existing password stored in \$HOME/.vnc/jrmc_passwd or use no password
will either use existing password stored in \$HOME/.vnc/jrmc_passwd or else no password
--display DISPLAY
Display to use for x11vnc/Xvnc (default: The current display (x11vnc) or the
current display incremented by 1 (Xvnc))
jriver-createrepo (system)
Install hourly service to build latest MC RPM and run createrepo
CONTAINERS (TODO: Under construction)
mediacenter-xvnc
createrepo
EOF
}
@@ -134,8 +136,7 @@ parse_input() {
eval set -- "$input"
while true; do
case $1 in
--install|-i)
shift
--install|-i) shift;
case $1 in
local|rpm|deb) BUILD_SWITCH=1 LOCAL_INSTALL_SWITCH=1 ;;
repo|remote) REPO_INSTALL_SWITCH=1 ;;
@@ -151,10 +152,10 @@ parse_input() {
if [[ $1 =~ ^([0-9]+)(\.[0-9]+\.[0-9]+)?(-([0-9]+))?$ ]]; then
# Major version is required
USER_MC_MVERSION="${BASH_REMATCH[1]}"
# If we get the full version, use it
[[ -n ${BASH_REMATCH[2]} ]] && USER_MC_VERSION="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
# Set default release to 1 if not provided
USER_MC_RELEASE="${BASH_REMATCH[4]:-1}"
# If we get the full version, use it
[[ -n ${BASH_REMATCH[2]} ]] && USER_MC_VERSION="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
# Set major version defaults
case "$USER_MC_MVERSION" in
@@ -181,7 +182,7 @@ parse_input() {
;;
--arch) shift; USER_ARCH="$1" ;;
--mcrepo) shift; USER_MC_REPO="$1" ;;
--restorefile) shift; MJR_FILE="$1" ;;
--restorefile) shift; MJR_FILE="$1"; [[ -f $MJR_FILE ]] || err "Specified license $MJR_FILE missing." ;;
--betapass) shift; BETAPASS="$1" ;;
--service-type) shift; SERVICE_TYPE="$1" ;;
--service|-s|--services) shift; SERVICES+=("$1") ;;
@@ -207,12 +208,11 @@ parse_input() {
err "Incorrect option provided, see installJRMC --help"; exit 1
fi
# Fallback to default install method in some scenarios
if ! ((UNINSTALL_SWITCH + BUILD_SWITCH + CREATEREPO_SWITCH +
LOCAL_INSTALL_SWITCH + CONTAINER_INSTALL_SWITCH + SNAP_INSTALL_SWITCH +
APPIMAGE_INSTALL_SWITCH)) &&
# Set some default conditions
if ! ((UNINSTALL_SWITCH || BUILD_SWITCH || CREATEREPO_SWITCH || LOCAL_INSTALL_SWITCH
|| CONTAINER_INSTALL_SWITCH || SNAP_INSTALL_SWITCH || APPIMAGE_INSTALL_SWITCH)) &&
[[ ${#SERVICES[@]} -eq 0 && ${#CONTAINERS[@]} -eq 0 ]]; then
debug "Automatically using --install=repo"
debug "Defaulting to --install=repo"
REPO_INSTALL_SWITCH=1
fi
@@ -220,16 +220,12 @@ parse_input() {
echo "Warning: not all repositories have beta channels"
echo "If the MC package is unavailable, try using --mcrepo to select another repository"
fi
# if [[ -n $CONTAINER_INSTALL_SWITCH ]] && ((LOCAL_INSTALL_SWITCH || REPO_INSTALL_SWITCH)); then
# err "Some --install methods are incompatible"
# fi
}
# @description Perform OS detection and generate OS-specific functions
# @see parse_input
init() {
debug "${FUNCNAME[0]}()"
debug "${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]}")")
@@ -241,20 +237,18 @@ init() {
declare -ga PKG_INSTALL PKG_REMOVE PKG_UPDATE PKG_QUERY
declare -ga SERVICES CONTAINERS
# Try to save users from themselves
if ((EUID == 0)); then
err "Running as root but attempting to continue"
ask_ok "Continue as root user?" || exit 1
fi
parse_input "$@"
if [[ -n $SUDO_USER ]]; then
# Try to save users from themselves
if [[ $EUID -eq 0 ]]; then
err "Running as root but attempting to continue"
ask_ok "Continue as root user (not recommended)?" || exit 1
elif [[ -n $SUDO_USER ]]; then
err "Sudo detected, installJRMC should not be run with sudo but attempting to continue"
ask_ok "Continue as user $SUDO_USER (unsupported and may result in permission issues)?" || exit 1
USER="${SUDO_USER:-$USER}"
fi
parse_input "$@"
# Run the self-updater if enabled
((UPDATE_SWITCH)) && update "$@"
@@ -293,7 +287,7 @@ init() {
raspbian) ID="debian" ;;
manjaro|arch) ID="arch"
if ((REPO_INSTALL_SWITCH)); then
debug "Automatically using --install=local for SUSE"
debug "Automatically using --install=local for Arch"
REPO_INSTALL_SWITCH=0
BUILD_SWITCH=1
LOCAL_INSTALL_SWITCH=1
@@ -384,7 +378,7 @@ init() {
fi
MC_REPO="${USER_MC_REPO:-$MC_REPO}" # allow user override
echo "MC target: $MC_REPO $MC_ARCH -> $BUILD_TARGET $ARCH"
echo "MC source -> target: $MC_REPO $MC_ARCH -> $BUILD_TARGET $ARCH"
# Retrieves the latest MC version number if we need it
if ((BUILD_SWITCH || LOCAL_INSTALL_SWITCH || CREATEREPO_SWITCH)); then
@@ -433,7 +427,7 @@ get_latest_mc_version() {
err "Warning! Using hardcoded version number"
fi
echo "Determined MC version $MC_VERSION from the $MC_REPO repo (via $mc_version_source)"
echo "Selected MC version $MC_VERSION from the $MC_REPO repo (via $mc_version_source)"
}
# @description Installs a package using the system package manager
@@ -449,6 +443,7 @@ install_package() {
local input pkg _pkg
local -i no_install_check=0 allow_downgrades=0 silent=0 refresh=0 no_gpg_check=0 reinstall=0
local long_opts="no-install-check,allow-downgrades,no-gpg-check,refresh,reinstall,silent"
local -a pkg_install=("${PKG_INSTALL[@]}")
input=$(getopt -o +s -l "$long_opts" -- "$@") || { err "Incorrect options provided"; exit 1; }
eval set -- "$input"
@@ -482,27 +477,20 @@ install_package() {
# Filter out already installed packages to create pkg_array
for pkg in "$@"; do
# Use alias if present, otherwise just pkg itself
pkg_names=("$pkg")
if [[ -v pkg_aliases[$pkg] ]]; then
debug "Aliasing $pkg to ${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")
IFS=' ' read -ra pkg_names <<< "${pkg_aliases[$pkg]}"
fi
for p in "${pkg_names[@]}"; do
if (( no_install_check )) ||
! { command -v "$p" &>/dev/null || "${PKG_QUERY[@]}" "$p" &>/dev/null; }; then
pkg_array+=("$p")
else
debug "$_pkg is already installed, skipping installation"
debug "$p is already installed, skipping installation"
fi
done
else
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
@@ -514,17 +502,18 @@ install_package() {
((allow_downgrades)) && install_flags+=(--allowerasing)
((no_gpg_check)) && install_flags+=(--nogpgcheck)
((refresh)) && install_flags+=(--refresh)
# if ((reinstall)) && [[ ${#pkg_array[@]} -eq 1 ]] && "${PKG_QUERY[@]}" "${pkg_array[0]}" &>/dev/null; then
# PKG_INSTALL=("${PKG_INSTALL[@]/install/reinstall}")
# fi
# Only add reinstall flag for mediacenter package
if ((reinstall)) && [[ ${#pkg_array[@]} -eq 1 ]] && "${PKG_QUERY[@]}" "mediacenter$MC_MVERSION" &>/dev/null; then
pkg_install=("${pkg_install[@]/install/reinstall}")
fi
;;
suse)
((no_gpg_check)) && install_flags+=(--allow-unsigned-rpm) ;;
esac
# Install packages if any need installation
# Install packages
if [[ ${#pkg_array[@]} -gt 0 ]]; then
if ! execute "${PKG_INSTALL[@]}" "${install_flags[@]}" "${pkg_array[@]}"; then
if ! execute "${pkg_install[@]}" "${install_flags[@]}" "${pkg_array[@]}"; then
((silent)) || err "Failed to install ${pkg_array[*]}"
return 1
fi
@@ -568,10 +557,8 @@ install_external_repos() {
install_package --no-install-check \
"https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$VERSION_ID.noarch.rpm"
fi
# Install mesa-va-drivers-freeworld separately from the RPM using dnf swap
install_mesa_freeworld
;;
suse) : # TODO may be needed if X11_XOrg is unavailable in default repos
suse) : # TODO may be needed if X11_XOrg is made unavailable in default repos
# if ! zypper repos | grep -q "X11_XOrg"; then
# echo "Installing the X11 repository"
# execute sudo zypper --non-interactive --quiet addrepo \
@@ -582,10 +569,12 @@ install_external_repos() {
esac
}
# @description Installs mesa-va-drivers-freeworld
# @description Installs mesa-va-drivers-freeworld on Fedora
install_mesa_freeworld() {
debug "${FUNCNAME[0]}()"
local pkg freeworld_pkg
case $ID in
fedora)
for pkg in mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers; do
freeworld_pkg="${pkg}-freeworld"
if ! "${PKG_QUERY[@]}" "$freeworld_pkg" &>/dev/null; then
@@ -598,6 +587,8 @@ install_mesa_freeworld() {
fi
fi
done
;;
esac
}
# @description Installs JRiver Media Center from a remote repository
@@ -627,7 +618,7 @@ install_mc_repo() {
repo_file="/etc/apt/sources.list.d/jriver.sources"
fi
# Remove old repo
# Remove deprecated repo files
old_repo_files=(
"/etc/apt/sources.list.d/jriver.list"
"/etc/apt/sources.list.d/jriver-beta.list"
@@ -642,9 +633,9 @@ install_mc_repo() {
Types: deb
URIs: https://dist.jriver.com/$channel/mediacenter/
Signed-By: $keyfile
Suites: $MC_REPO trixie bookworm bullseye oracular noble jammy focal
Suites: $MC_REPO
Components: main
Architectures: amd64 i386 armhf arm64
Architectures: amd64 armhf arm64
EOF
else
if [[ $channel == "beta" ]]; then
@@ -653,7 +644,7 @@ install_mc_repo() {
else
repo_file="/etc/apt/sources.list.d/jriver.list"
fi
repo_text="deb [signed-by=$keyfile arch=amd64,i386,armhf,arm64] https://dist.jriver.com/$channel/mediacenter/ $MC_REPO main"
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" "-" |
@@ -666,12 +657,24 @@ install_mc_repo() {
;;
esac
if [[ -f $repo_file ]]; then
ask_ok "Replace existing $repo_file repository file" && execute sudo rm -f "$repo_file"
fi
echo "Adding MC repository file: $repo_file"
debug "repo_text: $repo_text"
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
trap 'execute sudo rm -f "$TEMP_REPO_FILE"' EXIT
else
err "Failed to add temporary repository"
return 1
fi
"${PKG_UPDATE[@]}" || { err "Package update failed!"; return 1; }
echo "Installing $MC_PKG package"
if ! install_package \
--no-install-check \
--allow-downgrades \
@@ -681,6 +684,11 @@ install_mc_repo() {
err "Package install failed!"
return 1
fi
# Unset the trap and remove temporary legacy repository
trap - EXIT
[[ -f $TEMP_REPO_FILE ]] && execute sudo rm -f "$TEMP_REPO_FILE"
return 0
}
# @description Acquires the source DEB package from JRiver
@@ -815,7 +823,9 @@ build_rpm() {
requires=("${requires[@]/python/python3}")
requires=("${requires[@]/libwebkit2gtk-4.0*/webkit2gtk4.0}")
requires=("${requires[@]/libwebkit2gtk-4.1*/webkit2gtk4.1}")
recommends+=(mesa-va-drivers-freeworld)
recommends+=("mesa-va-drivers-freeworld|mesa-va-drivers")
recommends+=("mesa-vulkan-drivers-freeworld|mesa-vulkan-drivers")
recommends+=("mesa-vdpau-driver-freeworld|mesa-vdpau-driver")
;;
suse)
requires=("${requires[@]/python*/python313}")
@@ -912,7 +922,7 @@ build_rpm() {
EOF
# Run rpmbuild
echo "Building MC $MC_VERSION RPM, this may take some time"
echo "Building $MC_RPM, this may take some time"
rpmbuild_cmd=(
rpmbuild
--define="_topdir $OUTPUT_DIR"
@@ -925,15 +935,20 @@ build_rpm() {
echo "Build successful. The RPM file is located at: $MC_RPM"
else
err "Build failed"
# After failire, remove the source DEB and reaquire it on next run
[[ -f $MC_DEB ]] && echo "Removing source DEB" && execute sudo rm -f "$MC_DEB"
exit 1
# After failure, remove the source DEB and reaquire it on next run
if [[ -f $MC_DEB ]]; then
echo "Removing source DEB"
if ! execute rm -f "$MC_DEB"; then
execute sudo rm -f "$MC_DEB"
fi
fi
return 1
fi
}
# @description Installs Media Center via DEB package w/ optional compatability fixes
install_mc_deb() {
debug "${FUNCNAME[0]}()"
debug "${FUNCNAME[0]}()" "$@"
if ((COMPAT_SWITCH)); then
local extract_dir; extract_dir="$(mktemp -d)"
@@ -959,44 +974,14 @@ install_mc_deb() {
execute rm -rf "$extract_dir"
fi
# Helper function to add repository
add_temp_repo() {
local repo_name="$1"
local repo_uri="$2"
local repo_suite="$3"
local repo_key="$4"
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"
"${PKG_UPDATE[@]}" || { err "Package update failed!"; return 1; }
}
# Add older repository for libwebkit2gtk-4.0-37, etc, on newer Debian/Ubuntu
local -i remove_temp_repo=0
if [[ "$ID" == "ubuntu" ]]; then
local major_version="${VERSION_ID%%.*}"
local minor_version="${VERSION_ID##*.}"
if [[ $major_version -gt 24 || ($major_version == 24 && minor_version -ge 4) ]]; then
echo "Temporarily adding jammy repository for libwebkit2gtk-4.0-37, etc."
remove_temp_repo=1
add_temp_repo "jammy" "https://archive.ubuntu.com/ubuntu" "jammy" "/usr/share/keyrings/ubuntu-archive-keyring.gpg"
fi
elif [[ "$ID" == "debian" ]]; then
local major_version="${VERSION_ID%%.*}"
if [[ $major_version -ge 13 || -z $major_version ]]; then
echo "Temporarily adding bookworm repository for libwebkit2gtk-4.0-37, etc."
remove_temp_repo=1
add_temp_repo "bookworm" "https://deb.debian.org/debian" "bookworm" "/usr/share/keyrings/debian-archive-keyring.gpg"
fi
if add_temp_repo; then
trap 'execute sudo rm -f "$TEMP_REPO_FILE"' EXIT
else
err "Failed to add temporary repository"
return 1
fi
"${PKG_UPDATE[@]}" || { err "Package update failed!"; return 1; }
# Copy the DEB to a temporary file so _apt can read it
debug "Creating temporary deb file owned by _apt"
@@ -1013,16 +998,17 @@ install_mc_deb() {
--reinstall \
"$temp_deb"; then
err "Local MC DEB installation failed"
((remove_temp_repo)) && { echo "Removing temporary repo"; execute sudo rm -f "$TEMP_REPO_FILE"; }
if ask_ok "Remove source DEB and retry"; then
execute sudo rm -f "$MC_DEB" "$temp_deb"
exec "$SCRIPT_PATH" "$@" "--no-update"
fi
fi
# Cleanup temporary repository and temporary DEB file
((remove_temp_repo)) && { echo "Removing temporary repo"; execute sudo rm -f "$TEMP_REPO_FILE"; }
# 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"
return 0
}
# @description Installs MC via RPM package
@@ -1111,7 +1097,6 @@ install_mc_arch() {
# @description Copy the RPM to createrepo-webroot and run createrepo as the createrepo-user
run_createrepo() {
debug "${FUNCNAME[0]}()"
local -a cr_cmd
install_package createrepo_c
@@ -1136,15 +1121,10 @@ run_createrepo() {
fi
# Run createrepo
cr_cmd=(sudo -u "$CREATEREPO_USER" createrepo -q "$CREATEREPO_WEBROOT")
[[ -d $CREATEREPO_WEBROOT/repodata ]] && cr_cmd+=(--update)
if ! execute "${cr_cmd[@]}"; then
cr_cmd=(sudo createrepo -q "$CREATEREPO_WEBROOT")
[[ -d $CREATEREPO_WEBROOT/repodata ]] && cr_cmd+=(--update)
if ! (execute "${cr_cmd[@]}" ||
execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"); then
local -a cr_opts=(-q "$CREATEREPO_WEBROOT")
# [[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_opts+=(--update) # TODO temporarily disabled for legacy createrepo
if ! execute sudo -u "$CREATEREPO_USER" createrepo "${cr_opts[@]}"; then
if ! (execute sudo createrepo "${cr_opts[@]}" && execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"); then
err "createrepo failed"
return 1
fi
@@ -1207,7 +1187,12 @@ restore_license() {
for f in "$MJR_FILE" "$newest"; do
if [[ -f $f ]]; then
execute "mediacenter$MC_MVERSION" "/RestoreFromFile" "$f"
if execute "mediacenter$MC_MVERSION" "/RestoreFromFile" "$f"; then
echo "Restored license from $f"
return 0
else
err "Failed to restore license from $f"
fi
fi
done
fi
@@ -1534,7 +1519,7 @@ service_jriver-createrepo() {
[Service]
$USER_STRING
ExecStart=$SCRIPT_DIR/installJRMC --outputdir=$OUTPUT_DIR --createrepo=$CREATEREPO_TARGET \
--createrepo-webroot=$CREATEREPO_WEBROOT --createrepo-user=$CREATEREPO_USER --yes --no-update
--createrepo-webroot=$CREATEREPO_WEBROOT --createrepo-user=$CREATEREPO_USER --mcrepo=$MC_REPO --yes --no-update
[Install]
WantedBy=multi-user.target
@@ -1559,17 +1544,15 @@ service_jriver-createrepo() {
# @description Detects if MC is installed on btrfs and disables CoW
disable_btrfs_cow() {
debug "${FUNCNAME[0]}()"
local dir
local mc_user_path="$HOME/.jriver"
[[ -d "$mc_user_path" ]] || execute mkdir -p "$mc_user_path"
for dir in "$MC_ROOT" "$mc_user_path"; do
[[ -d $mc_user_path ]] || execute mkdir -p "$mc_user_path"
if [[ $(stat -f -c %T "$dir") == "btrfs" ]] &&
! lsattr -d "$dir" | cut -f1 -d" " | grep -q C &&
execute sudo chattr +C "$dir"; then
echo "Disabled btrfs CoW for $dir directory"
# Disable btrfs CoW
if [[ $(stat -f -c %T "$mc_user_path") == "btrfs" ]]; then
if execute chattr -R +C "$mc_user_path"; then
echo "Disabled btrfs CoW for $mc_user_path"
fi
fi
done
}
# @description Completely uninstalls MC, services, and firewall rules
@@ -1577,6 +1560,11 @@ uninstall() {
debug "${FUNCNAME[0]}()"
local service type unit f
if ! ask_ok "Do you really want to uninstall JRiver Media Center?"; then
echo "Uninstall cancelled"
return 1
fi
echo "Stopping and removing all Media Center services"
for service in $(compgen -A "function" "service"); do
service="${service##service_}"
@@ -1595,13 +1583,15 @@ uninstall() {
done
done
echo "Removing MC repositories"
execute sudo rm -rf \
"/etc/yum.repos.d/jriver.repo" \
/etc/apt/sources.list.d/{jriver,mediacenter}*.{list,sources} # also remove legacy repo files
# Remove the repository files
for file in "/etc/yum.repos.d/jriver.repo" /etc/apt/sources.list.d/{jriver,mediacenter}*.{list,sources}; do
if [[ -e $file ]]; then
echo "Removing repository file: $file"
execute sudo rm -f "$file"
fi
done
[[ $ID == "suse" ]] &&
execute sudo zypper --non-interactive removerepo jriver
[[ $ID == "suse" ]] && execute sudo zypper --non-interactive removerepo jriver
echo "Removing firewall rules"
for service in jriver-mediacenter jriver-xvnc jriver-x11vnc; do
@@ -1616,18 +1606,21 @@ uninstall() {
fi
done
echo "Uninstalling JRiver Media Center package"
echo "Uninstalling the JRiver Media Center package"
if "${PKG_REMOVE[@]}" "${MC_PKG%%=*}"; then # remove version specifier
echo "JRiver Media Center has been completely uninstalled"
echo "Successfully uninstalled the ${MC_PKG%%=*} package"
elif [[ $? -eq 100 ]]; then
err "JRiver Media Center package '${MC_PKG%%=*}' is not present and was not uninstalled"
else
err "Could not remove Media Center package"
fi
echo "Uninstalling JRiver Media Center GPG key"
# Remove the JRiver GPG keyfile
local keyfile="/usr/share/keyrings/jriver-com-archive-keyring.gpg"
[[ -f $keyfile ]] && execute sudo rm -f "$keyfile"
if [[ -f $keyfile ]]; then
echo "Removing the JRiver Media Center GPG key"
execute sudo rm -f "$keyfile"
fi
if [[ -f $SCRIPT_DIR/.uninstall ]]; then
echo "Removing files from .uninstall log"
@@ -1637,9 +1630,28 @@ uninstall() {
mv "$SCRIPT_DIR/.uninstall" "$SCRIPT_DIR/.uninstall.bk"
fi
echo "To remove installJRMC output: rm -rf $OUTPUT_DIR"
if [[ -d $OUTPUT_DIR ]]; then
if ask_ok "Remove installJRMC output directory $OUTPUT_DIR?"; then
execute sudo rm -rf "$OUTPUT_DIR"
fi
fi
if [[ -d $MC_ROOT ]]; then
if ask_ok "Remove MC installation directory $MC_ROOT?"; then
execute sudo rm -rf "$MC_ROOT"
fi
fi
if [[ -d $HOME/.jriver ]]; then
if ask_ok "Backup and reset your MC library?"; then
execute mv "$HOME/.jriver" "$HOME/.jriver.bk"
echo "Your MC library has been backed up to $HOME/.jriver.bk and reset"
echo "To restore your MC library backup: mv $HOME/.jriver.bk $HOME/.jriver"
return
fi
echo "To backup and reset your MC library: mv $HOME/.jriver $HOME/.jriver.bk"
echo "To remove your MC library: rm -rf $HOME/.jriver"
return 0
fi
}
# @description Checks for installJRMC update and re-executes, if necessary
@@ -1728,9 +1740,10 @@ update() {
# @description installJRMC main function
main() {
debug "${FUNCNAME[0]}()" "$@"
debug "${FUNCNAME[0]}()" "$@" # prints function name and arguments
echo "Starting installJRMC $SCRIPT_VERSION"
if ((DEBUG)); then
echo "Debugging on"
else
@@ -1740,13 +1753,13 @@ main() {
# Parse input, set default/host variables, and MC version
init "$@"
if ((UNINSTALL_SWITCH)); then
if ask_ok "Do you really want to uninstall JRiver Media Center?"; then
uninstall
else
echo "Uninstall canceled"
fi
exit
((UNINSTALL_SWITCH)) && uninstall
# Exit now if only --uninstall is passed
if ! (( BUILD_SWITCH || CREATEREPO_SWITCH || REPO_INSTALL_SWITCH || LOCAL_INSTALL_SWITCH ||
CONTAINER_INSTALL_SWITCH || SNAP_INSTALL_SWITCH || APPIMAGE_INSTALL_SWITCH )) &&
[[ ${#SERVICES[@]} -eq 0 && ${#CONTAINERS[@]} -eq 0 ]]; then
exit 0
fi
install_external_repos
@@ -1755,6 +1768,7 @@ main() {
echo "Installing JRiver Media Center from remote repository"
if install_mc_repo; then
echo "JRiver Media Center installed successfully from remote repository"
install_mesa_freeworld
link_ssl_certs
restore_license
open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp"
@@ -1776,12 +1790,14 @@ main() {
fi
if ((LOCAL_INSTALL_SWITCH)); then
echo "Installing JRiver Media Center from local package"
if PKG_INSTALL_LOCAL "$@"; then
echo "JRiver Media Center installed successfully from local package"
else
err "JRiver Media Center local package installation failed"
return 1
fi
install_mesa_freeworld
link_ssl_certs
restore_license
open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp"
@@ -1877,6 +1893,51 @@ create_mc_apt_container() {
sudo buildah run "$CNT" -- sh -c "$cmd" || { err "$cmd failed"; return 1; }
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
# Reset and reparse in parse_input() with getopt