From 64e86ecddf0712459a87ea23537b0d2909b3c7df Mon Sep 17 00:00:00 2001 From: bryan Date: Thu, 1 Apr 2021 10:56:51 -0400 Subject: [PATCH 01/19] Hide PackageInstaller icon --- .gitignore | 0 Containerfile | 0 installJRMC | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) mode change 100755 => 100644 .gitignore mode change 100755 => 100644 Containerfile diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/Containerfile b/Containerfile old mode 100755 new mode 100644 diff --git a/installJRMC b/installJRMC index 9f204ef..6549b92 100755 --- a/installJRMC +++ b/installJRMC @@ -18,7 +18,7 @@ shopt -s extglob ####################################### installJRMC() { - _scriptversion="0.9" + _scriptversion="0.9.1" _boardurl="https://yabb.jriver.com/interact/index.php/board,67.0.html" _outputdir="$_basedir/output" _createrepo_webroot="/srv/jriver" @@ -832,6 +832,7 @@ dpkg -x %{S:0} %{buildroot} %{_bindir}/mediacenter$_mversion %{_libdir}/jriver %{_datadir} +%exclude %{_datadir}/applications/media_center_packageinstaller_$_mversion.desktop /etc/security/limits.d/* EOF" From 09b914d11fe77bcf7c4aa6b01f3d365d3edd6837 Mon Sep 17 00:00:00 2001 From: bryan Date: Sat, 24 Apr 2021 12:27:25 -0400 Subject: [PATCH 02/19] Add back lame as dependency --- installJRMC | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/installJRMC b/installJRMC index 6549b92..c3db04c 100755 --- a/installJRMC +++ b/installJRMC @@ -12,13 +12,13 @@ shopt -s extglob # # installJRMC can be run directly or sourced as a function (by sourcing this file) # Arguments: -# see _printHelpAndExit() and/or check getopt's in _parseInput() for available options +# see _printHelpAndExit() and _parseInput() for available options # Returns: # 0 if critical functions complete successfully ####################################### installJRMC() { - _scriptversion="0.9.1" + _scriptversion="0.9.2" _boardurl="https://yabb.jriver.com/interact/index.php/board,67.0.html" _outputdir="$_basedir/output" _createrepo_webroot="/srv/jriver" @@ -806,6 +806,7 @@ Requires: nspr >= 4.12 Requires: ca-certificates Requires: python3 Recommends: vorbis-tools >= 1.4.0 +Recommends: lame >= 3.0 Provides: mediacenter$_mversion @@ -890,7 +891,7 @@ EOF" fi # Copy built rpms to webroot - if ! _cr_cp_cmd "$_rpmfile" "$_createrepo_webroot"; then + if ! _cr_cp_cmd -f "$_rpmfile" "$_createrepo_webroot"; then err "Could not copy the RPM to the createrepo-webroot path" err "Make sure that the createrepo-webroot path is writeable by createrepo-user" return 1 From 51e5da479553a8bc3469aa7d73a533346f8501f9 Mon Sep 17 00:00:00 2001 From: bryan Date: Thu, 6 May 2021 12:35:41 -0400 Subject: [PATCH 03/19] Fix formatting and Debian install --- installJRMC | 422 +++++++++++++++++++++++++--------------------------- 1 file changed, 206 insertions(+), 216 deletions(-) diff --git a/installJRMC b/installJRMC index c3db04c..9c56c41 100755 --- a/installJRMC +++ b/installJRMC @@ -18,7 +18,7 @@ shopt -s extglob ####################################### installJRMC() { - _scriptversion="0.9.2" + _scriptversion="0.9.3" _boardurl="https://yabb.jriver.com/interact/index.php/board,67.0.html" _outputdir="$_basedir/output" _createrepo_webroot="/srv/jriver" @@ -26,77 +26,75 @@ installJRMC() { _available_services=("jriver-createrepo" "jriver-x11vnc" "jriver-mediaserver" "jriver-mediacenter" "jriver-xvnc-mediacenter") #_available_containers=("mediacenter-xvnc" "createrepo") - _printHelpAndExit() { - debug "Running: ${FUNCNAME[0]}" - cat <<-'EOF' -USAGE: - installJRMC [[OPTION] [VALUE]]... + cat <<- 'EOF' + USAGE: + installJRMC [[OPTION] [VALUE]]... -OPTIONS - --install-repo - Install JRiver Media Center from repository using package manager (Default) - DEB-based OSes: Official package repository - RPM-based OSes: BryanC unofficial repository - --install-rpm - (RPM-based OSes only) Build RPM from source DEB and install it - --rpmbuild - Build RPM from source DEB - --outputdir PATH - Generate rpmbuild output in this directory (Default: $PWD/outputdir) - --mcversion VERSION - Build or install a specific version (Default: install the latest version) - --restorefile RESTOREFILE - Restore file location for registration (Default: skip registration) - --betapass PASSWORD - Enter beta team password for access to beta builds - --service-user USER - Install systemd services and containers for USER - --service, -s SERVICE - See SERVICES section below for a list of possible services to install - --container, -c CONTAINER (TODO: Under construction) - See CONTAINERS section below for a list of possible services to install - --createrepo - Build rpm, copy to webroot, and run createrepo - --createrepo-webroot PATH - The webroot directory to install the repo (Default: /srv/jriver/) - --createrepo-user USER - The web server user (Default: current user) - --version, -v - Print this script version and exit - --debug, -d - Print debug output - --help, -h - Print help dialog and exit - --uninstall, -u - Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files) + OPTIONS + --install-repo + Install JRiver Media Center from repository using package manager (Default) + DEB-based OSes: Official package repository + RPM-based OSes: BryanC unofficial repository + --install-rpm + (RPM-based OSes only) Build RPM from source DEB and install it + --rpmbuild + Build RPM from source DEB + --outputdir PATH + Generate rpmbuild output in this directory (Default: $PWD/outputdir) + --mcversion VERSION + Build or install a specific version (Default: install the latest version) + --restorefile RESTOREFILE + Restore file location for registration (Default: skip registration) + --betapass PASSWORD + Enter beta team password for access to beta builds + --service-user USER + Install systemd services and containers for USER + --service, -s SERVICE + See SERVICES section below for a list of possible services to install + --container, -c CONTAINER (TODO: Under construction) + See CONTAINERS section below for a list of possible services to install + --createrepo + Build rpm, copy to webroot, and run createrepo + --createrepo-webroot PATH + The webroot directory to install the repo (Default: /srv/jriver/) + --createrepo-user USER + The web server user (Default: current user) + --version, -v + Print this script version and exit + --debug, -d + Print debug output + --help, -h + Print help dialog and exit + --uninstall, -u + Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files) - SERVICES - jriver-mediaserver - Enable and start a mediaserver systemd service (requires an existing X server) - jriver-mediacenter - Enable and start a mediacenter systemd service (requires an existing X server) - jriver-x11vnc - Enable and start x11vnc for the local desktop (requires an existing X server) - Usually combined with jriver-mediaserver or jriver-mediacenter services - --vncpass and --display are also valid options (see below) - jriver-xvnc-mediacenter - 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 use no password - --display DISPLAY - Display to start x11vnc/Xvnc (Default: The current display (x11vnc) or the - current display incremented by 1 (Xvnc)) - jriver-createrepo - Install hourly service to build latest MC RPM and run createrepo + SERVICES + jriver-mediaserver + Enable and start a mediaserver systemd service (requires an existing X server) + jriver-mediacenter + Enable and start a mediacenter systemd service (requires an existing X server) + jriver-x11vnc + Enable and start x11vnc for the local desktop (requires an existing X server) + Usually combined with jriver-mediaserver or jriver-mediacenter services + --vncpass and --display are also valid options (see below) + jriver-xvnc-mediacenter + 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 use no password + --display DISPLAY + Display to start x11vnc/Xvnc (Default: The current display (x11vnc) or the + current display incremented by 1 (Xvnc)) + jriver-createrepo + Install hourly service to build latest MC RPM and run createrepo - CONTAINERS (TODO: Under construction) - mediacenter-xvnc - createrepo -EOF + CONTAINERS (TODO: Under construction) + mediacenter-xvnc + createrepo + EOF # Exit using passed exit code [[ -z $1 ]] && exit 0 || exit "$1" @@ -104,7 +102,6 @@ EOF _parseInput() { - debug "Running: ${FUNCNAME[0]}" # set default behavior @@ -190,7 +187,6 @@ EOF fi } - err() { echo "Error: $*" >&2; } debug() { [[ -n $_debug ]] && echo "Debug: $*"; } @@ -201,7 +197,6 @@ EOF # _exec_user ####################################### _ifSudo() { - if [[ "$_exec_user" != "root" ]]; then sudo "$@" else @@ -215,7 +210,6 @@ EOF # Used in: _buildCommands() ####################################### _getOS() { - debug "Running: ${FUNCNAME[0]}" if [[ -e "/etc/os-release" ]]; then @@ -316,7 +310,6 @@ EOF _createrepo_cmd(){ createrepo -q "$@"; } fi fi - } @@ -599,19 +592,21 @@ EOF # Add repository files _addRepo() { + debug "Running: ${FUNCNAME[0]}" # Add repositories to OS-specific package managers if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - _bash_cmd 'cat <<-EOF > /etc/yum.repos.d/jriver.repo -[jriver] -name=JRiver Media Center repo by BryanC -baseurl=https://repos.bryanroessler.com/jriver -gpgcheck=0 -EOF' + _bash_cmd 'cat <<- EOF > /etc/yum.repos.d/jriver.repo + [jriver] + name=JRiver Media Center repo by BryanC + baseurl=https://repos.bryanroessler.com/jriver + gpgcheck=0 + EOF' elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then + _installPackage wget wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | _ifSudo apt-key add - > /dev/null 2>&1 - _bash_cmd 'cat <<-EOF > /etc/apt/sources.list.d/jriver.list -deb [arch=amd64,i386,armhf] http://dist.jriver.com/latest/mediacenter/ jessie main -EOF' + _bash_cmd 'cat <<- EOF > /etc/apt/sources.list.d/jriver.list + deb [arch=amd64,i386,armhf] http://dist.jriver.com/latest/mediacenter/ buster main + EOF' fi } _addRepo @@ -772,77 +767,77 @@ EOF' fi # Create spec file - bash -c "cat < $_outputdir/SPECS/mediacenter.spec -Name: MediaCenter -Version: $_mcversion -Release: 1 -Summary: JRiver Media Center -Group: Applications/Media -Source0: http://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb -$_build_requires -BuildArch: x86_64 -%define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm + cat <<- EOF > "$_outputdir/SPECS/mediacenter.spec" + Name: MediaCenter + Version: $_mcversion + Release: 1 + Summary: JRiver Media Center + Group: Applications/Media + Source0: http://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb + $_build_requires + BuildArch: x86_64 + %define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm -AutoReq: 0 -Requires: glibc >= 2.19 -Requires: alsa-lib >= 1.0.28 -Requires: libuuid >= 2.25 -Requires: libX11 >= 1.6 -Requires: libX11-common >= 1.6 -Requires: libXext >= 1.3 -Requires: libxcb >= 1.1 -Requires: libXdmcp >= 1.1 -Requires: libstdc++ >= 4.9 -Requires: gtk3 >= 3.14 -Requires: mesa-libGL -Requires: libglvnd-glx -Requires: pango >= 1.36 -$_requires -Requires: libXScrnSaver -Requires: xdg-utils -Requires: libgomp >= 4.9 -Requires: nss >= 3.26 -Requires: nspr >= 4.12 -Requires: ca-certificates -Requires: python3 -Recommends: vorbis-tools >= 1.4.0 -Recommends: lame >= 3.0 + AutoReq: 0 + Requires: glibc >= 2.19 + Requires: alsa-lib >= 1.0.28 + Requires: libuuid >= 2.25 + Requires: libX11 >= 1.6 + Requires: libX11-common >= 1.6 + Requires: libXext >= 1.3 + Requires: libxcb >= 1.1 + Requires: libXdmcp >= 1.1 + Requires: libstdc++ >= 4.9 + Requires: gtk3 >= 3.14 + Requires: mesa-libGL + Requires: libglvnd-glx + Requires: pango >= 1.36 + $_requires + Requires: libXScrnSaver + Requires: xdg-utils + Requires: libgomp >= 4.9 + Requires: nss >= 3.26 + Requires: nspr >= 4.12 + Requires: ca-certificates + Requires: python3 + Recommends: vorbis-tools >= 1.4.0 + Recommends: lame >= 3.0 -Provides: mediacenter$_mversion + Provides: mediacenter$_mversion -License: Copyright 1998-2020, JRiver, Inc. All rights reserved. Protected by U.S. patents #7076468 and #7062468 -URL: http://www.jriver.com/ + License: Copyright 1998-2020, 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.*$ + %define __provides_exclude_from ^%{_libdir}/jriver/.*/.*\\.so.*$ -%description -Media Center is more than a world class player. + %description + Media Center is more than a world class player. -%global __os_install_post %{nil} -%prep + %global __os_install_post %{nil} + %prep -%build + %build -%install -dpkg -x %{S:0} %{buildroot} + %install + dpkg -x %{S:0} %{buildroot} -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig + %post -p /sbin/ldconfig + %postun -p /sbin/ldconfig -%files -%{_bindir}/mediacenter$_mversion -%{_libdir}/jriver -%{_datadir} -%exclude %{_datadir}/applications/media_center_packageinstaller_$_mversion.desktop -/etc/security/limits.d/* -EOF" + %files + %{_bindir}/mediacenter$_mversion + %{_libdir}/jriver + %{_datadir} + %exclude %{_datadir}/applications/media_center_packageinstaller_$_mversion.desktop + /etc/security/limits.d/* + EOF declare -g _mcrpm="$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm" # skip rebuilding the rpm if it already exists if [[ -f "$_mcrpm" ]]; then echo "$_mcrpm already exists. Skipping build step..." - return 0 # this is fine + return 0 else # Run rpmbuild echo "Building version $_mcversion, please wait..." @@ -914,7 +909,6 @@ EOF" # 0 if symlinking is unecessary or successful, 1 if not ####################################### _symlinkCerts() { - debug "Running: ${FUNCNAME[0]}" if [[ ! -f /etc/ssl/certs/ca-certificates.crt && \ @@ -937,7 +931,6 @@ EOF" # 0 if license restored successfully or skipped, 1 if unsuccessful ####################################### _restoreLicense() { - debug "Running: ${FUNCNAME[0]}" local _mjr @@ -972,7 +965,6 @@ EOF" # 0 if ports opened sucessfully, 1 if not ####################################### _openFirewall() { - debug "Running: ${FUNCNAME[0]}" "$@" # Create OS-specific port rules based on argument (service) name @@ -1006,12 +998,12 @@ EOF" # Debian ufw package state is broken on fresh installations [[ ! -x $(command -v ufw) ]] && _installPackage ufw if [[ ! -f "/etc/ufw/applications.d/$1" ]]; then - _bash_cmd "cat <<-EOF > /etc/ufw/applications.d/$1 -[$1] -title=$1 -description=$1 installed by installJRMC -ports=$_u_ports -EOF" + _bash_cmd "cat <<- EOF > /etc/ufw/applications.d/$1 + [$1] + title=$1 + description=$1 installed by installJRMC + ports=$_u_ports + EOF" fi _firewall_cmd app update "$1" _firewall_cmd allow "$1" > /dev/null 2>&1 @@ -1034,7 +1026,6 @@ EOF" # 0 if password created sucessfully, 1 if not ####################################### _setX11VNCPass() { - debug "Running: ${FUNCNAME[0]}" _vncpassfile="$HOME/.vnc/jrmc_passwd" @@ -1068,7 +1059,6 @@ EOF" # 0 if password created sucessfully, 1 if not ####################################### _setVNCPass() { - debug "Running: ${FUNCNAME[0]}" _vncpassfile="$HOME/.vnc/jrmc_passwd" @@ -1105,6 +1095,7 @@ EOF" # _next_displaynum ####################################### _setDisplay() { + debug "Running: ${FUNCNAME[0]}" # Check _display, else DISPLAY, else set to :0 by default if [[ -n $_display ]]; then @@ -1138,6 +1129,7 @@ EOF" # _user_specifier ####################################### _servicePrep() { + debug "Running: ${FUNCNAME[0]}" if [[ "$_service_user" == "root" ]]; then _service_fname="/usr/lib/systemd/system/${1}.service" @@ -1167,28 +1159,27 @@ EOF" # XAUTHORITY ####################################### _service_jriver-mediacenter() { - debug "Running: ${FUNCNAME[0]}" - _bash_cmd "cat <<-EOF > $_service_fname -[Unit] -Description=JRiver Media Center $_mversion -After=graphical.target + _bash_cmd "cat <<- EOF > $_service_fname + [Unit] + Description=JRiver Media Center $_mversion + After=graphical.target -[Service] -$_user_specifier -Type=simple -Environment=DISPLAY=$_display -Environment=XAUTHORITY=$XAUTHORITY -ExecStart=/usr/bin/mediacenter$_mversion $* -Restart=always -RestartSec=10 -KillSignal=SIGHUP -TimeoutStopSec=30 + [Service] + $_user_specifier + Type=simple + Environment=DISPLAY=$_display + Environment=XAUTHORITY=$XAUTHORITY + ExecStart=/usr/bin/mediacenter$_mversion $* + Restart=always + RestartSec=10 + KillSignal=SIGHUP + TimeoutStopSec=30 -[Install] -WantedBy=graphical.target -EOF" + [Install] + WantedBy=graphical.target + EOF" _systemctl_reload && \ _systemctl_start "$_service_name" && \ _systemctl_enable "$_service_name" && \ @@ -1200,7 +1191,6 @@ EOF" # Starts and enables (at startup) a JRiver Media Server service ####################################### _service_jriver-mediaserver() { - debug "Running: ${FUNCNAME[0]}" _service_jriver-mediacenter "/MediaServer" @@ -1210,8 +1200,7 @@ EOF" ####################################### # Starts and enables (at startup) JRiver Media Center in a new Xvnc session ####################################### - _service_jriver-xvnc() { - + _service_jriver-xvnc-mediacenter() { debug "Running: ${FUNCNAME[0]}" _installPackage tigervnc-server @@ -1226,22 +1215,23 @@ EOF" _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -rfbauth $HOME/.vnc/jrmc_passwd -autokill -xstartup /usr/bin/mediacenter$_mversion" fi - _bash_cmd "cat <<-EOF > $_service_fname -[Unit] -Description=Remote desktop service (VNC) -After=syslog.target network.target + _bash_cmd "cat <<- EOF > $_service_fname + [Unit] + Description=Remote desktop service (VNC) + After=syslog.target network.target -[Service] -Type=simple -$_user_specifier -ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill $_next_display > /dev/null 2>&1 || :' -ExecStart=$_exec_start_cmd -ExecStop=/usr/bin/vncserver -kill $_next_display -Restart=always + [Service] + Type=simple + $_user_specifier + ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill $_next_display > /dev/null 2>&1 || :' + ExecStart=$_exec_start_cmd + ExecStop=/usr/bin/vncserver -kill $_next_display + Restart=always + + [Install] + WantedBy=multi-user.target + EOF" -[Install] -WantedBy=multi-user.target -EOF" _systemctl_reload && \ _systemctl_start "$_service_name" && \ _systemctl_enable "$_service_name" && \ @@ -1255,7 +1245,6 @@ EOF" # Starts and enables (at startup) JRiver Media Server and x11vnc sharing the local desktop ####################################### _service_jriver-x11vnc() { - debug "Running: ${FUNCNAME[0]}" _installPackage x11vnc @@ -1282,21 +1271,22 @@ EOF" fi _bash_cmd "cat <<-EOF > $_service_fname -[Unit] -Description=x11vnc -After=multi.service + [Unit] + Description=x11vnc + After=multi.service -[Service] -$_user_specifier -Type=forking -Environment=DISPLAY=$_display -ExecStart=$_exec_start_cmd -Restart=always -RestartSec=10 + [Service] + $_user_specifier + Type=forking + Environment=DISPLAY=$_display + ExecStart=$_exec_start_cmd + Restart=always + RestartSec=10 + + [Install] + WantedBy=multi-user.target + EOF" -[Install] -WantedBy=multi-user.target -EOF" _systemctl_reload && \ _systemctl_start "$_service_name" && \ _systemctl_enable "$_service_name" && \ @@ -1310,31 +1300,32 @@ EOF" # Center RPM from the source DEB and create/update an RPM repository ####################################### _service_jriver-createrepo() { - debug "Running: ${FUNCNAME[0]}" _bash_cmd "cat <<-EOF > $_service_fname -[Unit] -Description=Builds JRiver Media Center RPM file, moves it to the repo dir, and runs createrepo + [Unit] + Description=Builds JRiver Media Center RPM file, moves it to the repo dir, and runs createrepo -[Service] -$_user_specifier -ExecStart=$_basedir/installJRMC --outputdir $_outputdir --createrepo --createrepo-webroot $_createrepo_webroot --createrepo-user $_createrepo_user + [Service] + $_user_specifier + ExecStart=$_basedir/installJRMC --outputdir $_outputdir --createrepo --createrepo-webroot $_createrepo_webroot --createrepo-user $_createrepo_user + + [Install] + WantedBy=default.target + EOF" -[Install] -WantedBy=default.target -EOF" _bash_cmd "cat <<-EOF > $_timer_fname -[Unit] -Description=Run JRiver MC rpmbuild hourly + [Unit] + Description=Run JRiver MC rpmbuild hourly -[Timer] -OnCalendar=hourly -Persistent=true + [Timer] + OnCalendar=hourly + Persistent=true + + [Install] + WantedBy=timers.target + EOF" -[Install] -WantedBy=timers.target -EOF" _systemctl_reload && \ _systemctl_start "$_timer_name" && \ _systemctl_enable "$_timer_name" @@ -1363,7 +1354,6 @@ EOF" # Complete uninstall ####################################### _uninstall() { - debug "Running: ${FUNCNAME[0]}" read -r -p "Do you really want to uninstall JRiver Media Center? [y/N] " _response @@ -1410,7 +1400,7 @@ EOF" } - __main() { + _main() { # Parse input _parseInput "$@" @@ -1426,7 +1416,7 @@ EOF" # Install MC using package manager if [[ -n $_repoinstall ]]; then - _installPackage rpmfusion-free-release epel-release + [[ "$ID" =~ ^(fedora|centos)$ ]] && _installPackage rpmfusion-free-release epel-release _installMCFromRepo _symlinkCerts _restoreLicense @@ -1483,5 +1473,5 @@ EOF" if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then _basedir=$(dirname "$(readlink -f "$0")") installJRMC - __main "$@" + _main "$@" fi From 1fa5b7532302c83432d27b2d45b4147f7333a206 Mon Sep 17 00:00:00 2001 From: bryan Date: Thu, 6 May 2021 16:59:26 -0400 Subject: [PATCH 04/19] Add Linux Mint support --- installJRMC | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/installJRMC b/installJRMC index 9c56c41..060940e 100755 --- a/installJRMC +++ b/installJRMC @@ -18,7 +18,7 @@ shopt -s extglob ####################################### installJRMC() { - _scriptversion="0.9.3" + _scriptversion="0.9.4" _boardurl="https://yabb.jriver.com/interact/index.php/board,67.0.html" _outputdir="$_basedir/output" _createrepo_webroot="/srv/jriver" @@ -283,7 +283,7 @@ installJRMC() { _pkg_update(){ _ifSudo dnf makecache; } _pkg_query(){ _ifSudo rpm -q "$@"; } _firewall_cmd(){ _ifSudo firewall-cmd "$@"; } - elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _pkg_install(){ _ifSudo apt-get install -y -q0 "$@"; } _pkg_reinstall(){ _ifSudo apt-get reinstall -y -q0 "$@"; } _pkg_install_nogpg(){ _ifSudo apt-get install -y -q0 "$@"; } @@ -424,11 +424,11 @@ installJRMC() { unset _url_pkg - if [[ "$1" == "xorg-x11-utils" && "$ID" =~ ^(ubuntu|debian)$ ]]; then + if [[ "$1" == "xorg-x11-utils" && "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _pkg="x11-utils" - elif [[ "$1" == "rpm-build" && "$ID" =~ ^(ubuntu|debian)$ ]]; then + elif [[ "$1" == "rpm-build" && "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _pkg="rpm" - elif [[ "$1" == "createrepo_c" && "$ID" =~ ^(ubuntu|debian)$ ]]; then + elif [[ "$1" == "createrepo_c" && "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _pkg="createrepo" elif [[ "$1" == "rpmfusion-free-release" ]]; then if [[ "$ID" == "fedora" ]]; then @@ -444,7 +444,7 @@ installJRMC() { fi elif [[ "$1" == "epel-release" && "$ID" != "centos" ]]; then _pkg="" - elif [[ "$1" == "tigervnc-server" && "$ID" =~ ^(ubuntu|debian)$ ]]; then + elif [[ "$1" == "tigervnc-server" && "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _pkg="tigervnc-standalone-server" else _pkg="$1" @@ -601,7 +601,7 @@ installJRMC() { baseurl=https://repos.bryanroessler.com/jriver gpgcheck=0 EOF' - elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _installPackage wget wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | _ifSudo apt-key add - > /dev/null 2>&1 _bash_cmd 'cat <<- EOF > /etc/apt/sources.list.d/jriver.list @@ -632,7 +632,7 @@ installJRMC() { fi # Ubuntu/Debian incorporate the mversion into the package name -- more fun! - if [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then + if [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then if [[ -z $_mversion ]]; then # Try parsing the latest mversion from the repo if _mcpkg=$(apt-get install mediacenter?? -s -q0 | grep "selecting" | tail -1| awk '{print $3}'); then @@ -660,7 +660,7 @@ installJRMC() { else _installPackage "$_mcpkg-$_mcversion" > /dev/null 2>&1 fi - elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then if [[ -n $_debug ]]; then _installPackage "$_mcpkg=$_mcversion" else @@ -994,7 +994,7 @@ installJRMC() { _firewall_cmd --add-service "$1" --permanent > /dev/null 2>&1 _firewall_cmd --reload > /dev/null 2>&1 fi - elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then # Debian ufw package state is broken on fresh installations [[ ! -x $(command -v ufw) ]] && _installPackage ufw if [[ ! -f "/etc/ufw/applications.d/$1" ]]; then @@ -1390,7 +1390,7 @@ installJRMC() { echo "Uninstalling Media Center" if [[ "$ID" =~ ^(fedora|centos)$ ]]; then _pkg_remove MediaCenter - elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _pkg_remove "mediacenter$_mversion" fi From 49a4dea41686148aab2ae2d58679912a503746cc Mon Sep 17 00:00:00 2001 From: bryan Date: Sat, 8 May 2021 16:28:48 -0400 Subject: [PATCH 05/19] Standardize operators --- installJRMC | 86 +++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/installJRMC b/installJRMC index 060940e..70cb60b 100755 --- a/installJRMC +++ b/installJRMC @@ -18,7 +18,7 @@ shopt -s extglob ####################################### installJRMC() { - _scriptversion="0.9.4" + _scriptversion="0.9.5" _boardurl="https://yabb.jriver.com/interact/index.php/board,67.0.html" _outputdir="$_basedir/output" _createrepo_webroot="/srv/jriver" @@ -97,7 +97,7 @@ installJRMC() { EOF # Exit using passed exit code - [[ -z $1 ]] && exit 0 || exit "$1" + [[ ! -v 1 ]] && exit 0 || exit "$1" } @@ -105,7 +105,7 @@ installJRMC() { debug "Running: ${FUNCNAME[0]}" # set default behavior - if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" == "--debug" ]]; then + if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then _repoinstall="true" fi @@ -189,7 +189,7 @@ installJRMC() { err() { echo "Error: $*" >&2; } - debug() { [[ -n $_debug ]] && echo "Debug: $*"; } + debug() { [[ -v _debug ]] && echo "Debug: $*"; } ####################################### # Prepend this to any command that you wish to execute with sudo @@ -220,7 +220,7 @@ installJRMC() { _printHelpAndExit 1 fi - [[ -n $_debug ]] && echo "Platform: $ID $VERSION_ID" + debug "Platform: $ID $VERSION_ID" } @@ -323,8 +323,8 @@ installJRMC() { ####################################### _setUser() { - [[ -z $_service_user ]] && _service_user="$_exec_user" - [[ -z $_createrepo_user ]] && _createrepo_user="$_exec_user" + [[ ! -v _service_user ]] && _service_user="$_exec_user" + [[ ! -v _createrepo_user ]] && _createrepo_user="$_exec_user" } @@ -370,8 +370,8 @@ installJRMC() { _packageQuirks "$_pkg" # Insert the package name to test if already installed if [[ "$_pkg" != "" ]]; then - if [[ -n $_noquery ]] || ! _pkg_query "$_pkg" > /dev/null 2>&1; then - if [[ -n $_url_pkg ]]; then + if [[ -v _noquery ]] || ! _pkg_query "$_pkg" > /dev/null 2>&1; then + if [[ -v _url_pkg ]]; then _url_pkg_array+=("$_url_pkg") else _pkg_array+=("$_pkg") @@ -383,7 +383,7 @@ installJRMC() { # Install from package name (with gpg check) if [[ ${#_pkg_array[@]} -ge 1 ]]; then echo "Installing:" "${_pkg_array[@]}" - if [[ -n $_debug ]]; then + if [[ -v _debug ]]; then if ! _pkg_install "${_pkg_array[@]}"; then err "Failed to install package. Attempting to continue..." return 1 @@ -397,7 +397,7 @@ installJRMC() { # Install from package url (without gpg check) if [[ ${#_url_pkg_array[@]} -ge 1 ]]; then echo "Installing:" "${_url_pkg_array[@]}" - if [[ -n $_debug ]]; then + if [[ -v _debug ]]; then if ! _pkg_install_nogpg "${_url_pkg_array[@]}"; then err "Failed to install package. Attempting to continue..." return 1 @@ -465,7 +465,7 @@ installJRMC() { debug "Running: ${FUNCNAME[0]}" - if [[ -z "$_mcversion" ]]; then + if [[ ! -v _mcversion ]]; then _installPackage wget @@ -519,7 +519,6 @@ installJRMC() { # _installJRMC should run sucessfully even without running _sanityChecks() ####################################### _sanityChecks() { - debug "Running: ${FUNCNAME[0]}" # Check for bad service name @@ -537,12 +536,11 @@ installJRMC() { _checkMCInstalled() { - debug "Running: ${FUNCNAME[0]}" for _service in "${_services[@]}"; do if [[ "$_service" =~ ^(jriver-mediacenter|jriver-mediaserver|jriver-xvnc-mediacenter|jriver-x11vnc)$ ]] \ - && [[ -z $_repoinstall && -z $_rpminstall ]] \ + && [[ ! -v _repoinstall && ! -v _rpminstall ]] \ && [[ ! -x $(command -v "mediacenter$_mversion") ]]; then err "You are attempting to install a service that depends on JRiver Media Center" err "without installing JRiver Media Center" @@ -554,10 +552,9 @@ installJRMC() { _checkUser() { - debug "Running: ${FUNCNAME[0]}" - if [[ "$_exec_user" == "root" && -z "$_service_user" && "${_services[*]}" ]]; then + if [[ "$_exec_user" == "root" && ! -v _service_user && "${_services[*]}" ]]; then err "Attempting to install services as the root user" err "This is not recommended and we are exiting now to prevent permission hell" err "You can override this safety check by manually specifying --user root" @@ -583,10 +580,12 @@ installJRMC() { # 0 if JRiver Media Center installed sucessfully ####################################### _installMCFromRepo() { - debug "Running: ${FUNCNAME[0]}" echo "Installing JRiver Media Center from repo..." + [[ ! -v _debug ]] && \ + echo "This may take a few minutes"; \ + echo "Use --debug for verbose output" local _mcpkg @@ -612,14 +611,14 @@ installJRMC() { _addRepo # Update package list - [[ -n $_debug ]] && echo "Updating package list" + debug "Updating package list" if ! _pkg_update > /dev/null 2>&1; then err "Package update failed!" exit 1 fi # If user specifies a version, use that - if [[ -n $_mcversion ]]; then + if [[ -v _mcversion ]]; then _setVersion local _specific_version="true" fi @@ -633,7 +632,7 @@ installJRMC() { # Ubuntu/Debian incorporate the mversion into the package name -- more fun! if [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - if [[ -z $_mversion ]]; then + if [[ ! -v _mversion ]]; then # Try parsing the latest mversion from the repo if _mcpkg=$(apt-get install mediacenter?? -s -q0 | grep "selecting" | tail -1| awk '{print $3}'); then _mcpkg="${_mcpkg%\'}" @@ -653,22 +652,22 @@ installJRMC() { fi fi - if [[ -n $_specific_version ]]; then + if [[ -v _specific_version ]]; then if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - if [[ -n $_debug ]]; then + if [[ -v _debug ]]; then _installPackage "$_mcpkg-$_mcversion" else _installPackage "$_mcpkg-$_mcversion" > /dev/null 2>&1 fi elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - if [[ -n $_debug ]]; then + if [[ -v _debug ]]; then _installPackage "$_mcpkg=$_mcversion" else _installPackage "$_mcpkg=$_mcversion" > /dev/null 2>&1 fi fi else - if [[ -n $_debug ]]; then + if [[ -v _debug ]]; then _installPackage "$_mcpkg" else _installPackage "$_mcpkg" > /dev/null 2>&1 @@ -693,7 +692,6 @@ installJRMC() { # 0 if DEB file downloaded successfully, 1 if failed ####################################### _acquireDeb() { - debug "Running: ${FUNCNAME[0]}" local _debfilename="$_outputdir/SOURCES/MediaCenter-${_mcversion}-amd64.deb" @@ -705,7 +703,7 @@ installJRMC() { if [[ -f "$_debfilename" ]]; then echo "Using local DEB file: $_debfilename" # Else check beta repo - elif [[ -n $_betapass ]]; then + elif [[ -v _betapass ]]; then if wget -q -O "$_debfilename" \ "https://files.jriver.com/mediacenter/channels/v${_mversion}/beta/${_betapass}/MediaCenter-${_mcversion}-amd64.deb"; then true @@ -744,7 +742,6 @@ installJRMC() { # 0 if rpmbuild is successful, 1 if not ####################################### _buildRPM() { - debug "Running: ${FUNCNAME[0]}" # install build dependencies @@ -761,7 +758,7 @@ installJRMC() { local _build_requires='' fi - if [[ "$ID" == "fedora" && -n $_rpminstall ]]; then + if [[ "$ID" == "fedora" && -v _rpminstall ]]; then # TODO: find out why this is required since it's not easily available on CentOS local _requires='Requires: pangox-compat >= 0.0.2' fi @@ -841,7 +838,7 @@ installJRMC() { else # Run rpmbuild echo "Building version $_mcversion, please wait..." - if [[ -n $_debug ]]; then + if [[ -v _debug ]]; then rpmbuild --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec" else rpmbuild --quiet --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec" > /dev/null 2>&1 @@ -869,7 +866,6 @@ installJRMC() { # 0 if createrepo is successful, 1 if not ####################################### _runCreaterepo() { - debug "Running: ${FUNCNAME[0]}" _installPackage createrepo_c @@ -936,7 +932,7 @@ installJRMC() { local _mjr # Allow user to drop an mjr file next to installJRMC - if [[ -z $_restorefile ]]; then + if [[ ! -v _restorefile ]]; then for _mjr in "$_basedir"/*.mjr; do [[ $_mjr -nt $_restorefile ]] && _restorefile="$_mjr" done @@ -1033,7 +1029,7 @@ installJRMC() { [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}" if [[ -f "$_vncpassfile" ]]; then - if [[ -z $_vncpass ]]; then + if [[ ! -v _vncpass ]]; then err "Refusing to overwrite existing $_vncpassfile with an empty password" err "Remove existing $_vncpassfile or set --vncpass to use an empty password" exit 1 @@ -1042,7 +1038,7 @@ installJRMC() { fi fi - if [[ -n $_vncpass ]]; then + if [[ -v _vncpass ]]; then if ! x11vnc -storepasswd "$_vncpass" "$_vncpassfile"; then err "Could not create VNC password file" return 1 @@ -1066,7 +1062,7 @@ installJRMC() { [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}" if [[ -f "$_vncpassfile" ]]; then - if [[ -z $_vncpass ]]; then + if [[ ! -v _vncpass ]]; then err "Refusing to overwrite existing $_vncpassfile with an empty password" err "Remove existing $_vncpassfile or set --vncpass to use an empty password" exit 1 @@ -1075,7 +1071,7 @@ installJRMC() { fi fi - if [[ -n $_vncpass ]]; then + if [[ -v _vncpass ]]; then if ! echo "$_vncpass" | vncpasswd -f > "$_vncpassfile"; then err "Could not create VNC password file" return 1 @@ -1098,9 +1094,9 @@ installJRMC() { debug "Running: ${FUNCNAME[0]}" # Check _display, else DISPLAY, else set to :0 by default - if [[ -n $_display ]]; then + if [[ -v _display ]]; then _next_display="$_display" - elif [[ -n $DISPLAY ]]; then + elif [[ -v DISPLAY ]]; then _display="${DISPLAY}" _displaynum="${_display#:}" # strip colon _displaynum="${_displaynum%.*}" # strip suffix @@ -1209,7 +1205,7 @@ installJRMC() { local _port=$(( _next_displaynum + 5900 )) - if [[ -n $_novncauth ]]; then + if [[ -v _novncauth ]]; then _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -name jriver$_next_display -SecurityTypes None -autokill -xstartup /usr/bin/mediacenter$_mversion" else _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -rfbauth $HOME/.vnc/jrmc_passwd -autokill -xstartup /usr/bin/mediacenter$_mversion" @@ -1264,7 +1260,7 @@ installJRMC() { } _getResolution - if [[ -n $_novncauth ]]; then + if [[ -v _novncauth ]]; then _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -nopw" else _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -rfbauth $HOME/.vnc/jrmc_passwd" @@ -1415,7 +1411,7 @@ installJRMC() { _buildCommands # Install MC using package manager - if [[ -n $_repoinstall ]]; then + if [[ -v _repoinstall ]]; then [[ "$ID" =~ ^(fedora|centos)$ ]] && _installPackage rpmfusion-free-release epel-release _installMCFromRepo _symlinkCerts @@ -1427,25 +1423,25 @@ installJRMC() { _setVersion # Uninstall and exit - if [[ -n $_uninstall ]]; then + if [[ -v _uninstall ]]; then _uninstall exit $? fi # Build RPM from source DEB - if [[ -n $_rpmbuild ]]; then + if [[ -v _rpmbuild ]]; then _installPackage epel-release _acquireDeb _buildRPM fi # Run createrepo - if [[ -n $_createrepo ]]; then + if [[ -v _createrepo ]]; then _runCreaterepo "$_mcrpm" fi # Install the rpm - if [[ -n $_rpminstall ]]; then + if [[ -v _rpminstall ]]; then if [[ "$ID" =~ ^(fedora|centos)$ ]]; then _installPackage rpmfusion-free-release epel-release _installPackage --noquery "$_mcrpm" From c6588e1f81579f68fda3780f13ada86aee3c3fd5 Mon Sep 17 00:00:00 2001 From: bryan Date: Sat, 8 May 2021 17:04:50 -0400 Subject: [PATCH 06/19] Some cleanup --- README.md | 29 +++++++++++++++-------------- installJRMC | 33 ++++----------------------------- 2 files changed, 19 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index a8b7055..0cf0d83 100755 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # installJRMC -This program will install [JRiver Media Center](https://www.jriver.com/) and associated helper services on Fedora (>=29), CentOS (>=8), Ubuntu (>=16.04), and Debian (>=9). +This program will install [JRiver Media Center](https://www.jriver.com/) and associated helper services on Fedora, CentOS (>=8), Ubuntu, Debian, and Linux Mint. ## README -1. This script will not point major upgrades (i.e. from v25 to v26) to your old library. You should **first perform a library backup**, install the new major version, and then restore the library backup in the new version. -2. Typically `installJRMC` should be **executed as your normal user** (i.e. don't run it with `sudo`). Services are installed for the user that executes the script so do not execute as root unless you want to install system-wide services. Doing so may lead to permissions issues. `installJRMC` will prompt you for your `sudo` password as necessary to install dependencies and services. +1. This script will not point major upgrades to your old library. You should **first perform a library backup**, install the new major version, and then restore the library backup in the new version. +2. Typically `installJRMC` should be **executed as your normal user** (i.e. don't run it with `sudo`). Services are installed for the user that executes the script so do not execute as root unless you want to install system-wide services. Doing so may lead to permissions issues. `installJRMC` will prompt you for your `sudo` password as necessary to install dependencies and services. ## Executing @@ -57,10 +57,9 @@ Here is a list of possible options that can be passed to the script. You can alw Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files) ``` - ### services -When installing systemd services it is important to execute `installJRMC` as the user you wish to run the services. Typically this is your normal user account but for some server installations it may be necessary to execute the script as root. If so, use `--service-user root` to override sanity checks. +When installing systemd services it is important to execute `installJRMC` as the user you wish to run the services. Typically this is your normal user account but for some server installations it may be necessary to execute the script as root. If so, use `--service-user root` to override sanity checks. ```text jriver-mediaserver @@ -84,7 +83,8 @@ jriver-createrepo It is possible to install multiple services at one time using multiple `--service` blocks: `installJRMC --install-repo --service jriver-x11vnc --service jriver-mediacenter` -##### `jriver-x11vnc` versus `jriver-xvnc-mediacenter` +#### `jriver-x11vnc` versus `jriver-xvnc-mediacenter` + [jriver-x11vnc](http://www.karlrunge.com/x11vnc/) shares your existing X display via VNC and can be combined with additional services to start Media Center or Media Server. Conversely, [jriver-xvnc-mediacenter](https://tigervnc.org/doc/Xvnc.html) creates a new Xvnc display and starts a JRiver Media Center service in the foreground of the new VNC display. The requisite firewall rules will also be added to the system firewall to enable remote access. **Note**: If `jriver-xvnc-mediacenter` finds an existing display it will attempt to increment the display number by 1. This should work fine in most cases, but if you have multiple running X servers on your host machine you should use the `--display` option to specify a free display. @@ -101,39 +101,40 @@ It is possible to install multiple services at one time using multiple `--servic ## Examples -* `installJRMC` +* `installJRMC` Installs the latest version of JRiver Media Center from the repository. -* `installJRMC --install-repo --service jriver-mediaserver` +* `installJRMC --install-repo --service jriver-mediaserver` Installs JRiver Media Center from the repository and starts/enables the /MediaServer service. -* `installJRMC --install-rpm --restorefile /path/to/license.mjr --mcversion 26.0.56` +* `installJRMC --install-rpm --restorefile /path/to/license.mjr --mcversion 26.0.56` Builds JRiver Media Center version 26.0.56 RPM from the source DEB, installs it (RPM distros only), and activates it using the specified .mjr license file. -* `installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user` +* `installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user` Builds the RPM, moves it to the webroot, and runs createrepo as `www-user`. -* `installJRMC --service jriver-createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user` +* `installJRMC --service jriver-createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user` Installs the jriver-createrepo timer and service to build the RPM, move it to the webroot, and run createrepo as `www-user` hourly. -* `installJRMC --install-repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"` +* `installJRMC --install-repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"` Installs services to share the existing local desktop via VNC and automatically run Media Center on startup. -* `installJRMC --install-repo --service jriver-xvnc-mediacenter --display ":2"` +* `installJRMC --install-repo --service jriver-xvnc-mediacenter --display ":2"` Installs an Xvnc server on display ':2' that starts Media Center. -* `installJRMC --uninstall` +* `installJRMC --uninstall` Uninstalls JRiver Media Center and its associated services and firewall rules. This will **not** remove your media, media library/database, or automated library backup folder. ## Additional Info + Did you find `installJRMC` useful? [Buy me a coffee!](https://paypal.me/bryanroessler?locale.x=en_US) Did you find a bug? Let me know on [Interact!](https://yabb.jriver.com/interact/index.php/topic,123648.0.html) diff --git a/installJRMC b/installJRMC index 70cb60b..6383a07 100755 --- a/installJRMC +++ b/installJRMC @@ -227,27 +227,6 @@ installJRMC() { ####################################### # Creates some OS-specific functions to query, install, and remove packages and edit # firewalls, run bash, remove and copy files, etc. - # Requires: - # ID - # _createrepo_user - # _createrepo_webroot - # Globals: - # _bash_cmd - # _rm_cmd - # _cp_cmd - # _mkdir_cmd - # _ln_cmd - # _createrepo_cmd - # _pkg_install - # _pkg_reinstall - # _pkg_install_nogpg - # _pkg_remove - # _pkg_update - # _pkg_query - # _firewall_cmd - # _systemctl_reload - # _systemctl_enable - # _systemctl_disable ####################################### _buildCommands() { @@ -315,11 +294,6 @@ installJRMC() { ####################################### # Sets default user variables - # Requires: - # _exec_user - # Globals - # _service_user - # _createrepo_user ####################################### _setUser() { @@ -458,8 +432,8 @@ installJRMC() { # _boardurl # _installPackage # Globals: - # _mcversion (i.e. "26.0.12") - # _mversion (i.e. "26") + # _mcversion + # _mversion ####################################### _setVersion() { @@ -758,6 +732,7 @@ installJRMC() { local _build_requires='' fi + if [[ "$ID" == "fedora" && -v _rpminstall ]]; then # TODO: find out why this is required since it's not easily available on CentOS local _requires='Requires: pangox-compat >= 0.0.2' @@ -964,7 +939,7 @@ installJRMC() { debug "Running: ${FUNCNAME[0]}" "$@" # Create OS-specific port rules based on argument (service) name - local -a _f_ports # for firewall_cmd + local -a _f_ports # for firewall-cmd local _u_ports # for ufw if [[ "$1" == "jriver" ]]; then _f_ports=("52100-52200/tcp" "1900/udp") From de0fc5704e663d955a68b4ec6a787873e4f5ffd9 Mon Sep 17 00:00:00 2001 From: bryan Date: Sat, 8 May 2021 17:06:03 -0400 Subject: [PATCH 07/19] Remove dead dependency --- installJRMC | 7 ------- 1 file changed, 7 deletions(-) diff --git a/installJRMC b/installJRMC index 6383a07..d7944e3 100755 --- a/installJRMC +++ b/installJRMC @@ -732,12 +732,6 @@ installJRMC() { local _build_requires='' fi - - if [[ "$ID" == "fedora" && -v _rpminstall ]]; then - # TODO: find out why this is required since it's not easily available on CentOS - local _requires='Requires: pangox-compat >= 0.0.2' - fi - # Create spec file cat <<- EOF > "$_outputdir/SPECS/mediacenter.spec" Name: MediaCenter @@ -764,7 +758,6 @@ installJRMC() { Requires: mesa-libGL Requires: libglvnd-glx Requires: pango >= 1.36 - $_requires Requires: libXScrnSaver Requires: xdg-utils Requires: libgomp >= 4.9 From 1a5d48e6ccf647fd7d54b69cd472f1c4d534e7c7 Mon Sep 17 00:00:00 2001 From: bryan Date: Sat, 8 May 2021 17:16:10 -0400 Subject: [PATCH 08/19] Remove unecessary if block --- installJRMC | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/installJRMC b/installJRMC index d7944e3..643c6d2 100755 --- a/installJRMC +++ b/installJRMC @@ -728,8 +728,6 @@ installJRMC() { # this will fail on non-rpm distros if [[ "$ID" =~ ^(fedora|centos)$ ]]; then local _build_requires=$'BuildRequires: rpm >= 4.11.0\nBuildRequires: dpkg' - else - local _build_requires='' fi # Create spec file @@ -740,7 +738,7 @@ installJRMC() { Summary: JRiver Media Center Group: Applications/Media Source0: http://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb - $_build_requires + ${_build_requires:-} BuildArch: x86_64 %define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm From 97e734e1ac858bba53569054435a521d7af5509d Mon Sep 17 00:00:00 2001 From: bryan Date: Sat, 8 May 2021 17:19:54 -0400 Subject: [PATCH 09/19] Echo script version in debug --- installJRMC | 1 + 1 file changed, 1 insertion(+) diff --git a/installJRMC b/installJRMC index 643c6d2..cc7c679 100755 --- a/installJRMC +++ b/installJRMC @@ -150,6 +150,7 @@ installJRMC() { ;; --debug|-d) echo "Debugging on" + echo "installJRMC version: $_scriptversion" _debug="true" ;; --help|-h) From 437f3da360c99b1e999c1f0d6ce4e64e24332912 Mon Sep 17 00:00:00 2001 From: bryan Date: Mon, 10 May 2021 17:08:18 -0400 Subject: [PATCH 10/19] Refactoring --- README.md | 22 +- installJRMC | 2508 ++++++++++++++++++++++++--------------------------- 2 files changed, 1183 insertions(+), 1347 deletions(-) diff --git a/README.md b/README.md index 0cf0d83..df18145 100755 --- a/README.md +++ b/README.md @@ -11,21 +11,21 @@ This program will install [JRiver Media Center](https://www.jriver.com/) and ass `installJRMC [--option [ARGUMENT]]` -Running `installJRMC` without any options will install the latest version of JRiver 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 any other option is specified then the default install method will need to be specified using `--install-repo` (or `--install-rpm`). This makes it possible to install services, containers, repos, etc. independent from Media Center. +Running `installJRMC` without any options will install the latest version of JRiver 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 any other option is specified then the default install method will need to be specified using `--repo` or `--rpm`. This makes it possible to install services, containers, repos, etc. independent of Media Center. ## Options Here is a list of possible options that can be passed to the script. You can always find the latest supported options by running `installJRMC --help`. ```text ---install-repo - Install JRiver Media Center from repository using package manager (Default) +--repo + Install JRiver Media Center from repository using package manager DEB-based OSes: Official package repository RPM-based OSes: BryanC's unofficial repository ---install-rpm - (RPM-based OSes only) Build RPM from source DEB and install it +--rpm + Build RPM from source DEB and install it --rpmbuild - Build RPM from source DEB + Build RPM from source DEB but do not install --outputdir PATH Generate rpmbuild output in this directory (Default: $PWD/outputdir) --mcversion VERSION @@ -81,7 +81,7 @@ jriver-createrepo Install hourly service to build latest MC RPM and run createrepo ``` -It is possible to install multiple services at one time using multiple `--service` blocks: `installJRMC --install-repo --service jriver-x11vnc --service jriver-mediacenter` +It is possible to install multiple services at one time using multiple `--service` blocks: `installJRMC --repo --service jriver-x11vnc --service jriver-mediacenter` #### `jriver-x11vnc` versus `jriver-xvnc-mediacenter` @@ -105,11 +105,11 @@ It is possible to install multiple services at one time using multiple `--servic Installs the latest version of JRiver Media Center from the repository. -* `installJRMC --install-repo --service jriver-mediaserver` +* `installJRMC --repo --service jriver-mediaserver` Installs JRiver Media Center from the repository and starts/enables the /MediaServer service. -* `installJRMC --install-rpm --restorefile /path/to/license.mjr --mcversion 26.0.56` +* `installJRMC --rpm --restorefile /path/to/license.mjr --mcversion 26.0.56` Builds JRiver Media Center version 26.0.56 RPM from the source DEB, installs it (RPM distros only), and activates it using the specified .mjr license file. @@ -121,11 +121,11 @@ It is possible to install multiple services at one time using multiple `--servic Installs the jriver-createrepo timer and service to build the RPM, move it to the webroot, and run createrepo as `www-user` hourly. -* `installJRMC --install-repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"` +* `installJRMC --repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"` Installs services to share the existing local desktop via VNC and automatically run Media Center on startup. -* `installJRMC --install-repo --service jriver-xvnc-mediacenter --display ":2"` +* `installJRMC --repo --service jriver-xvnc-mediacenter --display ":2"` Installs an Xvnc server on display ':2' that starts Media Center. diff --git a/installJRMC b/installJRMC index cc7c679..e341e5d 100755 --- a/installJRMC +++ b/installJRMC @@ -10,1431 +10,1267 @@ shopt -s extglob # 1. Raspberry Pi OS support # 2. Interactive installation (ncurses?) # -# installJRMC can be run directly or sourced as a function (by sourcing this file) -# Arguments: -# see _printHelpAndExit() and _parseInput() for available options -# Returns: -# 0 if critical functions complete successfully ####################################### -installJRMC() { - _scriptversion="0.9.5" - _boardurl="https://yabb.jriver.com/interact/index.php/board,67.0.html" - _outputdir="$_basedir/output" - _createrepo_webroot="/srv/jriver" - _exec_user="$(whoami)" - _available_services=("jriver-createrepo" "jriver-x11vnc" "jriver-mediaserver" "jriver-mediacenter" "jriver-xvnc-mediacenter") - #_available_containers=("mediacenter-xvnc" "createrepo") +_scriptversion="0.9.6" +_boardurl="https://yabb.jriver.com/interact/index.php/board,67.0.html" +_outputdir="$PWD/output" +_createrepo_webroot="/srv/jriver" +_exec_user="$(whoami)" - _printHelpAndExit() { - debug "Running: ${FUNCNAME[0]}" +_printHelpAndExit() { + debug "Running: ${FUNCNAME[0]}" - cat <<- 'EOF' - USAGE: - installJRMC [[OPTION] [VALUE]]... + cat <<- 'EOF' + USAGE: + installJRMC [[OPTION] [VALUE]]... - OPTIONS - --install-repo - Install JRiver Media Center from repository using package manager (Default) - DEB-based OSes: Official package repository - RPM-based OSes: BryanC unofficial repository - --install-rpm - (RPM-based OSes only) Build RPM from source DEB and install it - --rpmbuild - Build RPM from source DEB - --outputdir PATH - Generate rpmbuild output in this directory (Default: $PWD/outputdir) - --mcversion VERSION - Build or install a specific version (Default: install the latest version) - --restorefile RESTOREFILE - Restore file location for registration (Default: skip registration) - --betapass PASSWORD - Enter beta team password for access to beta builds - --service-user USER - Install systemd services and containers for USER - --service, -s SERVICE - See SERVICES section below for a list of possible services to install - --container, -c CONTAINER (TODO: Under construction) - See CONTAINERS section below for a list of possible services to install - --createrepo - Build rpm, copy to webroot, and run createrepo - --createrepo-webroot PATH - The webroot directory to install the repo (Default: /srv/jriver/) - --createrepo-user USER - The web server user (Default: current user) - --version, -v - Print this script version and exit - --debug, -d - Print debug output - --help, -h - Print help dialog and exit - --uninstall, -u - Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files) + If no options (besides -d) are provided, the script will default to --repo - SERVICES - jriver-mediaserver - Enable and start a mediaserver systemd service (requires an existing X server) - jriver-mediacenter - Enable and start a mediacenter systemd service (requires an existing X server) - jriver-x11vnc - Enable and start x11vnc for the local desktop (requires an existing X server) - Usually combined with jriver-mediaserver or jriver-mediacenter services - --vncpass and --display are also valid options (see below) - jriver-xvnc-mediacenter - 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 use no password - --display DISPLAY - Display to start x11vnc/Xvnc (Default: The current display (x11vnc) or the - current display incremented by 1 (Xvnc)) - jriver-createrepo - Install hourly service to build latest MC RPM and run createrepo + OPTIONS + --repo + Install JRiver Media Center from repository using package manager + DEB-based OSes: JRiver official package repository + RPM-based OSes: BryanC unofficial repository + --rpm + Build RPM from source DEB and install it + --rpmbuild + Build RPM from source DEB (no installation) + --outputdir PATH + Generate rpmbuild output in this directory (Default: $PWD/outputdir) + --mcversion VERSION + Build or install a specific version (Default: install the latest version) + --restorefile RESTOREFILE + Restore file location for registration (Default: skip registration) + --betapass PASSWORD + Enter beta team password for access to beta builds + --service-user USER + Install systemd services and containers for USER (Default: current user) + --service, -s SERVICE + See SERVICES section below for a list of possible services to install + --container, -c CONTAINER (TODO: Under construction) + See CONTAINERS section below for a list of possible services to install + --createrepo + Build rpm, copy to webroot, and run createrepo + --createrepo-webroot PATH + The webroot directory to install the repo (Default: /srv/jriver/) + --createrepo-user USER + The web server user (Default: current user) + --version, -v + Print this script version and exit + --debug, -d + Print debug output + --help, -h + Print help dialog and exit + --uninstall, -u + Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files) - CONTAINERS (TODO: Under construction) - mediacenter-xvnc - createrepo - EOF + SERVICES + jriver-mediaserver + Enable and start a mediaserver systemd service (requires an existing X server) + jriver-mediacenter + Enable and start a mediacenter systemd service (requires an existing X server) + jriver-x11vnc + Enable and start x11vnc for the local desktop (requires an existing X server) + Usually combined with jriver-mediaserver or jriver-mediacenter services + --vncpass and --display are also valid options (see below) + jriver-xvnc-mediacenter + 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 use no password + --display DISPLAY + Display to start x11vnc/Xvnc (Default: The current display (x11vnc) or the + current display incremented by 1 (Xvnc)) + jriver-createrepo + Install hourly service to build latest MC RPM and run createrepo + + CONTAINERS (TODO: Under construction) + mediacenter-xvnc + createrepo + EOF # Exit using passed exit code [[ ! -v 1 ]] && exit 0 || exit "$1" } - _parseInput() { - debug "Running: ${FUNCNAME[0]}" +_init() { + debug "Running: ${FUNCNAME[0]}" - # set default behavior - if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then - _repoinstall="true" - fi + _getOS - if _input=$(getopt -o +vdhus:c: -l install-repo,install-rpm,rpmbuild,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then - eval set -- "$_input" - while true; do - case "$1" in - --install-repo) - _repoinstall="true" - ;; - --install-rpm) - _rpmbuild="true" - _rpminstall="true" - ;; - --rpmbuild) - _rpmbuild="true" - ;; - --outputdir) - shift && _outputdir="$1" - ;; - --mcversion) - shift && _mcversion="$1" - ;; - --restorefile) - shift && _restorefile="$1" - ;; - --betapass) - shift && _betapass="$1" - ;; - --service-user) - shift && _service_user="$1" - ;; - --service|-s) - shift && _services+=("$1") - ;; - --container|-c) - shift && _containers+=("$1") - ;; - --version|-v) - echo "Version: $_scriptversion" - exit 0 - ;; - --debug|-d) - echo "Debugging on" - echo "installJRMC version: $_scriptversion" - _debug="true" - ;; - --help|-h) - _printHelpAndExit 0 - ;; - --uninstall|-u) - _uninstall="true" - ;; - --createrepo) - _createrepo="true" - _rpmbuild="true" - ;; - --createrepo-webroot) - shift && _createrepo_webroot="$1" - ;; - --createrepo-user) - shift && _createrepo_user="$1" - ;; - --vncpass) - shift && _vncpass="$1" - ;; - --display) - shift && _display="$1" - ;; - --) - shift - break - ;; - esac - shift - done - else - err "Incorrect options provided" - _printHelpAndExit 1 - fi - } + _parseInput "$@" - err() { echo "Error: $*" >&2; } + # Agnostic commands + _bash_cmd(){ _ifSudo bash -c "$@"; } + _rm_cmd(){ _ifSudo rm -rf "$@"; } + _cp_cmd(){ _ifSudo cp -n "$@"; } + _mkdir_cmd(){ _ifSudo mkdir -p "$@"; } + _ln_cmd(){ _ifSudo ln -s "$@"; } + _systemctl_reload(){ _ifSudo systemctl daemon-reload; } + _systemctl_enable(){ _ifSudo systemctl enable --now "$@"; } + _systemctl_disable(){ _ifSudo systemctl disable --now "$@"; } - debug() { [[ -v _debug ]] && echo "Debug: $*"; } + # OS-specific commands + if [[ "$ID" =~ ^(fedora|centos)$ ]]; then + _pkg_install(){ _ifSudo dnf install -y "$@"; } + _pkg_reinstall(){ _ifSudo dnf reinstall -y "$@"; } + _pkg_install_nogpg(){ _ifSudo dnf install --nogpgcheck -y "$@"; } + _pkg_remove(){ _ifSudo dnf remove -y "$@"; } + _pkg_update(){ _ifSudo dnf makecache; } + _pkg_query(){ _ifSudo rpm -q "$@"; } + _firewall_cmd(){ _ifSudo firewall-cmd "$@"; } + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then + _pkg_install(){ _ifSudo apt-get install -y -q0 "$@"; } + _pkg_reinstall(){ _ifSudo apt-get reinstall -y -q0 "$@"; } + _pkg_install_nogpg(){ _ifSudo apt-get install -y -q0 "$@"; } + _pkg_remove(){ _ifSudo apt-get remove -y -q0 "$@"; } + _pkg_update(){ _ifSudo apt-get update -y -q0; } + _pkg_query(){ _ifSudo dpkg -s "$@"; } + _firewall_cmd(){ _ifSudo ufw "$@"; } + fi - ####################################### - # Prepend this to any command that you wish to execute with sudo - # Requires: - # _exec_user - ####################################### - _ifSudo() { - if [[ "$_exec_user" != "root" ]]; then - sudo "$@" - else - "$@" - fi - } + # Set defaults + if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then + debug "No options passed, defaulting to --repo installation method" + _repoinstall="true" + fi + + _service_user="${_service_user:-$_exec_user}" + _createrepo_user="${_createrepo_user:-$_exec_user}" + + # Set package aliases + if [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then + declare -Ag PKG_ALIASES + PKG_ALIASES["xorg-x11-utils"]="xorg-x11" + PKG_ALIASES["rpm-build"]="rpm" + PKG_ALIASES["createrepo_c"]="createrepo" + PKG_ALIASES["tigervnc-server"]="tigervnc-standalone-server" + fi + + # Install script dependencies + [[ "$ID" == "centos" ]] && _installPackage epel-release + [[ ! -v _mcversion ]] && _installPackage wget + + # Set MC version + _setVersion +} - ####################################### - # Sources /etc/os-release so we know which OS we're running on - # Used in: _buildCommands() - ####################################### - _getOS() { - debug "Running: ${FUNCNAME[0]}" +_main() { - if [[ -e "/etc/os-release" ]]; then - source "/etc/os-release" - else - err "No /etc/os-release found" - err "Your OS is unsupported" - _printHelpAndExit 1 - fi + _init "$@" - debug "Platform: $ID $VERSION_ID" - } + # Uninstall and exit + if [[ -v _uninstall ]]; then + _uninstall + exit $? + fi + # Install MC using package manager + if [[ -v _repoinstall ]]; then + _installMCFromRepo + _symlinkCerts + _restoreLicense + _openFirewall "jriver" + fi - ####################################### - # Creates some OS-specific functions to query, install, and remove packages and edit - # firewalls, run bash, remove and copy files, etc. - ####################################### - _buildCommands() { + # Build RPM from source deb package + if [[ -v _rpmbuild ]]; then + _acquireDeb + _buildRPM + fi - # Detect OS - _getOS + # Run createrepo + if [[ -v _createrepo ]]; then + _runCreaterepo "$_mcrpm" + fi - debug "Running: ${FUNCNAME[0]}" + # Install the rpm + if [[ -v _rpminstall ]]; then + _installPackage --noquery "$_mcrpm" + _symlinkCerts + _restoreLicense + _openFirewall "jriver" + fi - # Agnostic commands - _bash_cmd(){ _ifSudo bash -c "$@"; } - _rm_cmd(){ _ifSudo rm -rf "$@"; } - _cp_cmd(){ _ifSudo cp -n "$@"; } - _mkdir_cmd(){ _ifSudo mkdir -p "$@"; } - _ln_cmd(){ _ifSudo ln -s "$@"; } - _systemctl_reload(){ _ifSudo systemctl daemon-reload; } - _systemctl_start(){ - echo "Starting $*" - if ! _ifSudo systemctl start "$@"; then - err "Could not start $*" - err "Check service status using \"sudo systemctl status $*\"" - return 1 - fi - } - _systemctl_enable(){ _ifSudo systemctl enable "$@"; } - _systemctl_disable(){ _ifSudo systemctl disable --now "$@"; } - - # OS-specific commands - if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - _pkg_install(){ _ifSudo dnf install -y "$@"; } - _pkg_reinstall(){ _ifSudo dnf reinstall -y "$@"; } - _pkg_install_nogpg(){ _ifSudo dnf install --nogpgcheck -y "$@"; } - _pkg_remove(){ _ifSudo dnf remove -y "$@"; } - _pkg_update(){ _ifSudo dnf makecache; } - _pkg_query(){ _ifSudo rpm -q "$@"; } - _firewall_cmd(){ _ifSudo firewall-cmd "$@"; } - elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - _pkg_install(){ _ifSudo apt-get install -y -q0 "$@"; } - _pkg_reinstall(){ _ifSudo apt-get reinstall -y -q0 "$@"; } - _pkg_install_nogpg(){ _ifSudo apt-get install -y -q0 "$@"; } - _pkg_remove(){ _ifSudo apt-get remove -y -q0 "$@"; } - _pkg_update(){ _ifSudo apt-get update -y -q0; } - _pkg_query(){ _ifSudo dpkg -s "$@"; } - _firewall_cmd(){ _ifSudo ufw "$@"; } - fi - - # Some additional commands specifically for createrepo (primarily to handle user rights) - # Could also go in runCreaterepo() but let's leave it here for now - if [[ $_createrepo_user != "root" ]]; then - if [[ -d "$_createrepo_webroot/repodata" ]]; then - _createrepo_cmd(){ sudo -u "$_createrepo_user" createrepo -q --update "$@"; } + # Install services + _setDisplay + for _service in "${_services[@]}"; do + _servicePrep "$_service" + if ! "_service_$_service"; then + if [[ $? -eq 127 ]]; then + err "Service $_service does not exist, check your service name" else - _createrepo_cmd(){ sudo -u "$_createrepo_user" createrepo -q "$@"; } + err "Failed to create service: $_service" fi - _cr_mkdir_cmd(){ sudo -u "$_createrepo_user" mkdir -p "$@"; } - _cr_cp_cmd(){ sudo -u "$_createrepo_user" cp -n "$@"; } - else - if [[ -d "$_createrepo_webroot/repodata" ]]; then - _createrepo_cmd(){ createrepo -q --update "$@"; } + fi + done + + # Install containers + for _container in "${_containers[@]}"; do + if ! "_container_$_container"; then + if [[ $? -eq 127 ]]; then + err "Container $_container does not exist, check your container name" else - _createrepo_cmd(){ createrepo -q "$@"; } + err "Failed to create container: $_container" fi fi - } + done +} - ####################################### - # Sets default user variables - ####################################### - _setUser() { - - [[ ! -v _service_user ]] && _service_user="$_exec_user" - [[ ! -v _createrepo_user ]] && _createrepo_user="$_exec_user" - } - - - ####################################### - # Installs a package using the system package manager - # Arguments: - # One or more package names - # Options: - # --noquery, -n: Do not query the package state (useful if installing a local RPM) - # Returns: - # Will exit 1 if failed - ####################################### - _installPackage() { - - debug "Running: ${FUNCNAME[0]}" "$@" - - if _input=$(getopt -o +n -l noquery -- "$@"); then - eval set -- "$_input" - while true; do - case "$1" in - --noquery|-n) - local _noquery="true" - ;; - --) - shift - break - ;; - esac - shift - done - else - err "Incorrect options provided" - _printHelpAndExit 1 +####################################### +# Helper functions +####################################### +err() { echo "Error: $*" >&2; } +debug() { + if [[ -v _debug ]]; then + if [[ $# -gt 0 ]]; then + echo "Debug: $*" fi - - # We will add packages to this array if their command is not available - local -a _pkg_array - local -a _url_pkg_array - - # parse arguments (packages) - for _pkg in "$@"; do - # Clean up package name and handle OS-specific tweaks - _packageQuirks "$_pkg" - # Insert the package name to test if already installed - if [[ "$_pkg" != "" ]]; then - if [[ -v _noquery ]] || ! _pkg_query "$_pkg" > /dev/null 2>&1; then - if [[ -v _url_pkg ]]; then - _url_pkg_array+=("$_url_pkg") - else - _pkg_array+=("$_pkg") - fi - fi - fi - done - - # Install from package name (with gpg check) - if [[ ${#_pkg_array[@]} -ge 1 ]]; then - echo "Installing:" "${_pkg_array[@]}" - if [[ -v _debug ]]; then - if ! _pkg_install "${_pkg_array[@]}"; then - err "Failed to install package. Attempting to continue..." - return 1 - fi - elif ! _pkg_install "${_pkg_array[@]}" > /dev/null 2>&1; then - err "Failed to install package. Attempting to continue..." - return 1 - fi - fi - - # Install from package url (without gpg check) - if [[ ${#_url_pkg_array[@]} -ge 1 ]]; then - echo "Installing:" "${_url_pkg_array[@]}" - if [[ -v _debug ]]; then - if ! _pkg_install_nogpg "${_url_pkg_array[@]}"; then - err "Failed to install package. Attempting to continue..." - return 1 - fi - elif ! _pkg_install_nogpg "${_url_pkg_array[@]}" > /dev/null 2>&1; then - err "Failed to install package. Attempting to continue..." - return 1 - fi - fi - } - - - ####################################### - # Handles OS-specific package name tweaks and source urls - # Arguments: - # A package name - # Globals: - # _pkg - # _url_pkg - ####################################### - _packageQuirks() { - - debug "Running: ${FUNCNAME[0]}" "$@" - - unset _url_pkg - - if [[ "$1" == "xorg-x11-utils" && "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - _pkg="x11-utils" - elif [[ "$1" == "rpm-build" && "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - _pkg="rpm" - elif [[ "$1" == "createrepo_c" && "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - _pkg="createrepo" - elif [[ "$1" == "rpmfusion-free-release" ]]; then - if [[ "$ID" == "fedora" ]]; then - # As of MC26 and Fedora 32 I don't believe that the rpmfusion repo is necessary - #_url_pkg="https://download1.rpmfusion.org/free/$ID/rpmfusion-free-release-$VERSION_ID.noarch.rpm" - #_pkg="$1" - _pkg="" - elif [[ "$ID" == "centos" ]]; then - _url_pkg="https://download1.rpmfusion.org/free/el/rpmfusion-free-release-$VERSION_ID.noarch.rpm" - _pkg="$1" - else - _pkg="" - fi - elif [[ "$1" == "epel-release" && "$ID" != "centos" ]]; then - _pkg="" - elif [[ "$1" == "tigervnc-server" && "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - _pkg="tigervnc-standalone-server" - else - _pkg="$1" - fi - } - - - ####################################### - # Get our MC working version from input argument or scraping Interact - # Requires: - # _boardurl - # _installPackage - # Globals: - # _mcversion - # _mversion - ####################################### - _setVersion() { - - debug "Running: ${FUNCNAME[0]}" - - if [[ ! -v _mcversion ]]; then - - _installPackage wget - - # Get latest version from Interact - echo "Scraping latest MC version number from Interact..." - if ! _mcversion=$(wget -qO- "$_boardurl" | grep -o "[0-9][0-9]\.[0-9]\.[0-9]\+" | head -n 1); then - err "MC version could not be scraped. Please specify a version manually using --mcversion or check your --boardurl" - _printHelpAndExit 1 - fi - fi - - echo "Using version: $_mcversion" - - # Extract major version number - _mversion="${_mcversion%%.*}" - - # Saving this substituion in case it's needed in the future - #_variation="${_mcversion##*.}" - } - - - ####################################### - # Check if an argument exists in an array - # Arguments: - # The first argument is the string to match to the following arguments - # Example: - # _inArray "zebra" "${animals_arr[@]}" - # Returns: - # 0 if a match is found, 1 if not - ####################################### - _inArray() { - - local _match="$1" - shift - - local _item - for _item in "$@"; do - [[ "$_item" == "$_match" ]] && return 0 - done - + else return 1 - } + fi +} - ####################################### - # Clean up nonsensical user input - # Notes: - # I try to keep this function as short as possible and provide better input options and - # sensible defaults than workarounds - # Test: - # _installJRMC should run sucessfully even without running _sanityChecks() - ####################################### - _sanityChecks() { - debug "Running: ${FUNCNAME[0]}" - - # Check for bad service name - _checkServices() { - - debug "Running: ${FUNCNAME[0]}" - - for _service in "${_services[@]}"; do - if ! _inArray "$_service" "${_available_services[@]}"; then - echo "Incorrect service type provided" - _printHelpAndExit 1 - fi - done - } +####################################### +# Prepend this to any command that you wish to execute with sudo +# Requires: +# _exec_user +####################################### +_ifSudo() { + if [[ "$_exec_user" != "root" ]]; then + sudo "$@" + else + "$@" + fi +} - _checkMCInstalled() { - debug "Running: ${FUNCNAME[0]}" +####################################### +# Parse CLI input from the user w/ getopt +####################################### +_parseInput() { + debug "Running: ${FUNCNAME[0]}" - for _service in "${_services[@]}"; do - if [[ "$_service" =~ ^(jriver-mediacenter|jriver-mediaserver|jriver-xvnc-mediacenter|jriver-x11vnc)$ ]] \ - && [[ ! -v _repoinstall && ! -v _rpminstall ]] \ - && [[ ! -x $(command -v "mediacenter$_mversion") ]]; then - err "You are attempting to install a service that depends on JRiver Media Center" - err "without installing JRiver Media Center" - err "Automatically enabling --repo-install" + if _input=$(getopt -o +vdhus:c: -l repo,rpm,rpmbuild,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then + eval set -- "$_input" + while true; do + case "$1" in + --repo) _repoinstall="true" - fi - done - } + ;; + --rpm) + [[ ! "$ID" =~ ^(fedora|centos)$ ]] && \ + err "RPM installation not available on $ID" && \ + _printHelpAndExit 1 + _rpmbuild="true" + _rpminstall="true" + ;; + --rpmbuild) + _rpmbuild="true" + ;; + --outputdir) + shift && _outputdir="$1" + ;; + --mcversion) + shift && _mcversion="$1" + ;; + --restorefile) + shift && _restorefile="$1" + ;; + --betapass) + shift && _betapass="$1" + ;; + --service-user) + shift && _service_user="$1" + ;; + --service|-s) + shift && _services+=("$1") + ;; + --createrepo) + _rpmbuild="true" + _createrepo="true" + ;; + --createrepo-webroot) + shift && _createrepo_webroot="$1" + ;; + --createrepo-user) + shift && _createrepo_user="$1" + ;; + --vncpass) + shift && _vncpass="$1" + ;; + --display) + shift && _display="$1" + ;; + --container|-c) + shift && _containers+=("$1") + ;; + --version|-v) + echo "Version: $_scriptversion" + exit 0 + ;; + --debug|-d) + echo "Debugging on" + echo "installJRMC version: $_scriptversion" + _debug="true" + ;; + --help|-h) + _printHelpAndExit 0 + ;; + --uninstall|-u) + _uninstall="true" + ;; + --) + shift + break + ;; + esac + shift + done + else + err "Incorrect options provided" + _printHelpAndExit 1 + fi +} - _checkUser() { - debug "Running: ${FUNCNAME[0]}" +####################################### +# Get host OS from /etc/os-release +####################################### +_getOS() { + debug "Running: ${FUNCNAME[0]}" - if [[ "$_exec_user" == "root" && ! -v _service_user && "${_services[*]}" ]]; then - err "Attempting to install services as the root user" - err "This is not recommended and we are exiting now to prevent permission hell" - err "You can override this safety check by manually specifying --user root" + if [[ -e "/etc/os-release" ]]; then + source "/etc/os-release" + else + err "/etc/os-release not found" + err "Your OS is unsupported" + _printHelpAndExit 1 + fi + + debug "Platform: $ID $VERSION_ID" +} + + +####################################### +# Get our MC working version from input argument or scraping Interact +# Requires: +# _boardurl +####################################### +_setVersion() { + debug "Running: ${FUNCNAME[0]}" + + # If user does not specify a version, scrape the latest from Interact + if [[ ! -v _mcversion ]]; then + echo "Scraping latest MC version number from Interact..." + if ! _mcversion=$(wget -qO- "$_boardurl" | grep -o "[0-9][0-9]\.[0-9]\.[0-9]\+" | head -n 1); then + err "MC version could not be scraped. Please recheck the boardurl: $_boardurl or specify a version manually using --mcversion" + _printHelpAndExit 1 + fi + fi + + echo "Using version: $_mcversion" + + # Extract major version number + _mversion="${_mcversion%%.*}" + + # Saving this substituion in case it's needed in the future + #_variation="${_mcversion##*.}" +} + + +####################################### +# Installs a package using the system package manager +# Arguments: +# One or more package names +# Options: +# --noquery, -n: Do not query the package state (useful if installing a local RPM) +# Returns: +# Will exit 1 if failed +####################################### +_installPackage() { + debug "Running: ${FUNCNAME[0]}" "$@" + + if _input=$(getopt -o +n -l noquery -- "$@"); then + eval set -- "$_input" + while true; do + case "$1" in + --noquery|-n) + local _noquery="true" + ;; + --) + shift + break + ;; + esac + shift + done + else + err "Incorrect options provided" + _printHelpAndExit 1 + fi + + # We will add packages to this array if their command is not available + local -a _pkg_array + local -a _url_pkg_array + + # Parse packages + for _pkg in "$@"; do + [[ -v PKG_ALIASES && -v PKG_ALIASES["$_pkg"] ]] && _pkg=PKG_ALIASES["$_pkg"] + # Insert the package name to test if already installed + if [[ -v _noquery ]] || ! _pkg_query "$_pkg" > /dev/null 2>&1; then + if [[ -v _url_pkg ]]; then + _url_pkg_array+=("$_url_pkg") + else + _pkg_array+=("$_pkg") + fi + fi + done + + # Install from package name (with gpg check) + if [[ ${#_pkg_array[@]} -ge 1 ]]; then + echo "Installing:" "${_pkg_array[@]}" + if debug; then + if ! _pkg_install "${_pkg_array[@]}"; then + err "Failed to install package. Attempting to continue..." return 1 fi - } - - - # Enable/disable sanity checks - if _checkServices && _checkMCInstalled && _checkUser; then - debug "Sanity checks passed!" - return 0 - else - err "Sanity checks failed!" - exit 1 + elif ! _pkg_install "${_pkg_array[@]}" > /dev/null 2>&1; then + err "Failed to install package. Attempting to continue..." + return 1 fi - } + fi + + # Install from package url (without gpg check) + if [[ ${#_url_pkg_array[@]} -ge 1 ]]; then + echo "Installing:" "${_url_pkg_array[@]}" + if debug; then + if ! _pkg_install_nogpg "${_url_pkg_array[@]}"; then + err "Failed to install package. Attempting to continue..." + return 1 + fi + elif ! _pkg_install_nogpg "${_url_pkg_array[@]}" > /dev/null 2>&1; then + err "Failed to install package. Attempting to continue..." + return 1 + fi + fi +} - ####################################### - # Installs JRiver Media Center from a repository - # Returns: - # 0 if JRiver Media Center installed sucessfully - ####################################### - _installMCFromRepo() { +####################################### +# Installs JRiver Media Center from a repository +# Returns: +# 0 if JRiver Media Center installed sucessfully +####################################### +_installMCFromRepo() { + debug "Running: ${FUNCNAME[0]}" + + echo "Installing JRiver Media Center from repo..." + + ! debug && \ + echo "This may take a few minutes to complete"; \ + echo "Use --debug for verbose output" + + local _mcpkg + + # Add repository files + _addRepo() { debug "Running: ${FUNCNAME[0]}" - echo "Installing JRiver Media Center from repo..." - [[ ! -v _debug ]] && \ - echo "This may take a few minutes"; \ - echo "Use --debug for verbose output" - - local _mcpkg - - # Add repository files - _addRepo() { - debug "Running: ${FUNCNAME[0]}" - # Add repositories to OS-specific package managers - if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - _bash_cmd 'cat <<- EOF > /etc/yum.repos.d/jriver.repo - [jriver] - name=JRiver Media Center repo by BryanC - baseurl=https://repos.bryanroessler.com/jriver - gpgcheck=0 - EOF' - elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - _installPackage wget - wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | _ifSudo apt-key add - > /dev/null 2>&1 - _bash_cmd 'cat <<- EOF > /etc/apt/sources.list.d/jriver.list - deb [arch=amd64,i386,armhf] http://dist.jriver.com/latest/mediacenter/ buster main - EOF' - fi - } - _addRepo - - # Update package list - debug "Updating package list" - if ! _pkg_update > /dev/null 2>&1; then - err "Package update failed!" - exit 1 - fi - - # If user specifies a version, use that - if [[ -v _mcversion ]]; then - _setVersion - local _specific_version="true" - fi - - local _mcpkg - - # Fedora/CentOS use a universal package name -- easy if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - _mcpkg="MediaCenter" + _bash_cmd 'cat <<- EOF > /etc/yum.repos.d/jriver.repo + [jriver] + name=JRiver Media Center repo by BryanC + baseurl=https://repos.bryanroessler.com/jriver + gpgcheck=0 + EOF' + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then + _installPackage wget + wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | _ifSudo apt-key add - > /dev/null 2>&1 + _bash_cmd 'cat <<- EOF > /etc/apt/sources.list.d/jriver.list + deb [arch=amd64,i386,armhf] http://dist.jriver.com/latest/mediacenter/ buster main + EOF' fi + } + _addRepo - # Ubuntu/Debian incorporate the mversion into the package name -- more fun! - if [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - if [[ ! -v _mversion ]]; then - # Try parsing the latest mversion from the repo - if _mcpkg=$(apt-get install mediacenter?? -s -q0 | grep "selecting" | tail -1| awk '{print $3}'); then - _mcpkg="${_mcpkg%\'}" - _mcpkg="${_mcpkg#\'}" - # Scrape Interact - else - _setVersion - _mcpkg="mediacenter$_mversion" - fi + # Update package list + debug "Updating package list" + if ! _pkg_update > /dev/null 2>&1; then + err "Package update failed!" + exit 1 + fi + + local _mcpkg + + # Fedora/CentOS use a universal package name -- easy + if [[ "$ID" =~ ^(fedora|centos)$ ]]; then + _mcpkg="MediaCenter" + # Ubuntu/Debian incorporate the mversion into the package name -- more fun! + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then + if [[ ! -v _mversion ]]; then + # Try parsing the latest mversion from the repo + if _mcpkg=$(apt-get install mediacenter?? -s -q0 | grep "selecting" | tail -1| awk '{print $3}'); then + _mcpkg="${_mcpkg%\'}" + _mcpkg="${_mcpkg#\'}" + # Scrape Interact else _mcpkg="mediacenter$_mversion" fi - # Sanity check - if [[ ! "$_mcpkg" =~ ^mediacenter[0-9][0-9]$ ]]; then - err "Could not parse MC package name" - exit 1 - fi - fi - - if [[ -v _specific_version ]]; then - if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - if [[ -v _debug ]]; then - _installPackage "$_mcpkg-$_mcversion" - else - _installPackage "$_mcpkg-$_mcversion" > /dev/null 2>&1 - fi - elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - if [[ -v _debug ]]; then - _installPackage "$_mcpkg=$_mcversion" - else - _installPackage "$_mcpkg=$_mcversion" > /dev/null 2>&1 - fi - fi else - if [[ -v _debug ]]; then - _installPackage "$_mcpkg" - else - _installPackage "$_mcpkg" > /dev/null 2>&1 - fi + _mcpkg="mediacenter$_mversion" fi - - # shellcheck disable=SC2181 - # Rationale: More compact to check this once - if [[ $? -eq 0 ]]; then - echo "JRiver Media Center installed successfully" - return 0 - else - err "JRiver Media Center installation failed" + # Sanity check + if [[ ! "$_mcpkg" =~ ^mediacenter[0-9][0-9]$ ]]; then + err "Could not parse MC package name" exit 1 fi - } + fi - - ####################################### - # Acquire the source DEB package from JRiver's servers - # Returns: - # 0 if DEB file downloaded successfully, 1 if failed - ####################################### - _acquireDeb() { - debug "Running: ${FUNCNAME[0]}" - - local _debfilename="$_outputdir/SOURCES/MediaCenter-${_mcversion}-amd64.deb" - - # If necessary, create SOURCES dir - [[ ! -d "$_outputdir/SOURCES" ]] && mkdir -p "$_outputdir/SOURCES" - - # If deb file already exists, skip download - if [[ -f "$_debfilename" ]]; then - echo "Using local DEB file: $_debfilename" - # Else check beta repo - elif [[ -v _betapass ]]; then - if wget -q -O "$_debfilename" \ - "https://files.jriver.com/mediacenter/channels/v${_mversion}/beta/${_betapass}/MediaCenter-${_mcversion}-amd64.deb"; then - true - fi - # Else check test repo - elif wget -q -O "$_debfilename" \ - "https://files.jriver.com/mediacenter/test/MediaCenter-${_mcversion}-amd64.deb"; then - true - # Else check latest repo - elif wget -q -O "$_debfilename" \ - "https://files.jriver.com/mediacenter/channels/v${_mversion}/latest/MediaCenter-${_mcversion}-amd64.deb"; then - true - else - err "Cannot find DEB file. Exiting..." - exit 1 - fi - - if [[ ! -f "$_debfilename" ]]; then - err "Downloaded DEB file missing or corrupted, exiting..." - exit 1 - fi - } - - - ####################################### - # Creates a SPEC file and builds the RPM from the source DEB using rpmbuild - # Requires: - # _outputdir - # ID - # _mcversion - # _mversion - # _installPackage - # Globals: - # _mcrpm - # Returns: - # 0 if rpmbuild is successful, 1 if not - ####################################### - _buildRPM() { - debug "Running: ${FUNCNAME[0]}" - - # install build dependencies - _installPackage wget dpkg rpm-build - - # If necessary, make build directories - [[ ! -d "$_outputdir/SPECS" ]] && mkdir -p "$_outputdir/SPECS" - - # rpmbuild uses rpm to check for build dependencies - # this will fail on non-rpm distros + if [[ -v _specific_version ]]; then if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - local _build_requires=$'BuildRequires: rpm >= 4.11.0\nBuildRequires: dpkg' - fi - - # Create spec file - cat <<- EOF > "$_outputdir/SPECS/mediacenter.spec" - Name: MediaCenter - Version: $_mcversion - Release: 1 - Summary: JRiver Media Center - Group: Applications/Media - Source0: http://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb - ${_build_requires:-} - BuildArch: x86_64 - %define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm - - AutoReq: 0 - Requires: glibc >= 2.19 - Requires: alsa-lib >= 1.0.28 - Requires: libuuid >= 2.25 - Requires: libX11 >= 1.6 - Requires: libX11-common >= 1.6 - Requires: libXext >= 1.3 - Requires: libxcb >= 1.1 - Requires: libXdmcp >= 1.1 - Requires: libstdc++ >= 4.9 - Requires: gtk3 >= 3.14 - Requires: mesa-libGL - Requires: libglvnd-glx - Requires: pango >= 1.36 - Requires: libXScrnSaver - Requires: xdg-utils - Requires: libgomp >= 4.9 - Requires: nss >= 3.26 - Requires: nspr >= 4.12 - Requires: ca-certificates - Requires: python3 - Recommends: vorbis-tools >= 1.4.0 - Recommends: lame >= 3.0 - - Provides: mediacenter$_mversion - - License: Copyright 1998-2020, 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.*$ - - %description - Media Center is more than a world class player. - - %global __os_install_post %{nil} - %prep - - %build - - %install - dpkg -x %{S:0} %{buildroot} - - %post -p /sbin/ldconfig - %postun -p /sbin/ldconfig - - %files - %{_bindir}/mediacenter$_mversion - %{_libdir}/jriver - %{_datadir} - %exclude %{_datadir}/applications/media_center_packageinstaller_$_mversion.desktop - /etc/security/limits.d/* - EOF - - declare -g _mcrpm="$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm" - - # skip rebuilding the rpm if it already exists - if [[ -f "$_mcrpm" ]]; then - echo "$_mcrpm already exists. Skipping build step..." - return 0 - else - # Run rpmbuild - echo "Building version $_mcversion, please wait..." - if [[ -v _debug ]]; then - rpmbuild --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec" + if debug; then + _installPackage "$_mcpkg-$_mcversion" else - rpmbuild --quiet --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec" > /dev/null 2>&1 - fi - - # Check return code - # shellcheck disable=SC2181 - if [[ $? -ne 0 || ! -f "$_mcrpm" ]]; then - err "Build failed. Exiting..." - exit 1 - else - echo "Build successful. The RPM file is located at: $_mcrpm" - fi - fi - } - - - ####################################### - # Copy the RPM to createrepo-webroot and runs createrepo as the createrepo-user - # Arguments: - # Requires one argument, the path to the RPM file (typically _mcrpm) - # Requires: - # _createrepo_webroot - # Returns: - # 0 if createrepo is successful, 1 if not - ####################################### - _runCreaterepo() { - debug "Running: ${FUNCNAME[0]}" - - _installPackage createrepo_c - - local _rpmfile="$1" - - # If the webroot does not exist, create it - if [[ ! -d "$_createrepo_webroot" ]]; then - if ! _cr_mkdir_cmd "$_createrepo_webroot"; then - err "Could not create the createrepo-webroot path!" - err "Make sure that the createrepo-webroot is writeable by createrepo-user" - return 1 - fi - fi - - # Copy built rpms to webroot - if ! _cr_cp_cmd -f "$_rpmfile" "$_createrepo_webroot"; then - err "Could not copy the RPM to the createrepo-webroot path" - err "Make sure that the createrepo-webroot path is writeable by createrepo-user" - return 1 - fi - - # Run createrepo - if _createrepo_cmd "$_createrepo_webroot"; then - echo "Successfully updated repo" - return 0 - else - err "Update repo failed" - return 1 - fi - } - - - ####################################### - # Symlink certificates where JRiver Media Center expects them to be on Fedora/CentOS - # Returns: - # 0 if symlinking is unecessary or successful, 1 if not - ####################################### - _symlinkCerts() { - debug "Running: ${FUNCNAME[0]}" - - if [[ ! -f /etc/ssl/certs/ca-certificates.crt && \ - -f /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem ]]; then - if ! _ln_cmd /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/ssl/certs/ca-certificates.crt; then - err "Symlinking certificates failed" - return 1 - fi - fi - } - - - ####################################### - # Automatically restore the mjr license file if it is found next to installJRMC or _restorefile - # is set - # Requires: - # _restorefile OR _basedir - # _mversion - # Returns: - # 0 if license restored successfully or skipped, 1 if unsuccessful - ####################################### - _restoreLicense() { - debug "Running: ${FUNCNAME[0]}" - - local _mjr - - # Allow user to drop an mjr file next to installJRMC - if [[ ! -v _restorefile ]]; then - for _mjr in "$_basedir"/*.mjr; do - [[ $_mjr -nt $_restorefile ]] && _restorefile="$_mjr" - done - fi - - # Restore license - if [[ -f "$_restorefile" ]]; then - if ! "mediacenter${_mversion}" /RestoreFromFile "$_restorefile"; then - err "Automatic license restore failed" - return 1 - fi - fi - } - - - ####################################### - # Opens ports using the system firewall tool - # Arguments - # Takes one argument, the pre-specified name of the service to enable - # Requires: - # ID - # _bash_cmd - # _firewall_cmd - # _port - # Returns: - # 0 if ports opened sucessfully, 1 if not - ####################################### - _openFirewall() { - debug "Running: ${FUNCNAME[0]}" "$@" - - # Create OS-specific port rules based on argument (service) name - local -a _f_ports # for firewall-cmd - local _u_ports # for ufw - if [[ "$1" == "jriver" ]]; then - _f_ports=("52100-52200/tcp" "1900/udp") - _u_ports="52100:52200/tcp|1900/udp" - elif [[ "$1" =~ ^(jriver-x11vnc|jriver-xvnc)$ ]]; then - _f_ports=("$_port/tcp") - _u_ports="$_port/tcp" - else - err "_openFirewall unrecognized service name" - exit 1 - fi - - # Open the ports - if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - [[ ! -x $(command -v firewall-cmd) ]] && _installPackage firewalld - if ! _firewall_cmd --get-services | grep -q "$1"; then - _firewall_cmd --permanent --new-service="$1" > /dev/null 2>&1 - _firewall_cmd --permanent --service="$1" --set-description="$1 installed by installJRMC" > /dev/null 2>&1 - _firewall_cmd --permanent --service="$1" --set-short="$1" > /dev/null 2>&1 - for _f_port in "${_f_ports[@]}"; do - _firewall_cmd --permanent --service="$1" --add-port="$_f_port" > /dev/null 2>&1 - done - _firewall_cmd --add-service "$1" --permanent > /dev/null 2>&1 - _firewall_cmd --reload > /dev/null 2>&1 + _installPackage "$_mcpkg-$_mcversion" > /dev/null 2>&1 fi elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - # Debian ufw package state is broken on fresh installations - [[ ! -x $(command -v ufw) ]] && _installPackage ufw - if [[ ! -f "/etc/ufw/applications.d/$1" ]]; then - _bash_cmd "cat <<- EOF > /etc/ufw/applications.d/$1 - [$1] - title=$1 - description=$1 installed by installJRMC - ports=$_u_ports - EOF" + if debug; then + _installPackage "$_mcpkg=$_mcversion" + else + _installPackage "$_mcpkg=$_mcversion" > /dev/null 2>&1 fi - _firewall_cmd app update "$1" - _firewall_cmd allow "$1" > /dev/null 2>&1 fi + else + if debug; then + _installPackage "$_mcpkg" + else + _installPackage "$_mcpkg" > /dev/null 2>&1 + fi + fi - # shellcheck disable=SC2181 - # Rationale: much more concise to check exit codes at the end - if [[ $? -ne 0 ]]; then - err "Firewall ports could not be opened" + # shellcheck disable=SC2181 + if [[ $? -ne 0 ]]; then + err "JRiver Media Center installation failed" + exit 1 + fi + + echo "JRiver Media Center installed successfully" +} + + +####################################### +# Acquire the source DEB package from JRiver's servers +# Returns: +# 0 if DEB file downloaded successfully, 1 if failed +####################################### +_acquireDeb() { + debug "Running: ${FUNCNAME[0]}" + + local _debfilename="$_outputdir/SOURCES/MediaCenter-$_mcversion-amd64.deb" + + # If necessary, create SOURCES dir + [[ ! -d "$_outputdir/SOURCES" ]] && mkdir -p "$_outputdir/SOURCES" + + # If deb file already exists, skip download + if [[ -f "$_debfilename" ]]; then + echo "Using local DEB file: $_debfilename" + # Else check beta repo + elif [[ -v _betapass ]]; then + if wget -q -O "$_debfilename" \ + "https://files.jriver.com/mediacenter/channels/v$_mversion/beta/$_betapass/MediaCenter-$_mcversion-amd64.deb"; then + true + fi + # Else check test repo + elif wget -q -O "$_debfilename" \ + "https://files.jriver.com/mediacenter/test/MediaCenter-$_mcversion-amd64.deb"; then + true + # Else check latest repo + elif wget -q -O "$_debfilename" \ + "https://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb"; then + true + else + err "Cannot find DEB file. Exiting..." + exit 1 + fi + + if [[ ! -f "$_debfilename" ]]; then + err "Downloaded DEB file missing or corrupted, exiting..." + exit 1 + fi +} + + +####################################### +# Creates a SPEC file and builds the RPM from the source DEB using rpmbuild +# Requires: +# _outputdir +# ID +# _mcversion +# _mversion +# _installPackage +# Globals: +# _mcrpm +# Returns: +# 0 if rpmbuild is successful, 1 if not +####################################### +_buildRPM() { + debug "Running: ${FUNCNAME[0]}" + + # install build dependencies + _installPackage wget dpkg rpm-build + + # If necessary, make build directories + [[ ! -d "$_outputdir/SPECS" ]] && mkdir -p "$_outputdir/SPECS" + + # rpmbuild uses rpm to check for build dependencies + # this will fail on non-rpm distros + if [[ "$ID" =~ ^(fedora|centos)$ ]]; then + local _build_requires=$'BuildRequires: rpm >= 4.11.0\nBuildRequires: dpkg' + fi + + # Create spec file + cat <<- EOF > "$_outputdir/SPECS/mediacenter.spec" + Name: MediaCenter + Version: $_mcversion + Release: 1 + Summary: JRiver Media Center + Group: Applications/Media + Source0: http://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb + ${_build_requires:-} + BuildArch: x86_64 + %define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm + + AutoReq: 0 + Requires: glibc >= 2.19 + Requires: alsa-lib >= 1.0.28 + Requires: libuuid >= 2.25 + Requires: libX11 >= 1.6 + Requires: libX11-common >= 1.6 + Requires: libXext >= 1.3 + Requires: libxcb >= 1.1 + Requires: libXdmcp >= 1.1 + Requires: libstdc++ >= 4.9 + Requires: gtk3 >= 3.14 + Requires: mesa-libGL + Requires: libglvnd-glx + Requires: pango >= 1.36 + Requires: libXScrnSaver + Requires: xdg-utils + Requires: libgomp >= 4.9 + Requires: nss >= 3.26 + Requires: nspr >= 4.12 + Requires: ca-certificates + Requires: python3 + Recommends: vorbis-tools >= 1.4.0 + Recommends: lame >= 3.0 + + Provides: mediacenter$_mversion + + License: Copyright 1998-2021, 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.*$ + + %description + Media Center is more than a world class player. + + %global __os_install_post %{nil} + %prep + + %build + + %install + dpkg -x %{S:0} %{buildroot} + + %post -p /sbin/ldconfig + %postun -p /sbin/ldconfig + + %files + %{_bindir}/mediacenter$_mversion + %{_libdir}/jriver + %{_datadir} + %exclude %{_datadir}/applications/media_center_packageinstaller_$_mversion.desktop + /etc/security/limits.d/* + EOF + + declare -g _mcrpm="$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm" + + # skip rebuilding the rpm if it already exists + if [[ -f "$_mcrpm" ]]; then + echo "$_mcrpm already exists. Skipping build step..." + return 0 + fi + + # Run rpmbuild + echo "Building version $_mcversion, please wait..." + if debug; then + rpmbuild --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec" + else + rpmbuild --quiet --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec" > /dev/null 2>&1 + fi + + # Check return code + # shellcheck disable=SC2181 + if [[ $? -ne 0 || ! -f "$_mcrpm" ]]; then + err "Build failed. Exiting..." + exit 1 + else + echo "Build successful. The RPM file is located at: $_mcrpm" + fi +} + + +####################################### +# Copy the RPM to createrepo-webroot and runs createrepo as the createrepo-user +# Arguments: +# Requires one argument, the path to the RPM file (typically _mcrpm) +# Requires: +# _createrepo_webroot +# Returns: +# 0 if createrepo is successful, 1 if not +####################################### +_runCreaterepo() { + debug "Running: ${FUNCNAME[0]}" + + # Some additional commands specifically for createrepo (primarily to handle user rights) + if [[ $_createrepo_user != "root" ]]; then + if [[ -d "$_createrepo_webroot/repodata" ]]; then + _createrepo_cmd(){ sudo -u "$_createrepo_user" createrepo -q --update "$@"; } + else + _createrepo_cmd(){ sudo -u "$_createrepo_user" createrepo -q "$@"; } + fi + _cr_mkdir_cmd(){ sudo -u "$_createrepo_user" mkdir -p "$@"; } + _cr_cp_cmd(){ sudo -u "$_createrepo_user" cp -n "$@"; } + else + if [[ -d "$_createrepo_webroot/repodata" ]]; then + _createrepo_cmd(){ createrepo -q --update "$@"; } + else + _createrepo_cmd(){ createrepo -q "$@"; } + fi + fi + + _installPackage createrepo_c + + local _rpmfile="$1" + + # If the webroot does not exist, create it + if [[ ! -d "$_createrepo_webroot" ]]; then + if ! _cr_mkdir_cmd "$_createrepo_webroot"; then + err "Could not create the createrepo-webroot path!" + err "Make sure that the createrepo-webroot is writeable by createrepo-user: $_createrepo_user" return 1 fi - } + fi + + # Copy built rpms to webroot + if ! _cr_cp_cmd -f "$_rpmfile" "$_createrepo_webroot"; then + err "Could not copy the RPM to the createrepo-webroot path" + err "Make sure that the createrepo-webroot path is writeable by createrepo-user: $_createrepo_user" + return 1 + fi + + # Run createrepo + if _createrepo_cmd "$_createrepo_webroot"; then + echo "Successfully updated repo" + return 0 + else + err "Update repo failed" + return 1 + fi +} - ####################################### - # Create the x11vnc password file - # Globals: - # _novncauth - # Returns: - # 0 if password created sucessfully, 1 if not - ####################################### - _setX11VNCPass() { - debug "Running: ${FUNCNAME[0]}" +####################################### +# Symlink certificates where JRiver Media Center expects them to be on Fedora/CentOS +# Returns: +# 0 if symlinking is unecessary or successful, 1 if not +####################################### +_symlinkCerts() { + debug "Running: ${FUNCNAME[0]}" - _vncpassfile="$HOME/.vnc/jrmc_passwd" - - [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}" - - if [[ -f "$_vncpassfile" ]]; then - if [[ ! -v _vncpass ]]; then - err "Refusing to overwrite existing $_vncpassfile with an empty password" - err "Remove existing $_vncpassfile or set --vncpass to use an empty password" - exit 1 - else - rm -f "$_vncpassfile" - fi + if [[ ! -f /etc/ssl/certs/ca-certificates.crt && \ + -f /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem ]]; then + if ! _ln_cmd /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/ssl/certs/ca-certificates.crt; then + err "Symlinking certificates failed" + return 1 fi + fi +} - if [[ -v _vncpass ]]; then - if ! x11vnc -storepasswd "$_vncpass" "$_vncpassfile"; then - err "Could not create VNC password file" - return 1 - fi + +####################################### +# Automatically restore the mjr license file if it is found next to installJRMC or _restorefile +# is set +# Requires: +# _restorefile OR _basedir +# _mversion +# Returns: +# 0 if license restored successfully or skipped, 1 if unsuccessful +####################################### +_restoreLicense() { + debug "Running: ${FUNCNAME[0]}" + + local _mjr + + # Allow user to drop an mjr file next to installJRMC + if [[ ! -v _restorefile ]]; then + for _mjr in "$PWD"/*.mjr; do + [[ $_mjr -nt $_restorefile ]] && _restorefile="$_mjr" + done + fi + + # Restore license + if [[ -f "$_restorefile" ]]; then + if ! "mediacenter$_mversion" /RestoreFromFile "$_restorefile"; then + err "Automatic license restore failed" + return 1 + fi + fi +} + + +####################################### +# Opens ports using the system firewall tool +# Arguments +# Service to enable (pre-defined) +# Requires: +# ID +# _bash_cmd +# _firewall_cmd +# _port +# Returns: +# 0 if ports opened sucessfully, 1 if not +####################################### +_openFirewall() { + debug "Running: ${FUNCNAME[0]}" "$@" + + # Create OS-specific port rules based on argument (service) name + local -a _f_ports # for firewall-cmd + local _u_ports # for ufw + if [[ "$1" == "jriver" ]]; then + _f_ports=("52100-52200/tcp" "1900/udp") + _u_ports="52100:52200/tcp|1900/udp" + elif [[ "$1" =~ ^(jriver-x11vnc|jriver-xvnc)$ ]]; then + _f_ports=("$_port/tcp" "1900/udp") + _u_ports="$_port/tcp|1900/udp" + fi + + # Open the ports + if [[ "$ID" =~ ^(fedora|centos)$ ]]; then + [[ ! -x $(command -v firewall-cmd) ]] && _installPackage firewalld + if ! _firewall_cmd --get-services | grep -q "$1"; then + _firewall_cmd --permanent --new-service="$1" > /dev/null 2>&1 + _firewall_cmd --permanent --service="$1" --set-description="$1 installed by installJRMC" > /dev/null 2>&1 + _firewall_cmd --permanent --service="$1" --set-short="$1" > /dev/null 2>&1 + for _f_port in "${_f_ports[@]}"; do + _firewall_cmd --permanent --service="$1" --add-port="$_f_port" > /dev/null 2>&1 + done + _firewall_cmd --add-service "$1" --permanent > /dev/null 2>&1 + _firewall_cmd --reload > /dev/null 2>&1 + fi + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then + # Debian ufw package state is broken on fresh installations + [[ ! -x $(command -v ufw) ]] && _installPackage ufw + if [[ ! -f "/etc/ufw/applications.d/$1" ]]; then + _bash_cmd "cat <<- EOF > /etc/ufw/applications.d/$1 + [$1] + title=$1 + description=$1 installed by installJRMC + ports=$_u_ports + EOF" + fi + _firewall_cmd app update "$1" + _firewall_cmd allow "$1" > /dev/null 2>&1 + fi + + # shellcheck disable=SC2181 + # Rationale: much more concise to check exit codes at the end + if [[ $? -ne 0 ]]; then + err "Firewall ports could not be opened" + return 1 + fi +} + + +####################################### +# Create the x11vnc password file +# Globals: +# _novncauth +# Returns: +# 0 if password created sucessfully, 1 if not +####################################### +_setX11VNCPass() { + debug "Running: ${FUNCNAME[0]}" + + _vncpassfile="$HOME/.vnc/jrmc_passwd" + + [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}" + + if [[ -f "$_vncpassfile" ]]; then + if [[ ! -v _vncpass ]]; then + err "Refusing to overwrite existing $_vncpassfile with an empty password" + err "Remove existing $_vncpassfile or set --vncpass to use an empty password" + exit 1 else - _novncauth="true" + rm -f "$_vncpassfile" fi - } + fi - - ####################################### - # Create the Xvnc password file - # Returns: - # 0 if password created sucessfully, 1 if not - ####################################### - _setVNCPass() { - debug "Running: ${FUNCNAME[0]}" - - _vncpassfile="$HOME/.vnc/jrmc_passwd" - - [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}" - - if [[ -f "$_vncpassfile" ]]; then - if [[ ! -v _vncpass ]]; then - err "Refusing to overwrite existing $_vncpassfile with an empty password" - err "Remove existing $_vncpassfile or set --vncpass to use an empty password" - exit 1 - else - rm -f "$_vncpassfile" - fi + if [[ -v _vncpass ]]; then + if ! x11vnc -storepasswd "$_vncpass" "$_vncpassfile"; then + err "Could not create VNC password file" + return 1 fi + else + _novncauth="true" + fi +} - if [[ -v _vncpass ]]; then - if ! echo "$_vncpass" | vncpasswd -f > "$_vncpassfile"; then - err "Could not create VNC password file" - return 1 - fi + +####################################### +# Create the Xvnc password file +# Returns: +# 0 if password created sucessfully, 1 if not +####################################### +_setVNCPass() { + debug "Running: ${FUNCNAME[0]}" + + _vncpassfile="$HOME/.vnc/jrmc_passwd" + + [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}" + + if [[ -f "$_vncpassfile" ]]; then + if [[ ! -v _vncpass ]]; then + err "Refusing to overwrite existing $_vncpassfile with an empty password" + err "Remove existing $_vncpassfile or set --vncpass to use an empty password" + exit 1 else - _novncauth="true" + rm -f "$_vncpassfile" fi - } + fi - - ####################################### - # Set display and port variables - # Globals: - # _display - # _displaynum - # _next_display - # _next_displaynum - ####################################### - _setDisplay() { - debug "Running: ${FUNCNAME[0]}" - - # Check _display, else DISPLAY, else set to :0 by default - if [[ -v _display ]]; then - _next_display="$_display" - elif [[ -v DISPLAY ]]; then - _display="${DISPLAY}" - _displaynum="${_display#:}" # strip colon - _displaynum="${_displaynum%.*}" # strip suffix - _next_displaynum=$(( _displaynum + 1 )) - _next_display=":$_next_displaynum" - else - _display=":0" - _next_display=":1" + if [[ -v _vncpass ]]; then + if ! echo "$_vncpass" | vncpasswd -f > "$_vncpassfile"; then + err "Could not create VNC password file" + return 1 fi + else + _novncauth="true" + fi +} + +####################################### +# Set display and port variables +# Globals: +# _display +# _displaynum +# _next_display +# _next_displaynum +####################################### +_setDisplay() { + debug "Running: ${FUNCNAME[0]}" + + # Check _display, else DISPLAY, else set to :0 by default + if [[ -v _display ]]; then + _next_display="$_display" + elif [[ -v DISPLAY ]]; then + _display="${DISPLAY}" _displaynum="${_display#:}" # strip colon _displaynum="${_displaynum%.*}" # strip suffix _next_displaynum=$(( _displaynum + 1 )) - } - - - ####################################### - # Create associated service variables based on service name - # Requires: - # _service_user - # Globals: - # _service_fname - # _timer_fname - # _service_name - # _timer_name - # _user_specifier - ####################################### - _servicePrep() { - debug "Running: ${FUNCNAME[0]}" - - if [[ "$_service_user" == "root" ]]; then - _service_fname="/usr/lib/systemd/system/${1}.service" - _timer_fname="/usr/lib/systemd/system/${1}.timer" - _service_name="jriver-${1}.service" - _timer_name="jriver-${1}}.timer" - _user_specifier="" - else - _service_fname="/usr/lib/systemd/system/${1}@.service" - _timer_fname="/usr/lib/systemd/system/${1}@.timer" - _service_name="${1}@$_service_user.service" - _timer_name="${1}@$_service_user.timer" - _user_specifier="User=%I" - fi - } - - - ####################################### - # SERVICES - ####################################### - - ####################################### - # Starts and enables (at startup) a JRiver Media Center service - # Arguments: - # Passes arguments as startup options to /usr/bin/mediacenter26 - # Requires: - # XAUTHORITY - ####################################### - _service_jriver-mediacenter() { - debug "Running: ${FUNCNAME[0]}" - - _bash_cmd "cat <<- EOF > $_service_fname - [Unit] - Description=JRiver Media Center $_mversion - After=graphical.target - - [Service] - $_user_specifier - Type=simple - Environment=DISPLAY=$_display - Environment=XAUTHORITY=$XAUTHORITY - ExecStart=/usr/bin/mediacenter$_mversion $* - Restart=always - RestartSec=10 - KillSignal=SIGHUP - TimeoutStopSec=30 - - [Install] - WantedBy=graphical.target - EOF" - _systemctl_reload && \ - _systemctl_start "$_service_name" && \ - _systemctl_enable "$_service_name" && \ - _openFirewall "jriver" - } - - - ####################################### - # Starts and enables (at startup) a JRiver Media Server service - ####################################### - _service_jriver-mediaserver() { - debug "Running: ${FUNCNAME[0]}" - - _service_jriver-mediacenter "/MediaServer" - } - - - ####################################### - # Starts and enables (at startup) JRiver Media Center in a new Xvnc session - ####################################### - _service_jriver-xvnc-mediacenter() { - debug "Running: ${FUNCNAME[0]}" - - _installPackage tigervnc-server - - _setVNCPass - - local _port=$(( _next_displaynum + 5900 )) - - if [[ -v _novncauth ]]; then - _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -name jriver$_next_display -SecurityTypes None -autokill -xstartup /usr/bin/mediacenter$_mversion" - else - _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -rfbauth $HOME/.vnc/jrmc_passwd -autokill -xstartup /usr/bin/mediacenter$_mversion" - fi - - _bash_cmd "cat <<- EOF > $_service_fname - [Unit] - Description=Remote desktop service (VNC) - After=syslog.target network.target - - [Service] - Type=simple - $_user_specifier - ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill $_next_display > /dev/null 2>&1 || :' - ExecStart=$_exec_start_cmd - ExecStop=/usr/bin/vncserver -kill $_next_display - Restart=always - - [Install] - WantedBy=multi-user.target - EOF" - - _systemctl_reload && \ - _systemctl_start "$_service_name" && \ - _systemctl_enable "$_service_name" && \ - echo "Xvnc running on localhost:$_port" && \ - _openFirewall "jriver-xvnc" && \ - _openFirewall "jriver" - } - - - ####################################### - # Starts and enables (at startup) JRiver Media Server and x11vnc sharing the local desktop - ####################################### - _service_jriver-x11vnc() { - debug "Running: ${FUNCNAME[0]}" - - _installPackage x11vnc - - _setX11VNCPass - - local _port=$(( _displaynum + 5900 )) - - # Get current desktop resolution - # TODO: may need to break this out into its own function and get smarter at identifying multi-monitors - _getResolution() { - - debug "Running: ${FUNCNAME[0]}" - - _installPackage xorg-x11-utils - _res=$(xdpyinfo | grep dimensions | awk '{print $2}') - } - _getResolution - - if [[ -v _novncauth ]]; then - _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -nopw" - else - _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -rfbauth $HOME/.vnc/jrmc_passwd" - fi - - _bash_cmd "cat <<-EOF > $_service_fname - [Unit] - Description=x11vnc - After=multi.service - - [Service] - $_user_specifier - Type=forking - Environment=DISPLAY=$_display - ExecStart=$_exec_start_cmd - Restart=always - RestartSec=10 - - [Install] - WantedBy=multi-user.target - EOF" - - _systemctl_reload && \ - _systemctl_start "$_service_name" && \ - _systemctl_enable "$_service_name" && \ - echo "x11vnc running on localhost:$_port" && \ - _openFirewall "jriver-x11vnc" - } - - - ####################################### - # Starts and enables (at startup) an hourly service to build the latest version of JRiver Media - # Center RPM from the source DEB and create/update an RPM repository - ####################################### - _service_jriver-createrepo() { - debug "Running: ${FUNCNAME[0]}" - - _bash_cmd "cat <<-EOF > $_service_fname - [Unit] - Description=Builds JRiver Media Center RPM file, moves it to the repo dir, and runs createrepo - - [Service] - $_user_specifier - ExecStart=$_basedir/installJRMC --outputdir $_outputdir --createrepo --createrepo-webroot $_createrepo_webroot --createrepo-user $_createrepo_user - - [Install] - WantedBy=default.target - EOF" - - _bash_cmd "cat <<-EOF > $_timer_fname - [Unit] - Description=Run JRiver MC rpmbuild hourly - - [Timer] - OnCalendar=hourly - Persistent=true - - [Install] - WantedBy=timers.target - EOF" - - _systemctl_reload && \ - _systemctl_start "$_timer_name" && \ - _systemctl_enable "$_timer_name" - } - - - ####################################### - # CONTAINERS - ####################################### - _containerCreaterepo() { - : - } - - - _containerVNC() { - : - } - - - _containerMC() { - : - } - - - ####################################### - # Complete uninstall - ####################################### - _uninstall() { - debug "Running: ${FUNCNAME[0]}" - - read -r -p "Do you really want to uninstall JRiver Media Center? [y/N] " _response - _response=${_response,,} # tolower - [[ ! "$_response" =~ ^(yes|y)$ ]] && echo "Cancelling uninstall..." && exit 0 - - # Uninstall services - echo "Stopping and removing all associated Media Center services" - for _service in "${_available_services[@]}"; do - _servicePrep "$_service" - _systemctl_disable "$_service_name" - _systemctl_disable "$_timer_name" - [[ -f "$_service_fname" ]] && _rm_cmd "$_service_fname" - [[ -f "$_timer_fname" ]] && _rm_cmd "$_timer_fname" - done - - echo "Removing repo files" - [[ -f "/etc/yum.repos.d/jriver.repo" ]] \ - && _rm_cmd "/etc/yum.repos.d/jriver.repo" - [[ -f "/etc/apt/sources.list.d/jriver.list" ]] \ - && _rm_cmd "/etc/apt/sources.list.d/jriver.list" - - echo "Removing firewall rules" - if [[ -x $(command -v firewall-cmd) ]]; then - _firewall_cmd --permanent --remove-service=jriver - _firewall_cmd --permanent --delete-service=jriver - _firewall_cmd --reload - elif [[ -x $(command -v ufw) ]]; then - _firewall_cmd delete allow jriver - [[ -f "/etc/ufw/applications.d/jriver" ]] \ - && _rm_cmd /etc/ufw/applications.d/jriver - fi - - echo "Uninstalling Media Center" - if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - _pkg_remove MediaCenter - elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then - _pkg_remove "mediacenter$_mversion" - fi - - echo "JRiver Media Center has been completely uninstalled" - echo "If you wish to remove your library files: rm -rf $HOME/.jriver" - echo "If you wish to remove your rpmbuild output files: rm -rf $_outputdir" - } - - - _main() { - - # Parse input - _parseInput "$@" - - # Sanity checks - _sanityChecks - - # Set user variables - _setUser - - # Build some OS-specific commands based on the selected OS - _buildCommands - - # Install MC using package manager - if [[ -v _repoinstall ]]; then - [[ "$ID" =~ ^(fedora|centos)$ ]] && _installPackage rpmfusion-free-release epel-release - _installMCFromRepo - _symlinkCerts - _restoreLicense - _openFirewall "jriver" - fi - - # Set version to install/uninstall - _setVersion - - # Uninstall and exit - if [[ -v _uninstall ]]; then - _uninstall - exit $? - fi - - # Build RPM from source DEB - if [[ -v _rpmbuild ]]; then - _installPackage epel-release - _acquireDeb - _buildRPM - fi - - # Run createrepo - if [[ -v _createrepo ]]; then - _runCreaterepo "$_mcrpm" - fi - - # Install the rpm - if [[ -v _rpminstall ]]; then - if [[ "$ID" =~ ^(fedora|centos)$ ]]; then - _installPackage rpmfusion-free-release epel-release - _installPackage --noquery "$_mcrpm" - _symlinkCerts - _restoreLicense - _openFirewall "jriver" - fi - fi - - # Install services - _setDisplay - for _service in "${_services[@]}"; do - _servicePrep "$_service" - "_service_$_service" - done - - # Install containers - for _container in "${_containers[@]}"; do - "_container_$_container" - done - } + _next_display=":$_next_displaynum" + else + _display=":0" + _next_display=":1" + fi + + _displaynum="${_display#:}" # strip colon + _displaynum="${_displaynum%.*}" # strip suffix + _next_displaynum=$(( _displaynum + 1 )) } -# Allow this file to be executed directly if not being sourced -if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - _basedir=$(dirname "$(readlink -f "$0")") - installJRMC - _main "$@" -fi + +####################################### +# Create associated service variables based on service name +# Requires: +# _service_user +# Globals: +# _service_fname +# _timer_fname +# _service_name +# _timer_name +# _user_specifier +####################################### +_servicePrep() { + debug "Running: ${FUNCNAME[0]}" + + if [[ "$_service_user" == "root" ]]; then + _service_fname="/usr/lib/systemd/system/${1}.service" + _timer_fname="/usr/lib/systemd/system/${1}.timer" + _service_name="jriver-${1}.service" + _timer_name="jriver-${1}}.timer" + _user_specifier="" + else + _service_fname="/usr/lib/systemd/system/${1}@.service" + _timer_fname="/usr/lib/systemd/system/${1}@.timer" + _service_name="${1}@$_service_user.service" + _timer_name="${1}@$_service_user.timer" + _user_specifier="User=%I" + fi +} + + +####################################### +# Starts and enables (at startup) a JRiver Media Center service +# Arguments: +# Passes arguments as startup options to /usr/bin/mediacenter26 +# Requires: +# XAUTHORITY +####################################### +_service_jriver-mediacenter() { + debug "Running: ${FUNCNAME[0]}" + + _bash_cmd "cat <<- EOF > $_service_fname + [Unit] + Description=JRiver Media Center $_mversion + After=graphical.target + + [Service] + $_user_specifier + Type=simple + Environment=DISPLAY=$_display + Environment=XAUTHORITY=$XAUTHORITY + ExecStart=/usr/bin/mediacenter$_mversion $* + Restart=always + RestartSec=10 + KillSignal=SIGHUP + TimeoutStopSec=30 + + [Install] + WantedBy=graphical.target + EOF" + + _systemctl_reload && \ + _systemctl_enable "$_service_name" && \ + _openFirewall "jriver" +} + + +####################################### +# Starts and enables (at startup) a JRiver Media Server service +####################################### +_service_jriver-mediaserver() { + debug "Running: ${FUNCNAME[0]}" + + _service_jriver-mediacenter "/MediaServer" +} + + +####################################### +# Starts and enables (at startup) JRiver Media Center in a new Xvnc session +####################################### +_service_jriver-xvnc-mediacenter() { + debug "Running: ${FUNCNAME[0]}" + + _installPackage tigervnc-server + + _setVNCPass + + local _port=$(( _next_displaynum + 5900 )) + + if [[ -v _novncauth ]]; then + _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -name jriver$_next_display -SecurityTypes None -autokill -xstartup /usr/bin/mediacenter$_mversion" + else + _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -rfbauth $HOME/.vnc/jrmc_passwd -autokill -xstartup /usr/bin/mediacenter$_mversion" + fi + + _bash_cmd "cat <<- EOF > $_service_fname + [Unit] + Description=Remote desktop service (VNC) + After=syslog.target network.target + + [Service] + Type=simple + $_user_specifier + ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill $_next_display > /dev/null 2>&1 || :' + ExecStart=$_exec_start_cmd + ExecStop=/usr/bin/vncserver -kill $_next_display + Restart=always + + [Install] + WantedBy=multi-user.target + EOF" + + _systemctl_reload && \ + _systemctl_enable "$_service_name" && \ + echo "Xvnc running on localhost:$_port" && \ + _openFirewall "jriver-xvnc" && \ + _openFirewall "jriver" +} + + +####################################### +# Starts and enables (at startup) JRiver Media Server and x11vnc sharing the local desktop +####################################### +_service_jriver-x11vnc() { + debug "Running: ${FUNCNAME[0]}" + + _installPackage x11vnc + + _setX11VNCPass + + local _port=$(( _displaynum + 5900 )) + + # Get current desktop resolution + # TODO: may need to break this out into its own function and get smarter at identifying multi-monitors + _getResolution() { + + debug "Running: ${FUNCNAME[0]}" + + _installPackage xorg-x11-utils + _res=$(xdpyinfo | grep dimensions | awk '{print $2}') + } + _getResolution + + if [[ -v _novncauth ]]; then + _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -nopw" + else + _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -rfbauth $HOME/.vnc/jrmc_passwd" + fi + + _bash_cmd "cat <<-EOF > $_service_fname + [Unit] + Description=x11vnc + After=multi.service + + [Service] + $_user_specifier + Type=forking + Environment=DISPLAY=$_display + ExecStart=$_exec_start_cmd + Restart=always + RestartSec=10 + + [Install] + WantedBy=multi-user.target + EOF" + + _systemctl_reload && \ + _systemctl_enable "$_service_name" && \ + echo "x11vnc running on localhost:$_port" && \ + _openFirewall "jriver-x11vnc" +} + + +####################################### +# Starts and enables (at startup) an hourly service to build the latest version of JRiver Media +# Center RPM from the source DEB and create/update an RPM repository +####################################### +_service_jriver-createrepo() { + debug "Running: ${FUNCNAME[0]}" + + _bash_cmd "cat <<-EOF > $_service_fname + [Unit] + Description=Builds JRiver Media Center RPM file, moves it to the repo dir, and runs createrepo + + [Service] + $_user_specifier + ExecStart=$PWD/installJRMC --outputdir $_outputdir --createrepo --createrepo-webroot $_createrepo_webroot --createrepo-user $_createrepo_user + + [Install] + WantedBy=default.target + EOF" + + _bash_cmd "cat <<-EOF > $_timer_fname + [Unit] + Description=Run JRiver MC rpmbuild hourly + + [Timer] + OnCalendar=hourly + Persistent=true + + [Install] + WantedBy=timers.target + EOF" + + _systemctl_reload && \ + _systemctl_enable "$_timer_name" +} + + +####################################### +# CONTAINERS +####################################### +_containerCreaterepo() { + : +} + + +_containerVNC() { + : +} + + +_containerMC() { + : +} + + +####################################### +# Complete uninstall +####################################### +_uninstall() { + debug "Running: ${FUNCNAME[0]}" + + read -r -p "Do you really want to uninstall JRiver Media Center? [y/N] " _response + _response=${_response,,} # tolower + [[ ! "$_response" =~ ^(yes|y)$ ]] && echo "Cancelling uninstall..." && exit 0 + + # Uninstall services + echo "Stopping and removing all associated Media Center services" + for _service in $(compgen -A "function" "_service"); do + _servicePrep "$_service" + _systemctl_disable "$_service_name" + _systemctl_disable "$_timer_name" + [[ -f "$_service_fname" ]] && _rm_cmd "$_service_fname" + [[ -f "$_timer_fname" ]] && _rm_cmd "$_timer_fname" + done + + echo "Removing repo files" + [[ -f "/etc/yum.repos.d/jriver.repo" ]] \ + && _rm_cmd "/etc/yum.repos.d/jriver.repo" + [[ -f "/etc/apt/sources.list.d/jriver.list" ]] \ + && _rm_cmd "/etc/apt/sources.list.d/jriver.list" + + echo "Removing firewall rules" + if [[ -x $(command -v firewall-cmd) ]]; then + _firewall_cmd --permanent --remove-service=jriver + _firewall_cmd --permanent --delete-service=jriver + _firewall_cmd --reload + elif [[ -x $(command -v ufw) ]]; then + _firewall_cmd delete allow jriver + [[ -f "/etc/ufw/applications.d/jriver" ]] \ + && _rm_cmd /etc/ufw/applications.d/jriver + fi + + echo "Uninstalling Media Center" + if [[ "$ID" =~ ^(fedora|centos)$ ]]; then + _pkg_remove MediaCenter + elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then + _pkg_remove "mediacenter$_mversion" + fi + + echo "JRiver Media Center has been completely uninstalled" + echo "If you wish to remove your library files: rm -rf $HOME/.jriver" + echo "If you wish to remove your rpmbuild output files: rm -rf $_outputdir" +} + + +_main "$@" From 9b8d8a302e5f05dbafd200ef256c89c688602463 Mon Sep 17 00:00:00 2001 From: bryan Date: Mon, 10 May 2021 18:02:04 -0400 Subject: [PATCH 11/19] Add support for legacy versions on Ubuntu/Debian --- installJRMC | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/installJRMC b/installJRMC index e341e5d..0f3cec5 100755 --- a/installJRMC +++ b/installJRMC @@ -492,9 +492,7 @@ _installMCFromRepo() { elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _installPackage wget wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | _ifSudo apt-key add - > /dev/null 2>&1 - _bash_cmd 'cat <<- EOF > /etc/apt/sources.list.d/jriver.list - deb [arch=amd64,i386,armhf] http://dist.jriver.com/latest/mediacenter/ buster main - EOF' + _ifSudo wget "http://dist.jriver.com/latest/mediacenter/mediacenter$mversion.list" -O "/etc/apt/sources.list.d/mediacenter$mversion.list" fi } _addRepo From 16fb94124fdfc43b1c99f2ee1a266385869309e0 Mon Sep 17 00:00:00 2001 From: bryan Date: Mon, 21 Jun 2021 09:10:29 -0400 Subject: [PATCH 12/19] Update for MC28 --- .gitignore | 1 + README.md | 36 +++++++-------- installJRMC | 127 +++++++++++++++++++++++++++++++++++----------------- 3 files changed, 103 insertions(+), 61 deletions(-) diff --git a/.gitignore b/.gitignore index e3d0e3d..043f248 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ testing.sh .lock tests +test-container.sh \ No newline at end of file diff --git a/README.md b/README.md index df18145..f49c067 100755 --- a/README.md +++ b/README.md @@ -11,36 +11,32 @@ This program will install [JRiver Media Center](https://www.jriver.com/) and ass `installJRMC [--option [ARGUMENT]]` -Running `installJRMC` without any options will install the latest version of JRiver 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 any other option is specified then the default install method will need to be specified using `--repo` or `--rpm`. This makes it possible to install services, containers, repos, etc. independent of Media Center. +Running `installJRMC` without any options will install the latest version of JRiver 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 any other option is specified, then the default install method will need to be specified using `--install`. This makes it possible to install services, containers, repos, etc. independent of Media Center. ## Options Here is a list of possible options that can be passed to the script. You can always find the latest supported options by running `installJRMC --help`. ```text ---repo - Install JRiver Media Center from repository using package manager - DEB-based OSes: Official package repository - RPM-based OSes: BryanC's unofficial repository ---rpm - Build RPM from source DEB and install it ---rpmbuild - Build RPM from source DEB but do not install ---outputdir PATH - Generate rpmbuild output in this directory (Default: $PWD/outputdir) +--install, -i repo|rpm + repo: Install MC from repository, future updates will be handled by the system package manager + rpm: Build and install MC locally (RPM-based OSes only) +--build + Build RPM from source DEB (no installation) --mcversion VERSION - Build or install a specific version (Default: install the latest version) + Build or install a specific MC version, ex. "28.0.25" +--outputdir PATH + Generate rpmbuild output in this directory (Default: $PWD/output) --restorefile RESTOREFILE - Restore file location for registration (Default: skip registration) + Restore file location for automatic license registration (Default: skip registration) --betapass PASSWORD Enter beta team password for access to beta builds --service-user USER - Install systemd services and containers for USER + Install systemd services and containers for USER (Default: current user) --service, -s SERVICE See SERVICES section below for a list of possible services to install ---container, -c CONTAINER +--container, -c CONTAINER (TODO: Under construction) See CONTAINERS section below for a list of possible services to install - TODO: Containers are a work-in-progress --createrepo Build rpm, copy to webroot, and run createrepo --createrepo-webroot PATH @@ -105,11 +101,11 @@ It is possible to install multiple services at one time using multiple `--servic Installs the latest version of JRiver Media Center from the repository. -* `installJRMC --repo --service jriver-mediaserver` +* `installJRMC --install repo --service jriver-mediaserver` Installs JRiver Media Center from the repository and starts/enables the /MediaServer service. -* `installJRMC --rpm --restorefile /path/to/license.mjr --mcversion 26.0.56` +* `installJRMC --install rpm --restorefile /path/to/license.mjr --mcversion 26.0.56` Builds JRiver Media Center version 26.0.56 RPM from the source DEB, installs it (RPM distros only), and activates it using the specified .mjr license file. @@ -121,11 +117,11 @@ It is possible to install multiple services at one time using multiple `--servic Installs the jriver-createrepo timer and service to build the RPM, move it to the webroot, and run createrepo as `www-user` hourly. -* `installJRMC --repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"` +* `installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"` Installs services to share the existing local desktop via VNC and automatically run Media Center on startup. -* `installJRMC --repo --service jriver-xvnc-mediacenter --display ":2"` +* `installJRMC --install repo --service jriver-xvnc-mediacenter --display ":2"` Installs an Xvnc server on display ':2' that starts Media Center. diff --git a/installJRMC b/installJRMC index 0f3cec5..193f3c9 100755 --- a/installJRMC +++ b/installJRMC @@ -12,8 +12,8 @@ shopt -s extglob # ####################################### -_scriptversion="0.9.6" -_boardurl="https://yabb.jriver.com/interact/index.php/board,67.0.html" +_scriptversion="1.0.0a1" +_boardurl="https://yabb.jriver.com/interact/index.php/board,71.0.html" _outputdir="$PWD/output" _createrepo_webroot="/srv/jriver" _exec_user="$(whoami)" @@ -25,23 +25,20 @@ _printHelpAndExit() { USAGE: installJRMC [[OPTION] [VALUE]]... - If no options (besides -d) are provided, the script will default to --repo + If no options (besides -d) are provided, the script will default to '--install repo' OPTIONS - --repo - Install JRiver Media Center from repository using package manager - DEB-based OSes: JRiver official package repository - RPM-based OSes: BryanC unofficial repository - --rpm - Build RPM from source DEB and install it - --rpmbuild + --install, -i repo|rpm + repo: Install JRiver Media Center from repository ('repo'), future updates will be handled by the system package manager + rpm: Build and install rpm file locally ('rpm') + --build Build RPM from source DEB (no installation) - --outputdir PATH - Generate rpmbuild output in this directory (Default: $PWD/outputdir) --mcversion VERSION Build or install a specific version (Default: install the latest version) + --outputdir PATH + Generate rpmbuild output in this directory (Default: $PWD/output) --restorefile RESTOREFILE - Restore file location for registration (Default: skip registration) + Restore file location for automatic license registration (Default: skip registration) --betapass PASSWORD Enter beta team password for access to beta builds --service-user USER @@ -133,8 +130,8 @@ _init() { # Set defaults if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then - debug "No options passed, defaulting to --repo installation method" - _repoinstall="true" + debug "No options passed, defaulting to repo installation method" + _install="repo" fi _service_user="${_service_user:-$_exec_user}" @@ -169,7 +166,7 @@ _main() { fi # Install MC using package manager - if [[ -v _repoinstall ]]; then + if [[ -v _install && "$_install" == "repo" ]]; then _installMCFromRepo _symlinkCerts _restoreLicense @@ -177,7 +174,7 @@ _main() { fi # Build RPM from source deb package - if [[ -v _rpmbuild ]]; then + if [[ -v _build ]]; then _acquireDeb _buildRPM fi @@ -188,7 +185,7 @@ _main() { fi # Install the rpm - if [[ -v _rpminstall ]]; then + if [[ -v _install && "$_install" == "rpm" ]]; then _installPackage --noquery "$_mcrpm" _symlinkCerts _restoreLicense @@ -256,22 +253,23 @@ _ifSudo() { _parseInput() { debug "Running: ${FUNCNAME[0]}" - if _input=$(getopt -o +vdhus:c: -l repo,rpm,rpmbuild,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then + if _input=$(getopt -o +i:vdhus:c: -l install,rpmbuild,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then eval set -- "$_input" while true; do case "$1" in - --repo) - _repoinstall="true" + --install|-i) + shift + _install="$1" + if [[ "$_install" == "rpm" ]]; then + if [[ ! "$ID" =~ ^(fedora|centos)$ ]]; then + err "RPM install method not available on $ID" + _printHelpAndExit 1 + fi + _build="true" + fi ;; - --rpm) - [[ ! "$ID" =~ ^(fedora|centos)$ ]] && \ - err "RPM installation not available on $ID" && \ - _printHelpAndExit 1 - _rpmbuild="true" - _rpminstall="true" - ;; - --rpmbuild) - _rpmbuild="true" + --build) + _build="true" ;; --outputdir) shift && _outputdir="$1" @@ -292,7 +290,7 @@ _parseInput() { shift && _services+=("$1") ;; --createrepo) - _rpmbuild="true" + _build="true" _createrepo="true" ;; --createrepo-webroot) @@ -492,7 +490,7 @@ _installMCFromRepo() { elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then _installPackage wget wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | _ifSudo apt-key add - > /dev/null 2>&1 - _ifSudo wget "http://dist.jriver.com/latest/mediacenter/mediacenter$mversion.list" -O "/etc/apt/sources.list.d/mediacenter$mversion.list" + _ifSudo wget "http://dist.jriver.com/latest/mediacenter/mediacenter$_mversion.list" -O "/etc/apt/sources.list.d/mediacenter$_mversion.list" fi } _addRepo @@ -1206,19 +1204,66 @@ _service_jriver-createrepo() { ####################################### # CONTAINERS ####################################### -_containerCreaterepo() { - : -} +# _containerCreaterepo() { +# : +# } -_containerVNC() { - : -} +# _containerVNC() { +# : +# } -_containerMC() { - : -} +# _containerMC() { +# _installPackage buildah podman +# cnt=$(buildah from docker.io/jlesage/baseimage-gui:debian-10) +# podman_create_cmd=("podman" "create" "--name" "$CNAME") +# buildah_config_cmd=("buildah" "config" \ +# "--author" "bryanroessler@gmail.com" \ +# "--label" "maintainer=$MAINTAINER" \ +# "--env" "TZ=$TZ" \ +# "--workingdir" "/app" \ +# "--cmd" "mediacenter$_mversion") + +# mkcdirs() { +# local dir +# for dir in "$@"; do +# if [[ ! -d "$dir" ]]; then +# if ! mkdir -p "$dir"; then +# err "Could not create directory $dir, check your permissions" +# fi +# fi +# if ! chcon -t container_file_t -R "$dir"; then +# err "Could not set container_file_t attribute for $dir, check your permissions" +# fi +# done +# } + +# mkcdirs "$HOME/.jriver" + +# podman_create_cmd+=("-v" "$HOME/.jriver:/root/.jriver") +# podman_create_cmd+=("-v" "$DOWNLOAD_ROOT:/downloads:z") +# podman_create_cmd+=("-v" "$MONITOR_ROOT/nzbs:/nzbs") +# podman_create_cmd+=("-p" "${CONTAINER[HOST_PORT]}:${CONTAINER[CONTAINER_PORT]}") + +# brc() { buildah run "$1" "${@:2}" || return 1; } + +# brc add-pkg gnupg2 libxss1 wmctrl xdotool ca-certificates inotify-tools libgbm1 + +# brc add-pkg --virtual .build-deps wget + +# brc sh -s <<- EOF +# wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | apt-key add - > /dev/null 2>&1 +# EOF + +# brc wget "http://dist.jriver.com/latest/mediacenter/mediacenter$_mversion.list" -O "/etc/apt/sources.list.d/mediacenter$_mversion.list" + +# brc apt-get update -y -q0 + +# brc add-pkg "mediacenter$_mversion" + +# brc del-pkg .build-deps +# } ####################################### From facae84e4fd1e16cd30806c5b524557d169a0fcb Mon Sep 17 00:00:00 2001 From: bryan Date: Mon, 21 Jun 2021 09:12:11 -0400 Subject: [PATCH 13/19] Fix derp --- installJRMC | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/installJRMC b/installJRMC index 193f3c9..f11d3c2 100755 --- a/installJRMC +++ b/installJRMC @@ -29,12 +29,12 @@ _printHelpAndExit() { OPTIONS --install, -i repo|rpm - repo: Install JRiver Media Center from repository ('repo'), future updates will be handled by the system package manager - rpm: Build and install rpm file locally ('rpm') + repo: Install MC from repository, future updates will be handled by the system package manager + rpm: Build and install MC locally (RPM-based OSes only) --build Build RPM from source DEB (no installation) --mcversion VERSION - Build or install a specific version (Default: install the latest version) + Build or install a specific MC version, ex. "28.0.25" --outputdir PATH Generate rpmbuild output in this directory (Default: $PWD/output) --restorefile RESTOREFILE @@ -253,7 +253,7 @@ _ifSudo() { _parseInput() { debug "Running: ${FUNCNAME[0]}" - if _input=$(getopt -o +i:vdhus:c: -l install,rpmbuild,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then + if _input=$(getopt -o +i:vdhus:c: -l install,build,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then eval set -- "$_input" while true; do case "$1" in From 5f65694f99cf03297ddc4912991849903f3059cb Mon Sep 17 00:00:00 2001 From: bryan Date: Mon, 21 Jun 2021 09:13:03 -0400 Subject: [PATCH 14/19] Fix getopt install --- installJRMC | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installJRMC b/installJRMC index f11d3c2..5fb2e75 100755 --- a/installJRMC +++ b/installJRMC @@ -253,7 +253,7 @@ _ifSudo() { _parseInput() { debug "Running: ${FUNCNAME[0]}" - if _input=$(getopt -o +i:vdhus:c: -l install,build,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then + if _input=$(getopt -o +i:vdhus:c: -l install:,build,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container: -- "$@"); then eval set -- "$_input" while true; do case "$1" in From c5e9037833e2419d4ce8d328da3f3e49eb0c326c Mon Sep 17 00:00:00 2001 From: bryan Date: Mon, 21 Jun 2021 09:26:14 -0400 Subject: [PATCH 15/19] Don't reprompt for wget install --- installJRMC | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installJRMC b/installJRMC index 5fb2e75..0d8bcfd 100755 --- a/installJRMC +++ b/installJRMC @@ -34,7 +34,7 @@ _printHelpAndExit() { --build Build RPM from source DEB (no installation) --mcversion VERSION - Build or install a specific MC version, ex. "28.0.25" + Build or install a specific MC version, ex. "28.0.25" (Default: scrape latest version from Interact) --outputdir PATH Generate rpmbuild output in this directory (Default: $PWD/output) --restorefile RESTOREFILE @@ -148,7 +148,7 @@ _init() { # Install script dependencies [[ "$ID" == "centos" ]] && _installPackage epel-release - [[ ! -v _mcversion ]] && _installPackage wget + [[ ! -v _mcversion ]] && [[ ! -x $(command -v wget) ]] && _installPackage wget # Set MC version _setVersion From 226a3deb0857f551e7b583da2d6ae74492a84cd3 Mon Sep 17 00:00:00 2001 From: bryan Date: Wed, 15 Sep 2021 14:10:14 -0400 Subject: [PATCH 16/19] Fix help dialog --- installJRMC | 108 ++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/installJRMC b/installJRMC index 0d8bcfd..15d8d4f 100755 --- a/installJRMC +++ b/installJRMC @@ -12,7 +12,7 @@ shopt -s extglob # ####################################### -_scriptversion="1.0.0a1" +_scriptversion="1.0.0a2" _boardurl="https://yabb.jriver.com/interact/index.php/board,71.0.html" _outputdir="$PWD/output" _createrepo_webroot="/srv/jriver" @@ -23,68 +23,68 @@ _printHelpAndExit() { cat <<- 'EOF' USAGE: - installJRMC [[OPTION] [VALUE]]... + installJRMC [[OPTION] [VALUE]]... - If no options (besides -d) are provided, the script will default to '--install repo' + If no options (besides -d) are provided, the script will default to '--install repo' OPTIONS - --install, -i repo|rpm - repo: Install MC from repository, future updates will be handled by the system package manager + --install, -i repo|rpm + repo: Install MC from repository, future updates will be handled by the system package manager rpm: Build and install MC locally (RPM-based OSes only) - --build - Build RPM from source DEB (no installation) - --mcversion VERSION - Build or install a specific MC version, ex. "28.0.25" (Default: scrape latest version from Interact) + --build + Build RPM from source DEB (no installation) + --mcversion VERSION + Build or install a specific MC version, ex. "28.0.25" (Default: scrape latest version from Interact) --outputdir PATH - Generate rpmbuild output in this directory (Default: $PWD/output) - --restorefile RESTOREFILE - Restore file location for automatic license registration (Default: skip registration) - --betapass PASSWORD - Enter beta team password for access to beta builds - --service-user USER - Install systemd services and containers for USER (Default: current user) - --service, -s SERVICE - See SERVICES section below for a list of possible services to install - --container, -c CONTAINER (TODO: Under construction) - See CONTAINERS section below for a list of possible services to install - --createrepo - Build rpm, copy to webroot, and run createrepo - --createrepo-webroot PATH - The webroot directory to install the repo (Default: /srv/jriver/) - --createrepo-user USER - The web server user (Default: current user) - --version, -v - Print this script version and exit - --debug, -d - Print debug output - --help, -h - Print help dialog and exit - --uninstall, -u - Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files) + Generate rpmbuild output in this directory (Default: $PWD/output) + --restorefile RESTOREFILE + Restore file location for automatic license registration (Default: skip registration) + --betapass PASSWORD + Enter beta team password for access to beta builds + --service-user USER + Install systemd services and containers for USER (Default: current user) + --service, -s SERVICE + See SERVICES section below for a list of possible services to install + --container, -c CONTAINER (TODO: Under construction) + See CONTAINERS section below for a list of possible services to install + --createrepo + Build rpm, copy to webroot, and run createrepo + --createrepo-webroot PATH + The webroot directory to install the repo (Default: /srv/jriver/) + --createrepo-user USER + The web server user (Default: current user) + --version, -v + Print this script version and exit + --debug, -d + Print debug output + --help, -h + Print help dialog and exit + --uninstall, -u + Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files) SERVICES - jriver-mediaserver - Enable and start a mediaserver systemd service (requires an existing X server) - jriver-mediacenter - Enable and start a mediacenter systemd service (requires an existing X server) - jriver-x11vnc - Enable and start x11vnc for the local desktop (requires an existing X server) - Usually combined with jriver-mediaserver or jriver-mediacenter services - --vncpass and --display are also valid options (see below) - jriver-xvnc-mediacenter - 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 use no password - --display DISPLAY - Display to start x11vnc/Xvnc (Default: The current display (x11vnc) or the - current display incremented by 1 (Xvnc)) - jriver-createrepo - Install hourly service to build latest MC RPM and run createrepo + jriver-mediaserver + Enable and start a mediaserver systemd service (requires an existing X server) + jriver-mediacenter + Enable and start a mediacenter systemd service (requires an existing X server) + jriver-x11vnc + Enable and start x11vnc for the local desktop (requires an existing X server) + Usually combined with jriver-mediaserver or jriver-mediacenter services + --vncpass and --display are also valid options (see below) + jriver-xvnc-mediacenter + 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 use no password + --display DISPLAY + Display to start x11vnc/Xvnc (Default: The current display (x11vnc) or the + current display incremented by 1 (Xvnc)) + jriver-createrepo + Install hourly service to build latest MC RPM and run createrepo CONTAINERS (TODO: Under construction) - mediacenter-xvnc - createrepo + mediacenter-xvnc + createrepo EOF # Exit using passed exit code From e2855aae9925862558c0bf7d0f5bf1111b6f8995 Mon Sep 17 00:00:00 2001 From: bryan Date: Wed, 15 Sep 2021 14:23:23 -0400 Subject: [PATCH 17/19] Final touches on help dialog --- installJRMC | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installJRMC b/installJRMC index 15d8d4f..d1687d4 100755 --- a/installJRMC +++ b/installJRMC @@ -30,12 +30,12 @@ _printHelpAndExit() { OPTIONS --install, -i repo|rpm repo: Install MC from repository, future updates will be handled by the system package manager - rpm: Build and install MC locally (RPM-based OSes only) + rpm: Build and install MC locally (RPM-based OSes only) --build Build RPM from source DEB (no installation) --mcversion VERSION Build or install a specific MC version, ex. "28.0.25" (Default: scrape latest version from Interact) - --outputdir PATH + --outputdir PATH Generate rpmbuild output in this directory (Default: $PWD/output) --restorefile RESTOREFILE Restore file location for automatic license registration (Default: skip registration) From 51b3281d21f4d1ccc7c139a4e27195cc6921c465 Mon Sep 17 00:00:00 2001 From: bryan Date: Wed, 15 Sep 2021 15:34:12 -0400 Subject: [PATCH 18/19] Echo upstream source repo --- installJRMC | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/installJRMC b/installJRMC index d1687d4..7bd267d 100755 --- a/installJRMC +++ b/installJRMC @@ -576,20 +576,19 @@ _acquireDeb() { # If deb file already exists, skip download if [[ -f "$_debfilename" ]]; then echo "Using local DEB file: $_debfilename" - # Else check beta repo elif [[ -v _betapass ]]; then + echo -n "Checking beta repo..." if wget -q -O "$_debfilename" \ "https://files.jriver.com/mediacenter/channels/v$_mversion/beta/$_betapass/MediaCenter-$_mcversion-amd64.deb"; then - true + echo "Found!" fi - # Else check test repo - elif wget -q -O "$_debfilename" \ + elif echo -n "Checking test repo..." && wget -q -O "$_debfilename" \ "https://files.jriver.com/mediacenter/test/MediaCenter-$_mcversion-amd64.deb"; then - true + echo "Found!" # Else check latest repo - elif wget -q -O "$_debfilename" \ + elif echo -n "Checking latest repo..." && wget -q -O "$_debfilename" \ "https://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb"; then - true + echo "Found!" else err "Cannot find DEB file. Exiting..." exit 1 From c3dda12f3519433e975870ceb8d2135b91b00c76 Mon Sep 17 00:00:00 2001 From: bryan Date: Wed, 15 Sep 2021 17:44:31 -0400 Subject: [PATCH 19/19] Remove source RPM if build fails --- installJRMC | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/installJRMC b/installJRMC index 7bd267d..bb83626 100755 --- a/installJRMC +++ b/installJRMC @@ -12,7 +12,7 @@ shopt -s extglob # ####################################### -_scriptversion="1.0.0a2" +_scriptversion="1.0.0a3" _boardurl="https://yabb.jriver.com/interact/index.php/board,71.0.html" _outputdir="$PWD/output" _createrepo_webroot="/srv/jriver" @@ -562,31 +562,34 @@ _installMCFromRepo() { ####################################### # Acquire the source DEB package from JRiver's servers +# Globals: +# DEBFILENAME # Returns: # 0 if DEB file downloaded successfully, 1 if failed ####################################### _acquireDeb() { debug "Running: ${FUNCNAME[0]}" - local _debfilename="$_outputdir/SOURCES/MediaCenter-$_mcversion-amd64.deb" + declare -g DEBFILENAME + DEBFILENAME="$_outputdir/SOURCES/MediaCenter-$_mcversion-amd64.deb" # If necessary, create SOURCES dir [[ ! -d "$_outputdir/SOURCES" ]] && mkdir -p "$_outputdir/SOURCES" # If deb file already exists, skip download - if [[ -f "$_debfilename" ]]; then - echo "Using local DEB file: $_debfilename" + if [[ -f "$DEBFILENAME" ]]; then + echo "Using local DEB file: $DEBFILENAME" elif [[ -v _betapass ]]; then echo -n "Checking beta repo..." - if wget -q -O "$_debfilename" \ + if wget -q -O "$DEBFILENAME" \ "https://files.jriver.com/mediacenter/channels/v$_mversion/beta/$_betapass/MediaCenter-$_mcversion-amd64.deb"; then echo "Found!" fi - elif echo -n "Checking test repo..." && wget -q -O "$_debfilename" \ + elif echo -n "Checking test repo..." && wget -q -O "$DEBFILENAME" \ "https://files.jriver.com/mediacenter/test/MediaCenter-$_mcversion-amd64.deb"; then echo "Found!" # Else check latest repo - elif echo -n "Checking latest repo..." && wget -q -O "$_debfilename" \ + elif echo -n "Checking latest repo..." && wget -q -O "$DEBFILENAME" \ "https://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb"; then echo "Found!" else @@ -594,7 +597,7 @@ _acquireDeb() { exit 1 fi - if [[ ! -f "$_debfilename" ]]; then + if [[ ! -f "$DEBFILENAME" ]]; then err "Downloaded DEB file missing or corrupted, exiting..." exit 1 fi @@ -714,6 +717,8 @@ _buildRPM() { # shellcheck disable=SC2181 if [[ $? -ne 0 || ! -f "$_mcrpm" ]]; then err "Build failed. Exiting..." + echo "Removing source DEB" + [[ -f "$DEBFILENAME" ]] && rm -f "$DEBFILENAME" exit 1 else echo "Build successful. The RPM file is located at: $_mcrpm"