installJRMC 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. #!/usr/bin/env bash
  2. # This script will download, build, and install JRiver Media Center with optional systemd services
  3. # on Fedora, CentOS, Debian, and Ubuntu
  4. #
  5. # To-dos:
  6. # 1. Raspberry Pi support -- do not own one so difficult to test
  7. # 2. Arch support -- would love some testing and PRs
  8. # 3. ncurses graphical installer
  9. shopt -s extglob
  10. installJRMC () {
  11. ########################
  12. ####### DEFAULTS #######
  13. ########################
  14. _scriptversion="0.1"
  15. [[ -z "$_boardurl" ]] && \
  16. _boardurl="https://yabb.jriver.com/interact/index.php/board,64.0.html"
  17. [[ -z "$_outputdir" ]] && \
  18. _outputdir="$_basedir/output"
  19. [[ -z $_createrepo_webroot ]] && \
  20. _createrepo_webroot="/srv/jriver"
  21. [[ -z $_createrepo_user ]] && \
  22. _createrepo_user="$(whoami)"
  23. [[ -z $_user ]] && \
  24. _user="$(whoami)"
  25. [[ -z $_display ]] && \
  26. _display="${DISPLAY:-":0"}"
  27. ########################
  28. ###### FUNCTIONS #######
  29. ########################
  30. _printHelpAndExit () {
  31. _runDebug "${FUNCNAME[0]}"
  32. cat <<-'EOF'
  33. USAGE:
  34. installJRMC [[OPTION] [VALUE]]...
  35. OPTIONS
  36. --rpmbuild
  37. Debian/Ubuntu: Build RPM from source DEB
  38. Fedora/CentOS: Build RPM from source DEB and install it
  39. --outputdir PATH
  40. Generate rpmbuild output in this directory (Default: $PWD/outputdir)
  41. --mcversion VERSION
  42. Build or install a specific version (Default: scrape the latest version from Interact)
  43. --restorefile RESTOREFILE
  44. Restore file location for registration (Default: skip registration)
  45. --betapass PASSWORD
  46. Enter beta team password for access to beta builds
  47. --service SERVICE
  48. See SERVICES section below for a list of possible service to install
  49. -v|--version
  50. Print this script version and exit
  51. -d|--debug
  52. Enter debug mode
  53. -h|--help
  54. Print help dialog and exit
  55. -u|--uninstall
  56. Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove
  57. library files)
  58. CREATEREPO
  59. --createrepo
  60. Build rpm, copy to webroot, and run createrepo
  61. --createrepo-webroot PATH
  62. The webroot directory to install the repo (Default: /srv/jriver/)
  63. --createrepo-user USER
  64. The web server user (Default: current user)
  65. SERVICES
  66. mediaserver
  67. Create and enable a JRiver MC Media Server systemd service for the current user
  68. x11vnc-mediaserver
  69. Create and enable a JRiver MC mediaserver service and x11vnc (for headless
  70. installations without an existing X server) service for the current user
  71. --vncpass PASSWORD
  72. Set vnc password for x11vnc access. If no password is set, the script will either use
  73. existing password stored in ~/.vnc/jrmc_passwd or use no password
  74. --display DISPLAY
  75. Start X11VNC on this display (Default: The current display or :0 if current display is
  76. unaccessible)
  77. createrepo
  78. Install service to build latest MC RPM and run createrepo hourly for the current user
  79. EOF
  80. # Exit using passed exit code
  81. [[ -z $1 ]] && exit 0 || exit "$1"
  82. }
  83. _parseInput () {
  84. _runDebug "${FUNCNAME[0]}"
  85. if _input=$(getopt -o +vdhu -l rpmbuild,outputdir:,mcversion:,restorefile:,betapass:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display: -- "$@"); then
  86. eval set -- "$_input"
  87. while true; do
  88. case "$1" in
  89. --rpmbuild)
  90. _rpmbuild="true"
  91. ;;
  92. --outputdir)
  93. shift && _outputdir="$1"
  94. ;;
  95. --mcversion)
  96. shift && _mcversion="$1"
  97. ;;
  98. --restorefile)
  99. shift && _restorefile="$1"
  100. ;;
  101. --betapass)
  102. shift && _betapass="$1"
  103. ;;
  104. --service)
  105. shift && _service="$1"
  106. ;;
  107. --version|-v)
  108. echo "Version: $_scriptversion"
  109. exit 0
  110. ;;
  111. --debug|-d)
  112. echo "Debugging on"
  113. _debug="true"
  114. ;;
  115. --help|-h)
  116. _printHelpAndExit 0
  117. ;;
  118. --uninstall|-u)
  119. _uninstall="true"
  120. ;;
  121. --createrepo)
  122. _createrepo="true"
  123. ;;
  124. --createrepo-webroot)
  125. shift && _createrepo_webroot="$1"
  126. ;;
  127. --createrepo-user)
  128. shift && _createrepo_user="$1"
  129. ;;
  130. --vncpass)
  131. shift && _vncpass="$1"
  132. ;;
  133. --display)
  134. shift && _display="$1"
  135. ;;
  136. --)
  137. shift
  138. break
  139. ;;
  140. esac
  141. shift
  142. done
  143. else
  144. echo "Incorrect options provided"
  145. _printHelpAndExit 1
  146. fi
  147. }
  148. _runDebug () {
  149. [[ -n $_debug ]] && echo "Running: " "$@"
  150. }
  151. _checkUser () {
  152. _runDebug "${FUNCNAME[0]}"
  153. if [[ "$_user" == "root" ]]; then
  154. cat <<EOF
  155. Warning! You are currently running installJRMC as the root user. This is not recommended! When
  156. running as a regular user, installJRMC will ask you for your sudo password when necessary.
  157. Installation will continue but any systemd services will be installed as system services and you
  158. may run into permissions issues.
  159. EOF
  160. else
  161. [[ -n $_debug ]] && echo "Installing as user: $_user"
  162. fi
  163. }
  164. _getOS () {
  165. _runDebug "${FUNCNAME[0]}"
  166. if [[ -e /etc/os-release ]]; then
  167. source /etc/os-release
  168. else
  169. echo "No /etc/os-release found!"
  170. echo "Your OS is unsupported"
  171. _printHelpAndExit 1
  172. fi
  173. [[ -n $_debug ]] && echo "Platform: $ID $VERSION_ID"
  174. }
  175. _buildCommands () {
  176. _runDebug "${FUNCNAME[0]}"
  177. # build some basic command arrays based on OS and user input
  178. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  179. _install_cmd=("dnf" "install" "-y")
  180. _update_cmd=("dnf" "makecache" "-y")
  181. _pkg_query_cmd=("rpm" "-q")
  182. _firewall_cmd=("firewall-cmd")
  183. elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then
  184. _install_cmd=("apt-get" "install" "-y")
  185. _update_cmd=("apt-get" "update" "-y")
  186. _pkg_query_cmd=("dpkg" "-l")
  187. _firewall_cmd=("ufw")
  188. fi
  189. _bash_cmd=("bash" "-c")
  190. _rm_cmd=("rm" "-rf")
  191. _install_cmd_nogpg=("${_install_cmd[@]}" "--nogpgcheck")
  192. # append sudo for non-root users
  193. if [[ "$_user" != "root" ]]; then
  194. _install_cmd=("sudo" "${_install_cmd[@]}")
  195. _install_cmd_nogpg=("sudo" "${_install_cmd_nogpg[@]}")
  196. _update_cmd=("sudo" "${_update_cmd[@]}")
  197. _bash_cmd=("sudo" "${_bash_cmd[@]}")
  198. _rm_cmd=("sudo" "${_rm_cmd[@]}")
  199. _firewall_cmd=("sudo" "${_firewall_cmd[@]}")
  200. #_pkg_query_cmd=("sudo" "${_pkg_query_cmd[@]}")
  201. fi
  202. [[ -n $_debug ]] && \
  203. echo "Install command: " "${_install_cmd[@]}" && \
  204. echo "Update command: " "${_update_cmd[@]}" && \
  205. echo "Bash command: " "${_bash_cmd[@]}" && \
  206. echo "Package query command: " "${_pkg_query_cmd[@]}"
  207. }
  208. _installPackage () {
  209. _runDebug "${FUNCNAME[0]}" "$@"
  210. # We will add packages to this array if their command is not available
  211. local -a _pkg_array
  212. local -a _url_pkg_array
  213. # parse commands
  214. for _pkg in "$@"; do
  215. # Clean up package name and handle OS-specific tweaks
  216. _packageQuirks "$_pkg"
  217. # Insert the package name to test if already installed
  218. if [[ "$_pkg" != "" ]] && ! "${_pkg_query_cmd[@]}" "$_pkg" > /dev/null 2>&1; then
  219. if [[ -n $_url_pkg ]]; then
  220. _url_pkg_array+=("$_url_pkg")
  221. else
  222. _pkg_array+=("$_pkg")
  223. fi
  224. fi
  225. done
  226. if [[ ${#_pkg_array[@]} -ge 1 ]]; then
  227. echo "Installing: " "${_pkg_array[@]}"
  228. "${_install_cmd[@]}" "${_pkg_array[@]}" > /dev/null 2>&1
  229. fi
  230. if [[ ${#_url_pkg_array[@]} -ge 1 ]]; then
  231. echo "Installing: " "${_url_pkg_array[@]}"
  232. "${_install_cmd_nogpg[@]}" "${_url_pkg_array[@]}" > /dev/null 2>&1
  233. fi
  234. }
  235. _packageQuirks () {
  236. _runDebug "${FUNCNAME[0]}" "$@"
  237. unset _url_pkg
  238. if [[ "$1" == "rpm-build" && "$ID" =~ ^(ubuntu|debian)$ ]]; then
  239. _pkg="rpm"
  240. elif [[ "$1" == "createrepo_c" && "$ID" =~ ^(ubuntu|debian)$ ]]; then
  241. _pkg="createrepo"
  242. elif [[ "$1" == "rpmfusion-free-release" ]]; then
  243. if [[ "$ID" == "fedora" ]]; then
  244. _url_pkg="https://download1.rpmfusion.org/free/$ID/rpmfusion-free-release-$VERSION_ID.noarch.rpm"
  245. _pkg="$1"
  246. elif [[ "$ID" == "centos" ]]; then
  247. _url_pkg="https://download1.rpmfusion.org/free/el/rpmfusion-free-release-$VERSION_ID.noarch.rpm"
  248. _pkg="$1"
  249. else
  250. _pkg=""
  251. fi
  252. elif [[ "$1" == "epel-release" && "$ID" != "centos" ]]; then
  253. _pkg=""
  254. else
  255. _pkg="$1"
  256. fi
  257. }
  258. _setVersion () {
  259. _runDebug "${FUNCNAME[0]}"
  260. if [[ -z "$_mcversion" ]]; then
  261. _installPackage wget
  262. # Get latest version from Interact
  263. echo -n "Scraping latest MC version number from Interact..."
  264. if ! _mcversion=$(wget -qO- "$_boardurl" | grep -o "[0-9][0-9]\.[0-9]\.[0-9]\+" | head -n 1); then
  265. echo "MC version could not be scraped. Please specify a version manually using --mcversion or check your --boardurl"
  266. fi
  267. fi
  268. if [[ "$_mcversion" =~ ^[0-9]+.[0-9].[0-9]+ ]]; then
  269. echo "$_mcversion"
  270. else
  271. echo "MC version: $_mcversion could not be parsed!"
  272. _printHelpAndExit 1
  273. fi
  274. # Extract major and variation version numbers
  275. _mversion="${_mcversion%%.*}"
  276. #_variation="${_mcversion##*.}"
  277. }
  278. _sanityChecks () {
  279. _runDebug "${FUNCNAME[0]}"
  280. # Cannot create a repo without an rpm
  281. if [[ -n $_createrepo || "$_service" == "createrepo" ]]; then
  282. _rpmbuild="true"
  283. fi
  284. # Check for bad service name
  285. if [[ -n $_service && ! "$_service" =~ ^(mediaserver|x11vnc-mediaserver|createrepo)$ ]]; then
  286. echo "Incorrect service type provided!"
  287. _printHelpAndExit 1
  288. fi
  289. }
  290. _installExternalRepos () {
  291. _runDebug "${FUNCNAME[0]}"
  292. _installPackage rpmfusion-free-release epel-release
  293. }
  294. _installRepo () {
  295. _runDebug "${FUNCNAME[0]}"
  296. _installPackage wget gnupg
  297. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  298. "${_bash_cmd[@]}" 'cat <<-EOF > /etc/yum.repos.d/jriver.repo
  299. [jriver]
  300. name=JRiver Media Center repo by BryanC
  301. baseurl=https://repos.bryanroessler.com/jriver
  302. gpgcheck=0
  303. EOF'
  304. [[ -n $_debug ]] && cat /etc/yum.repos.d/jriver.repo
  305. echo "Installing latest JRiver Media Center from repo..."
  306. if "${_update_cmd[@]}" && "${_install_cmd[@]}" MediaCenter > /dev/null 2>&1; then
  307. echo "JRiver Media Center installed successfully!"
  308. echo "You can check for future MC updates by running \"sudo dnf update\""
  309. else
  310. echo "JRiver Media Center installation failed!"
  311. _printHelpAndExit 1
  312. fi
  313. elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then
  314. if [[ $_user != "root" ]]; then
  315. wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | sudo apt-key add - > /dev/null 2>&1
  316. sudo wget "http://dist.jriver.com/latest/mediacenter/mediacenter$_mversion.list" -O "/etc/apt/sources.list.d/jriver.list" > /dev/null 2>&1
  317. else
  318. wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | apt-key add - > /dev/null 2>&1
  319. wget "http://dist.jriver.com/latest/mediacenter/mediacenter$_mversion.list" -O "/etc/apt/sources.list.d/jriver.list" > /dev/null 2>&1
  320. fi
  321. [[ -n $_debug ]] && cat "/etc/apt/sources.list.d/jriver.list"
  322. echo "Installing JRiver Media Center from repo..."
  323. if "${_update_cmd[@]}" > /dev/null 2>&1 && "${_install_cmd[@]}" "mediacenter$_mversion" > /dev/null 2>&1; then
  324. echo "JRiver Media Center installed successfully!"
  325. echo "You can check for future MC updates by running \"apt-get update && apt-get dist-upgrade\""
  326. else
  327. echo "JRiver Media Center installation failed!"
  328. _printHelpAndExit 1
  329. fi
  330. fi
  331. }
  332. _acquireDeb () {
  333. _runDebug "${FUNCNAME[0]}"
  334. # If necessary, create SOURCES dir
  335. [[ ! -d "$_outputdir/SOURCES" ]] && mkdir -p "$_outputdir/SOURCES"
  336. # If deb file already exists, skip download
  337. if [[ -f "$_outputdir/SOURCES/MediaCenter-${_mcversion}-amd64.deb" ]]; then
  338. echo "Using local DEB file: $_outputdir/SOURCES/MediaCenter-${_mcversion}-amd64.deb"
  339. # Else check beta repo
  340. elif [[ -n $_betapass ]]; then
  341. if wget -q -O "$_outputdir/SOURCES/MediaCenter-${_mcversion}-amd64.deb" \
  342. "https://files.jriver.com/mediacenter/channels/v${_mversion}/beta/${_betapass}/MediaCenter-${_mcversion}-amd64.deb"; then
  343. true
  344. fi
  345. # Else check test repo
  346. elif wget -q -O "$_outputdir/SOURCES/MediaCenter-${_mcversion}-amd64.deb" \
  347. "https://files.jriver.com/mediacenter/test/MediaCenter-${_mcversion}-amd64.deb"; then
  348. true
  349. # Else check latest repo
  350. elif wget -q -O "$_outputdir/SOURCES/MediaCenter-${_mcversion}-amd64.deb" \
  351. "https://files.jriver.com/mediacenter/channels/v${_mversion}/latest/MediaCenter-${_mcversion}-amd64.deb"; then
  352. true
  353. else
  354. echo "Cannot find DEB file. Exiting..." && exit 1
  355. fi
  356. if [[ ! -f "$_outputdir/SOURCES/MediaCenter-${_mcversion}-amd64.deb" ]]; then
  357. echo "Downloaded DEB file missing or corrupted, exiting..."
  358. exit 1
  359. fi
  360. }
  361. _buildRPM () {
  362. _runDebug "${FUNCNAME[0]}"
  363. # install build dependencies
  364. _installPackage wget dpkg rpm-build
  365. # If necessary, make build directories
  366. [[ ! -d "$_outputdir/SPECS" ]] && mkdir -p "$_outputdir/SPECS"
  367. # rpmbuild uses rpm to check for build dependencies
  368. # this will fail on non-rpm distros
  369. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  370. _build_requires=$'BuildRequires: rpm >= 4.11.0\nBuildRequires: dpkg'
  371. else
  372. _build_requires=''
  373. fi
  374. if [[ "$ID" == "centos" ]]; then
  375. _requires='Requires: pangox-compat >= 0.0.2'
  376. else
  377. _requires=''
  378. fi
  379. # Create spec file
  380. bash -c "cat <<EOF > $_outputdir/SPECS/mediacenter.spec
  381. Name: MediaCenter
  382. Version: $_mcversion
  383. Release: 1
  384. Summary: JRiver Media Center
  385. Group: Applications/Media
  386. Source0: http://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb
  387. $_build_requires
  388. BuildArch: x86_64
  389. %define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm
  390. AutoReq: 0
  391. Requires: glibc >= 2.19
  392. Requires: alsa-lib >= 1.0.28
  393. Requires: libuuid >= 2.25
  394. Requires: libX11 >= 1.6
  395. Requires: libX11-common >= 1.6
  396. Requires: libXext >= 1.3
  397. Requires: libxcb >= 1.1
  398. Requires: libXdmcp >= 1.1
  399. Requires: libstdc++ >= 4.9
  400. Requires: gtk3 >= 3.14
  401. Requires: mesa-libGL
  402. Requires: libglvnd-glx
  403. Requires: pango >= 1.36
  404. $_requires
  405. Requires: xdg-utils
  406. Requires: libgomp >= 4.9
  407. Requires: gstreamer1 >= 1.4.4
  408. Requires: gstreamer1-plugins-base >= 1.4.4
  409. Requires: nss >= 3.26
  410. Requires: nspr >= 4.12
  411. Requires: ca-certificates
  412. Requires: python3
  413. Recommends: vorbis-tools >= 1.4.0
  414. Provides: mediacenter$_mversion
  415. License: Copyright 1998-2020, JRiver, Inc. All rights reserved. Protected by U.S. patents #7076468 and #7062468
  416. URL: http://www.jriver.com/
  417. %description
  418. Media Center is more than a world class player.
  419. %global __os_install_post %{nil}
  420. %prep
  421. %build
  422. %install
  423. dpkg -x %{S:0} %{buildroot}
  424. %post -p /sbin/ldconfig
  425. %postun -p /sbin/ldconfig
  426. %files
  427. %{_bindir}/mediacenter$_mversion
  428. %{_libdir}/jriver
  429. %{_datadir}
  430. /etc/security/limits.d/*
  431. EOF"
  432. # skip rebuilding the rpm if it already exists
  433. if [[ -f "$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm" ]]; then
  434. echo "$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm already exists! Skipping build step..."
  435. else
  436. # Run rpmbuild
  437. echo "Building version $_mcversion, please wait..."
  438. if rpmbuild --quiet --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec"; then
  439. echo "Build complete!"
  440. echo "The RPM is located at $_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm"
  441. else
  442. echo "Build failed! Exiting..."
  443. exit 1
  444. fi
  445. fi
  446. }
  447. _runCreateRepo () {
  448. _runDebug "${FUNCNAME[0]}"
  449. _installPackage createrepo_c
  450. unset _prefix
  451. if [[ $_createrepo_user != "root" ]]; then
  452. _prefix=("sudo" "-u" "$_createrepo_user")
  453. fi
  454. _createrepo_cmd=("createrepo" "-q")
  455. # If the webroot does not exist, create it
  456. if [[ ! -d "$_createrepo_webroot" ]]; then
  457. if ! "${_prefix[@]}" mkdir -p "$_createrepo_webroot"; then
  458. echo "Could not create the createrepo-webroot path!"
  459. echo "Make sure that the createrepo-webroot is writeable by createrepo-user!"
  460. fi
  461. fi
  462. # Copy built rpms to webroot
  463. if "${_prefix[@]}" cp -n "$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm" "$_createrepo_webroot"; then
  464. echo "Copied $_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm to $_createrepo_webroot/MediaCenter-$_mcversion.x86_64.rpm"
  465. else
  466. echo "Could not copy the RPM to the createrepo-webroot path!"
  467. echo "Make sure that the createrepo-webroot path is writeable by createrepo-user!"
  468. fi
  469. # If repodata exists, append --update to createrepo command
  470. [[ -d "$_createrepo_webroot/repodata" ]] && _createrepo_cmd+=("--update")
  471. # Run createrepo
  472. if "${_prefix[@]}" "${_createrepo_cmd[@]}" "$_createrepo_webroot"; then
  473. echo "Successfully updated repo!"
  474. else
  475. echo "Update repo failed!"
  476. return 1
  477. fi
  478. }
  479. _installRPM () {
  480. _runDebug "${FUNCNAME[0]}"
  481. # skip installing same version
  482. _installed_ver="$(rpm --query MediaCenter)"
  483. _to_be_installed_ver="MediaCenter-$_mcversion.x86_64"
  484. if [[ $_installed_ver == "$_to_be_installed_ver" ]]; then
  485. echo "JRiver Media Center $_mcversion is already installed! Skipping installation..."
  486. return
  487. fi
  488. # install rpm
  489. if [[ -f "$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm" ]]; then
  490. echo "Attempting to install version $_mcversion..."
  491. if "${_install_cmd[@]}" "$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm"; then
  492. echo "JRiver Media Center $_mcversion was installed successfully!"
  493. else
  494. echo "JRiver Media Center $_mcversion installation failed!"
  495. exit 1
  496. fi
  497. else
  498. echo "$_outputdir/RPMS/x86_64/MediaCenter-${_mcversion}.x86_64.rpm is missing!"
  499. echo "JRiver Media Center ${_mcversion} installation failed!"
  500. exit 1
  501. fi
  502. }
  503. _symlinkCerts () {
  504. _runDebug "${FUNCNAME[0]}"
  505. if [[ ! -f /etc/ssl/certs/ca-certificates.crt && \
  506. -f /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem ]]; then
  507. echo "Symlinking /etc/ssl/certs/ca-certificates.crt to /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"
  508. if [[ "$_user" == "root" ]]; then
  509. ln -s /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/ssl/certs/ca-certificates.crt
  510. else
  511. sudo ln -s /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/ssl/certs/ca-certificates.crt
  512. fi
  513. fi
  514. }
  515. _restoreLicense () {
  516. _runDebug "${FUNCNAME[0]}"
  517. # Allow user to drop an mjr file next to installJRMC
  518. if [[ -z $_restorefile ]]; then
  519. for _mjr in "$_basedir"/*.mjr; do
  520. [[ $_mjr -nt $_restorefile ]] && _restorefile="$_mjr"
  521. done
  522. fi
  523. # Restore license
  524. if [[ -f "$_restorefile" ]]; then
  525. if ! "mediacenter${_mversion}" /RestoreFromFile "$_restorefile"; then
  526. echo "Automatic license restore failed"
  527. fi
  528. fi
  529. }
  530. _openFirewall () {
  531. _runDebug "${FUNCNAME[0]}"
  532. # RHEL
  533. if [[ "$ID" =~ ^(fedora|centos)$ ]] && [[ -x $(command -v firewall-cmd) ]]; then
  534. if ! firewall-cmd --get-services | grep -q jriver; then
  535. # shellcheck disable=SC2140,SC1079,SC1078
  536. "${_firewall_cmd[@]}" --permanent --new-service=jriver > /dev/null 2>&1
  537. "${_firewall_cmd[@]}" --permanent --service=jriver --set-description="JRiver Media Center Media Server" > /dev/null 2>&1
  538. "${_firewall_cmd[@]}" --permanent --service=jriver --set-short="jriver" > /dev/null 2>&1
  539. "${_firewall_cmd[@]}" --permanent --service=jriver --add-port=52100-52200/tcp > /dev/null 2>&1
  540. "${_firewall_cmd[@]}" --permanent --service=jriver --add-port=1900/udp > /dev/null 2>&1
  541. "${_firewall_cmd[@]}" --reload > /dev/null 2>&1
  542. fi
  543. # Ubuntu
  544. elif [[ "$ID" =~ ^(ubuntu|debian)$ ]] && [[ -x $(command -v ufw) ]]; then
  545. if [[ ! -f "/etc/ufw/applications.d/jriver.service" ]]; then
  546. "${_bash_cmd[@]}" "cat <<-EOF > /etc/ufw/applications.d/jriver.service
  547. [jriver]
  548. title=JRiver Media Center
  549. description=Allows JRiver Media Server access
  550. ports=52100:52200/tcp|1900/udp
  551. EOF"
  552. fi
  553. "${_firewall_cmd[@]}" allow jriver > /dev/null 2>&1
  554. fi
  555. }
  556. _setVNCPass () {
  557. _runDebug "${FUNCNAME[0]}"
  558. _vncpassfile="$HOME/.vnc/jrmc_passwd"
  559. if [[ -n $_vncpass ]]; then
  560. # Remove existing password file if it exists and write a new one
  561. [[ -f "$_vncpassfile" ]] && rm -f "$_vncpassfile"
  562. x11vnc -storepasswd "$_vncpass" "$_vncpassfile"
  563. # Else disable authentication
  564. elif [[ ! -f "$_vncpassfile" ]]; then
  565. _novncauth="true"
  566. fi
  567. }
  568. _systemctlReloadAndEnable () {
  569. _runDebug "${FUNCNAME[0]}"
  570. echo "Enabling $1"
  571. if [[ "$_user" == "root" ]]; then
  572. systemctl daemon-reload
  573. systemctl enable --now "$1" > /dev/null 2>&1
  574. else
  575. sudo systemctl daemon-reload
  576. sudo systemctl enable --now "$1" > /dev/null 2>&1
  577. fi
  578. }
  579. _generateServiceVars () {
  580. _runDebug "${FUNCNAME[0]}"
  581. unset _service_fname _service_name _timer_fname _timer_name _user_specifier
  582. if [[ "$_user" == "root" ]]; then
  583. _service_fname="/usr/lib/systemd/system/$1.service"
  584. _timer_fname="/usr/lib/systemd/system/$1.timer"
  585. _service_name="$1.service"
  586. _timer_name="$1.timer"
  587. _user_specifier=""
  588. else
  589. _service_fname="/usr/lib/systemd/system/$1@.service"
  590. _timer_fname="/usr/lib/systemd/system/$1@.timer"
  591. _service_name="$1@$_user.service"
  592. _timer_name="$1@$_user.timer"
  593. _user_specifier="User=%I"
  594. fi
  595. }
  596. _serviceMediaserver () {
  597. _runDebug "${FUNCNAME[0]}"
  598. _generateServiceVars "jriver-mediaserver"
  599. "${_bash_cmd[@]}" "cat <<-EOF > $_service_fname
  600. [Unit]
  601. Description=JRiver Media Center $_mversion Media Server
  602. After=graphical.target
  603. [Service]
  604. $_user_specifier
  605. Type=simple
  606. Environment=DISPLAY=$_display
  607. ExecStart=/usr/bin/mediacenter$_mversion /MediaServer
  608. Restart=always
  609. RestartSec=10
  610. KillSignal=SIGHUP
  611. TimeoutStopSec=30
  612. [Install]
  613. WantedBy=graphical.target
  614. EOF"
  615. _systemctlReloadAndEnable "$_service_name"
  616. }
  617. _serviceX11VNC () {
  618. _runDebug "${FUNCNAME[0]}"
  619. _installPackage x11vnc
  620. _setVNCPass
  621. _generateServiceVars "jriver-x11vnc"
  622. if [[ "$_novncauth" == "true" ]]; then
  623. _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry 1920x1080 -auth guess -forever -bg -nopw"
  624. else
  625. _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry 1920x1080 -rfbauth $HOME/.vnc/jrmc_passwd -auth guess -forever -bg"
  626. fi
  627. "${_bash_cmd[@]}" "cat <<-EOF > $_service_fname
  628. [Unit]
  629. Description=x11vnc
  630. After=display-manager.service
  631. [Service]
  632. $_user_specifier
  633. Type=forking
  634. Environment=DISPLAY=$_display
  635. ExecStart=$_exec_start_cmd
  636. Restart=always
  637. RestartSec=10
  638. [Install]
  639. WantedBy=default.target
  640. EOF"
  641. _systemctlReloadAndEnable "$_service_name"
  642. }
  643. _serviceCreaterepo () {
  644. _runDebug "${FUNCNAME[0]}"
  645. _generateServiceVars "jriver-createrepo"
  646. "${_bash_cmd[@]}" "cat <<-EOF > $_service_fname
  647. [Unit]
  648. Description=Builds JRiver Media Center RPM file, moves it to the repo dir, and runs createrepo
  649. [Service]
  650. $_user_specifier
  651. ExecStart=$_basedir/installJRMC --outputdir $_outputdir --createrepo --createrepo-webroot $_createrepo_webroot --createrepo-user $_createrepo_user
  652. [Install]
  653. WantedBy=default.target
  654. EOF"
  655. "${_bash_cmd[@]}" "cat <<-EOF > $_timer_fname
  656. [Unit]
  657. Description=Run JRiver MC rpmbuild hourly
  658. [Timer]
  659. OnCalendar=hourly
  660. Persistent=true
  661. [Install]
  662. WantedBy=timers.target
  663. EOF"
  664. _systemctlReloadAndEnable "$_timer_name"
  665. }
  666. _uninstall () {
  667. _runDebug "${FUNCNAME[0]}"
  668. read -r -p "Do you really want to uninstall all JRiver Media Center files? [y/N] " _response
  669. _response=${_response,,} # tolower
  670. [[ ! "$_response" =~ ^(yes|y)$ ]] && echo "Cancelling uninstall..." && exit 0
  671. echo "Stopping and disabling all Media Center services"
  672. sudo systemctl disable --now jriver-createrepo.timer jriver-x11vnc.service jriver-mediaserver.service
  673. echo "Removing repo and service files"
  674. for _service in "jriver-mediaserver" "jriver-x11vnc" "jriver-createrepo"; do
  675. _generateServiceVars _service
  676. [[ -f "$_service_fname" ]] && "${_rm_cmd[@]}" "$_service_fname"
  677. [[ -f "$_timer_fname" ]] && "${_rm_cmd[@]}" "$_timer_fname"
  678. done
  679. [[ -f "/etc/yum.repos.d/jriver.repo" ]] \
  680. && "${_rm_cmd[@]}" "/etc/yum.repos.d/jriver.repo"
  681. [[ -f "/etc/apt/sources.list.d/jriver.list" ]] \
  682. && "${_rm_cmd[@]}" "/etc/apt/sources.list.d/jriver.list"
  683. if [[ -x $(command -v firewall-cmd) ]]; then
  684. echo "Removing firewall rules"
  685. sudo firewall-cmd --permanent --remove-service=jriver > /dev/null 2>&1
  686. sudo firewall-cmd --permanent --delete-service=jriver > /dev/null 2>&1
  687. sudo firewall-cmd --reload > /dev/null 2>&1
  688. elif [[ -x $(command -v ufw) ]]; then
  689. echo "Removing firewall rules"
  690. sudo ufw delete allow jriver > /dev/null 2>&1
  691. [[ -f "/etc/ufw/applications.d/jriver.service" ]] \
  692. && "${_rm_cmd[@]}" /etc/ufw/applications.d/jriver.service
  693. fi
  694. echo "Uninstalling Media Center"
  695. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  696. sudo dnf remove MediaCenter -y
  697. elif [[ "$ID" =~ ^(ubuntu|debian)$ ]]; then
  698. sudo apt-get remove "mediacenter$_mversion" -y
  699. fi
  700. echo "JRiver Media Center has been completely uninstalled"
  701. echo "Your library files will remain at $HOME/.jriver"
  702. }
  703. __main () {
  704. # Check user
  705. _checkUser
  706. # Parse input
  707. _parseInput "$@"
  708. # Detect OS
  709. _getOS
  710. # Build some commands based on the selected OS
  711. _buildCommands
  712. # Set version to install/uninstall
  713. _setVersion
  714. # Sanity checks
  715. _sanityChecks
  716. # Uninstall and exit
  717. if [[ -n $_uninstall ]]; then
  718. _uninstall
  719. return $?
  720. fi
  721. # Install external repos
  722. _installExternalRepos
  723. # install MC using package manager (default)
  724. if [[ -z $_rpmbuild ]]; then
  725. _installRepo
  726. _symlinkCerts
  727. _restoreLicense
  728. _openFirewall
  729. else
  730. _acquireDeb
  731. _buildRPM
  732. if [[ -n $_createrepo ]]; then
  733. _runCreateRepo
  734. # Go ahead and install MC from RPM if on a supported platform
  735. elif [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  736. _installRPM
  737. _symlinkCerts
  738. _restoreLicense
  739. _openFirewall
  740. fi
  741. fi
  742. # Install systemd services
  743. if [[ "$_service" == "createrepo" ]]; then
  744. _serviceCreaterepo
  745. elif [[ "$_service" == "x11vnc-mediaserver" ]]; then
  746. _serviceMediaserver
  747. _serviceX11VNC
  748. elif [[ "$_service" == "mediaserver" ]]; then
  749. _serviceMediaserver
  750. fi
  751. }
  752. # Execute main function when called
  753. __main "$@"
  754. }
  755. # Allow this file to be executed directly if not being sourced
  756. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  757. _basedir=$(dirname "$(readlink -f "$0")")
  758. installJRMC "$@"
  759. fi