installJRMC 29 KB

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