installJRMC 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
  1. #!/usr/bin/env bash
  2. shopt -s extglob
  3. #######################################
  4. # This script will download, build, and install JRiver Media Center with optional systemd services
  5. # on Fedora, CentOS, Debian, and Ubuntu
  6. #
  7. # Run installJRMC --help to see available options
  8. #
  9. # To-dos:
  10. # 1. Raspberry Pi OS support
  11. # 2. Interactive installation (ncurses?)
  12. #
  13. #######################################
  14. _scriptversion="1.0.0a3"
  15. _boardurl="https://yabb.jriver.com/interact/index.php/board,71.0.html"
  16. _outputdir="$PWD/output"
  17. _createrepo_webroot="/srv/jriver"
  18. _exec_user="$(whoami)"
  19. _printHelpAndExit() {
  20. debug "Running: ${FUNCNAME[0]}"
  21. cat <<- 'EOF'
  22. USAGE:
  23. installJRMC [[OPTION] [VALUE]]...
  24. If no options (besides -d) are provided, the script will default to '--install repo'
  25. OPTIONS
  26. --install, -i repo|rpm
  27. repo: Install MC from repository, future updates will be handled by the system package manager
  28. rpm: Build and install MC locally (RPM-based OSes only)
  29. --build
  30. Build RPM from source DEB (no installation)
  31. --mcversion VERSION
  32. Build or install a specific MC version, ex. "28.0.25" (Default: scrape latest version from Interact)
  33. --outputdir PATH
  34. Generate rpmbuild output in this directory (Default: $PWD/output)
  35. --restorefile RESTOREFILE
  36. Restore file location for automatic license registration (Default: skip registration)
  37. --betapass PASSWORD
  38. Enter beta team password for access to beta builds
  39. --service-user USER
  40. Install systemd services and containers for USER (Default: current user)
  41. --service, -s SERVICE
  42. See SERVICES section below for a list of possible services to install
  43. --container, -c CONTAINER (TODO: Under construction)
  44. See CONTAINERS section below for a list of possible services to install
  45. --createrepo
  46. Build rpm, copy to webroot, and run createrepo
  47. --createrepo-webroot PATH
  48. The webroot directory to install the repo (Default: /srv/jriver/)
  49. --createrepo-user USER
  50. The web server user (Default: current user)
  51. --version, -v
  52. Print this script version and exit
  53. --debug, -d
  54. Print debug output
  55. --help, -h
  56. Print help dialog and exit
  57. --uninstall, -u
  58. Uninstall JRiver MC, cleanup service files, and remove firewall rules (does not remove library files)
  59. SERVICES
  60. jriver-mediaserver
  61. Enable and start a mediaserver systemd service (requires an existing X server)
  62. jriver-mediacenter
  63. Enable and start a mediacenter systemd service (requires an existing X server)
  64. jriver-x11vnc
  65. Enable and start x11vnc for the local desktop (requires an existing X server)
  66. Usually combined with jriver-mediaserver or jriver-mediacenter services
  67. --vncpass and --display are also valid options (see below)
  68. jriver-xvnc-mediacenter
  69. Enable and start a new Xvnc session running JRiver Media Center
  70. --vncpass PASSWORD
  71. Set vnc password for x11vnc/Xvnc access. If no password is set, the script
  72. will either use existing password stored in ~/.vnc/jrmc_passwd or use no password
  73. --display DISPLAY
  74. Display to start x11vnc/Xvnc (Default: The current display (x11vnc) or the
  75. current display incremented by 1 (Xvnc))
  76. jriver-createrepo
  77. Install hourly service to build latest MC RPM and run createrepo
  78. CONTAINERS (TODO: Under construction)
  79. mediacenter-xvnc
  80. createrepo
  81. EOF
  82. # Exit using passed exit code
  83. [[ ! -v 1 ]] && exit 0 || exit "$1"
  84. }
  85. _init() {
  86. debug "Running: ${FUNCNAME[0]}"
  87. _getOS
  88. _parseInput "$@"
  89. # Agnostic commands
  90. _bash_cmd(){ _ifSudo bash -c "$@"; }
  91. _rm_cmd(){ _ifSudo rm -rf "$@"; }
  92. _cp_cmd(){ _ifSudo cp -n "$@"; }
  93. _mkdir_cmd(){ _ifSudo mkdir -p "$@"; }
  94. _ln_cmd(){ _ifSudo ln -s "$@"; }
  95. _systemctl_reload(){ _ifSudo systemctl daemon-reload; }
  96. _systemctl_enable(){ _ifSudo systemctl enable --now "$@"; }
  97. _systemctl_disable(){ _ifSudo systemctl disable --now "$@"; }
  98. # OS-specific commands
  99. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  100. _pkg_install(){ _ifSudo dnf install -y "$@"; }
  101. _pkg_reinstall(){ _ifSudo dnf reinstall -y "$@"; }
  102. _pkg_install_nogpg(){ _ifSudo dnf install --nogpgcheck -y "$@"; }
  103. _pkg_remove(){ _ifSudo dnf remove -y "$@"; }
  104. _pkg_update(){ _ifSudo dnf makecache; }
  105. _pkg_query(){ _ifSudo rpm -q "$@"; }
  106. _firewall_cmd(){ _ifSudo firewall-cmd "$@"; }
  107. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  108. _pkg_install(){ _ifSudo apt-get install -y -q0 "$@"; }
  109. _pkg_reinstall(){ _ifSudo apt-get reinstall -y -q0 "$@"; }
  110. _pkg_install_nogpg(){ _ifSudo apt-get install -y -q0 "$@"; }
  111. _pkg_remove(){ _ifSudo apt-get remove -y -q0 "$@"; }
  112. _pkg_update(){ _ifSudo apt-get update -y -q0; }
  113. _pkg_query(){ _ifSudo dpkg -s "$@"; }
  114. _firewall_cmd(){ _ifSudo ufw "$@"; }
  115. fi
  116. # Set defaults
  117. if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then
  118. debug "No options passed, defaulting to repo installation method"
  119. _install="repo"
  120. fi
  121. _service_user="${_service_user:-$_exec_user}"
  122. _createrepo_user="${_createrepo_user:-$_exec_user}"
  123. # Set package aliases
  124. if [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  125. declare -Ag PKG_ALIASES
  126. PKG_ALIASES["xorg-x11-utils"]="xorg-x11"
  127. PKG_ALIASES["rpm-build"]="rpm"
  128. PKG_ALIASES["createrepo_c"]="createrepo"
  129. PKG_ALIASES["tigervnc-server"]="tigervnc-standalone-server"
  130. fi
  131. # Install script dependencies
  132. [[ "$ID" == "centos" ]] && _installPackage epel-release
  133. [[ ! -v _mcversion ]] && [[ ! -x $(command -v wget) ]] && _installPackage wget
  134. # Set MC version
  135. _setVersion
  136. }
  137. _main() {
  138. _init "$@"
  139. # Uninstall and exit
  140. if [[ -v _uninstall ]]; then
  141. _uninstall
  142. exit $?
  143. fi
  144. # Install MC using package manager
  145. if [[ -v _install && "$_install" == "repo" ]]; then
  146. _installMCFromRepo
  147. _symlinkCerts
  148. _restoreLicense
  149. _openFirewall "jriver"
  150. fi
  151. # Build RPM from source deb package
  152. if [[ -v _build ]]; then
  153. _acquireDeb
  154. _buildRPM
  155. fi
  156. # Run createrepo
  157. if [[ -v _createrepo ]]; then
  158. _runCreaterepo "$_mcrpm"
  159. fi
  160. # Install the rpm
  161. if [[ -v _install && "$_install" == "rpm" ]]; then
  162. _installPackage --noquery "$_mcrpm"
  163. _symlinkCerts
  164. _restoreLicense
  165. _openFirewall "jriver"
  166. fi
  167. # Install services
  168. _setDisplay
  169. for _service in "${_services[@]}"; do
  170. _servicePrep "$_service"
  171. if ! "_service_$_service"; then
  172. if [[ $? -eq 127 ]]; then
  173. err "Service $_service does not exist, check your service name"
  174. else
  175. err "Failed to create service: $_service"
  176. fi
  177. fi
  178. done
  179. # Install containers
  180. for _container in "${_containers[@]}"; do
  181. if ! "_container_$_container"; then
  182. if [[ $? -eq 127 ]]; then
  183. err "Container $_container does not exist, check your container name"
  184. else
  185. err "Failed to create container: $_container"
  186. fi
  187. fi
  188. done
  189. }
  190. #######################################
  191. # Helper functions
  192. #######################################
  193. err() { echo "Error: $*" >&2; }
  194. debug() {
  195. if [[ -v _debug ]]; then
  196. if [[ $# -gt 0 ]]; then
  197. echo "Debug: $*"
  198. fi
  199. else
  200. return 1
  201. fi
  202. }
  203. #######################################
  204. # Prepend this to any command that you wish to execute with sudo
  205. # Requires:
  206. # _exec_user
  207. #######################################
  208. _ifSudo() {
  209. if [[ "$_exec_user" != "root" ]]; then
  210. sudo "$@"
  211. else
  212. "$@"
  213. fi
  214. }
  215. #######################################
  216. # Parse CLI input from the user w/ getopt
  217. #######################################
  218. _parseInput() {
  219. debug "Running: ${FUNCNAME[0]}"
  220. 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
  221. eval set -- "$_input"
  222. while true; do
  223. case "$1" in
  224. --install|-i)
  225. shift
  226. _install="$1"
  227. if [[ "$_install" == "rpm" ]]; then
  228. if [[ ! "$ID" =~ ^(fedora|centos)$ ]]; then
  229. err "RPM install method not available on $ID"
  230. _printHelpAndExit 1
  231. fi
  232. _build="true"
  233. fi
  234. ;;
  235. --build)
  236. _build="true"
  237. ;;
  238. --outputdir)
  239. shift && _outputdir="$1"
  240. ;;
  241. --mcversion)
  242. shift && _mcversion="$1"
  243. ;;
  244. --restorefile)
  245. shift && _restorefile="$1"
  246. ;;
  247. --betapass)
  248. shift && _betapass="$1"
  249. ;;
  250. --service-user)
  251. shift && _service_user="$1"
  252. ;;
  253. --service|-s)
  254. shift && _services+=("$1")
  255. ;;
  256. --createrepo)
  257. _build="true"
  258. _createrepo="true"
  259. ;;
  260. --createrepo-webroot)
  261. shift && _createrepo_webroot="$1"
  262. ;;
  263. --createrepo-user)
  264. shift && _createrepo_user="$1"
  265. ;;
  266. --vncpass)
  267. shift && _vncpass="$1"
  268. ;;
  269. --display)
  270. shift && _display="$1"
  271. ;;
  272. --container|-c)
  273. shift && _containers+=("$1")
  274. ;;
  275. --version|-v)
  276. echo "Version: $_scriptversion"
  277. exit 0
  278. ;;
  279. --debug|-d)
  280. echo "Debugging on"
  281. echo "installJRMC version: $_scriptversion"
  282. _debug="true"
  283. ;;
  284. --help|-h)
  285. _printHelpAndExit 0
  286. ;;
  287. --uninstall|-u)
  288. _uninstall="true"
  289. ;;
  290. --)
  291. shift
  292. break
  293. ;;
  294. esac
  295. shift
  296. done
  297. else
  298. err "Incorrect options provided"
  299. _printHelpAndExit 1
  300. fi
  301. }
  302. #######################################
  303. # Get host OS from /etc/os-release
  304. #######################################
  305. _getOS() {
  306. debug "Running: ${FUNCNAME[0]}"
  307. if [[ -e "/etc/os-release" ]]; then
  308. source "/etc/os-release"
  309. else
  310. err "/etc/os-release not found"
  311. err "Your OS is unsupported"
  312. _printHelpAndExit 1
  313. fi
  314. debug "Platform: $ID $VERSION_ID"
  315. }
  316. #######################################
  317. # Get our MC working version from input argument or scraping Interact
  318. # Requires:
  319. # _boardurl
  320. #######################################
  321. _setVersion() {
  322. debug "Running: ${FUNCNAME[0]}"
  323. # If user does not specify a version, scrape the latest from Interact
  324. if [[ ! -v _mcversion ]]; then
  325. echo "Scraping latest MC version number from Interact..."
  326. if ! _mcversion=$(wget -qO- "$_boardurl" | grep -o "[0-9][0-9]\.[0-9]\.[0-9]\+" | head -n 1); then
  327. err "MC version could not be scraped. Please recheck the boardurl: $_boardurl or specify a version manually using --mcversion"
  328. _printHelpAndExit 1
  329. fi
  330. fi
  331. echo "Using version: $_mcversion"
  332. # Extract major version number
  333. _mversion="${_mcversion%%.*}"
  334. # Saving this substituion in case it's needed in the future
  335. #_variation="${_mcversion##*.}"
  336. }
  337. #######################################
  338. # Installs a package using the system package manager
  339. # Arguments:
  340. # One or more package names
  341. # Options:
  342. # --noquery, -n: Do not query the package state (useful if installing a local RPM)
  343. # Returns:
  344. # Will exit 1 if failed
  345. #######################################
  346. _installPackage() {
  347. debug "Running: ${FUNCNAME[0]}" "$@"
  348. if _input=$(getopt -o +n -l noquery -- "$@"); then
  349. eval set -- "$_input"
  350. while true; do
  351. case "$1" in
  352. --noquery|-n)
  353. local _noquery="true"
  354. ;;
  355. --)
  356. shift
  357. break
  358. ;;
  359. esac
  360. shift
  361. done
  362. else
  363. err "Incorrect options provided"
  364. _printHelpAndExit 1
  365. fi
  366. # We will add packages to this array if their command is not available
  367. local -a _pkg_array
  368. local -a _url_pkg_array
  369. # Parse packages
  370. for _pkg in "$@"; do
  371. [[ -v PKG_ALIASES && -v PKG_ALIASES["$_pkg"] ]] && _pkg=PKG_ALIASES["$_pkg"]
  372. # Insert the package name to test if already installed
  373. if [[ -v _noquery ]] || ! _pkg_query "$_pkg" > /dev/null 2>&1; then
  374. if [[ -v _url_pkg ]]; then
  375. _url_pkg_array+=("$_url_pkg")
  376. else
  377. _pkg_array+=("$_pkg")
  378. fi
  379. fi
  380. done
  381. # Install from package name (with gpg check)
  382. if [[ ${#_pkg_array[@]} -ge 1 ]]; then
  383. echo "Installing:" "${_pkg_array[@]}"
  384. if debug; then
  385. if ! _pkg_install "${_pkg_array[@]}"; then
  386. err "Failed to install package. Attempting to continue..."
  387. return 1
  388. fi
  389. elif ! _pkg_install "${_pkg_array[@]}" > /dev/null 2>&1; then
  390. err "Failed to install package. Attempting to continue..."
  391. return 1
  392. fi
  393. fi
  394. # Install from package url (without gpg check)
  395. if [[ ${#_url_pkg_array[@]} -ge 1 ]]; then
  396. echo "Installing:" "${_url_pkg_array[@]}"
  397. if debug; then
  398. if ! _pkg_install_nogpg "${_url_pkg_array[@]}"; then
  399. err "Failed to install package. Attempting to continue..."
  400. return 1
  401. fi
  402. elif ! _pkg_install_nogpg "${_url_pkg_array[@]}" > /dev/null 2>&1; then
  403. err "Failed to install package. Attempting to continue..."
  404. return 1
  405. fi
  406. fi
  407. }
  408. #######################################
  409. # Installs JRiver Media Center from a repository
  410. # Returns:
  411. # 0 if JRiver Media Center installed sucessfully
  412. #######################################
  413. _installMCFromRepo() {
  414. debug "Running: ${FUNCNAME[0]}"
  415. echo "Installing JRiver Media Center from repo..."
  416. ! debug && \
  417. echo "This may take a few minutes to complete"; \
  418. echo "Use --debug for verbose output"
  419. local _mcpkg
  420. # Add repository files
  421. _addRepo() {
  422. debug "Running: ${FUNCNAME[0]}"
  423. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  424. _bash_cmd 'cat <<- EOF > /etc/yum.repos.d/jriver.repo
  425. [jriver]
  426. name=JRiver Media Center repo by BryanC
  427. baseurl=https://repos.bryanroessler.com/jriver
  428. gpgcheck=0
  429. EOF'
  430. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  431. _installPackage wget
  432. wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | _ifSudo apt-key add - > /dev/null 2>&1
  433. _ifSudo wget "http://dist.jriver.com/latest/mediacenter/mediacenter$_mversion.list" -O "/etc/apt/sources.list.d/mediacenter$_mversion.list"
  434. fi
  435. }
  436. _addRepo
  437. # Update package list
  438. debug "Updating package list"
  439. if ! _pkg_update > /dev/null 2>&1; then
  440. err "Package update failed!"
  441. exit 1
  442. fi
  443. local _mcpkg
  444. # Fedora/CentOS use a universal package name -- easy
  445. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  446. _mcpkg="MediaCenter"
  447. # Ubuntu/Debian incorporate the mversion into the package name -- more fun!
  448. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  449. if [[ ! -v _mversion ]]; then
  450. # Try parsing the latest mversion from the repo
  451. if _mcpkg=$(apt-get install mediacenter?? -s -q0 | grep "selecting" | tail -1| awk '{print $3}'); then
  452. _mcpkg="${_mcpkg%\'}"
  453. _mcpkg="${_mcpkg#\'}"
  454. # Scrape Interact
  455. else
  456. _mcpkg="mediacenter$_mversion"
  457. fi
  458. else
  459. _mcpkg="mediacenter$_mversion"
  460. fi
  461. # Sanity check
  462. if [[ ! "$_mcpkg" =~ ^mediacenter[0-9][0-9]$ ]]; then
  463. err "Could not parse MC package name"
  464. exit 1
  465. fi
  466. fi
  467. if [[ -v _specific_version ]]; then
  468. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  469. if debug; then
  470. _installPackage "$_mcpkg-$_mcversion"
  471. else
  472. _installPackage "$_mcpkg-$_mcversion" > /dev/null 2>&1
  473. fi
  474. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  475. if debug; then
  476. _installPackage "$_mcpkg=$_mcversion"
  477. else
  478. _installPackage "$_mcpkg=$_mcversion" > /dev/null 2>&1
  479. fi
  480. fi
  481. else
  482. if debug; then
  483. _installPackage "$_mcpkg"
  484. else
  485. _installPackage "$_mcpkg" > /dev/null 2>&1
  486. fi
  487. fi
  488. # shellcheck disable=SC2181
  489. if [[ $? -ne 0 ]]; then
  490. err "JRiver Media Center installation failed"
  491. exit 1
  492. fi
  493. echo "JRiver Media Center installed successfully"
  494. }
  495. #######################################
  496. # Acquire the source DEB package from JRiver's servers
  497. # Globals:
  498. # DEBFILENAME
  499. # Returns:
  500. # 0 if DEB file downloaded successfully, 1 if failed
  501. #######################################
  502. _acquireDeb() {
  503. debug "Running: ${FUNCNAME[0]}"
  504. declare -g DEBFILENAME
  505. DEBFILENAME="$_outputdir/SOURCES/MediaCenter-$_mcversion-amd64.deb"
  506. # If necessary, create SOURCES dir
  507. [[ ! -d "$_outputdir/SOURCES" ]] && mkdir -p "$_outputdir/SOURCES"
  508. # If deb file already exists, skip download
  509. if [[ -f "$DEBFILENAME" ]]; then
  510. echo "Using local DEB file: $DEBFILENAME"
  511. elif [[ -v _betapass ]]; then
  512. echo -n "Checking beta repo..."
  513. if wget -q -O "$DEBFILENAME" \
  514. "https://files.jriver.com/mediacenter/channels/v$_mversion/beta/$_betapass/MediaCenter-$_mcversion-amd64.deb"; then
  515. echo "Found!"
  516. fi
  517. elif echo -n "Checking test repo..." && wget -q -O "$DEBFILENAME" \
  518. "https://files.jriver.com/mediacenter/test/MediaCenter-$_mcversion-amd64.deb"; then
  519. echo "Found!"
  520. # Else check latest repo
  521. elif echo -n "Checking latest repo..." && wget -q -O "$DEBFILENAME" \
  522. "https://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb"; then
  523. echo "Found!"
  524. else
  525. err "Cannot find DEB file. Exiting..."
  526. exit 1
  527. fi
  528. if [[ ! -f "$DEBFILENAME" ]]; then
  529. err "Downloaded DEB file missing or corrupted, exiting..."
  530. exit 1
  531. fi
  532. }
  533. #######################################
  534. # Creates a SPEC file and builds the RPM from the source DEB using rpmbuild
  535. # Requires:
  536. # _outputdir
  537. # ID
  538. # _mcversion
  539. # _mversion
  540. # _installPackage
  541. # Globals:
  542. # _mcrpm
  543. # Returns:
  544. # 0 if rpmbuild is successful, 1 if not
  545. #######################################
  546. _buildRPM() {
  547. debug "Running: ${FUNCNAME[0]}"
  548. # install build dependencies
  549. _installPackage wget dpkg rpm-build
  550. # If necessary, make build directories
  551. [[ ! -d "$_outputdir/SPECS" ]] && mkdir -p "$_outputdir/SPECS"
  552. # rpmbuild uses rpm to check for build dependencies
  553. # this will fail on non-rpm distros
  554. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  555. local _build_requires=$'BuildRequires: rpm >= 4.11.0\nBuildRequires: dpkg'
  556. fi
  557. # Create spec file
  558. cat <<- EOF > "$_outputdir/SPECS/mediacenter.spec"
  559. Name: MediaCenter
  560. Version: $_mcversion
  561. Release: 1
  562. Summary: JRiver Media Center
  563. Group: Applications/Media
  564. Source0: http://files.jriver.com/mediacenter/channels/v$_mversion/latest/MediaCenter-$_mcversion-amd64.deb
  565. ${_build_requires:-}
  566. BuildArch: x86_64
  567. %define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm
  568. AutoReq: 0
  569. Requires: glibc >= 2.19
  570. Requires: alsa-lib >= 1.0.28
  571. Requires: libuuid >= 2.25
  572. Requires: libX11 >= 1.6
  573. Requires: libX11-common >= 1.6
  574. Requires: libXext >= 1.3
  575. Requires: libxcb >= 1.1
  576. Requires: libXdmcp >= 1.1
  577. Requires: libstdc++ >= 4.9
  578. Requires: gtk3 >= 3.14
  579. Requires: mesa-libGL
  580. Requires: libglvnd-glx
  581. Requires: pango >= 1.36
  582. Requires: libXScrnSaver
  583. Requires: xdg-utils
  584. Requires: libgomp >= 4.9
  585. Requires: nss >= 3.26
  586. Requires: nspr >= 4.12
  587. Requires: ca-certificates
  588. Requires: python3
  589. Recommends: vorbis-tools >= 1.4.0
  590. Recommends: lame >= 3.0
  591. Provides: mediacenter$_mversion
  592. License: Copyright 1998-2021, JRiver, Inc. All rights reserved. Protected by U.S. patents #7076468 and #7062468
  593. URL: http://www.jriver.com/
  594. %define __provides_exclude_from ^%{_libdir}/jriver/.*/.*\\.so.*$
  595. %description
  596. Media Center is more than a world class player.
  597. %global __os_install_post %{nil}
  598. %prep
  599. %build
  600. %install
  601. dpkg -x %{S:0} %{buildroot}
  602. %post -p /sbin/ldconfig
  603. %postun -p /sbin/ldconfig
  604. %files
  605. %{_bindir}/mediacenter$_mversion
  606. %{_libdir}/jriver
  607. %{_datadir}
  608. %exclude %{_datadir}/applications/media_center_packageinstaller_$_mversion.desktop
  609. /etc/security/limits.d/*
  610. EOF
  611. declare -g _mcrpm="$_outputdir/RPMS/x86_64/MediaCenter-$_mcversion.x86_64.rpm"
  612. # skip rebuilding the rpm if it already exists
  613. if [[ -f "$_mcrpm" ]]; then
  614. echo "$_mcrpm already exists. Skipping build step..."
  615. return 0
  616. fi
  617. # Run rpmbuild
  618. echo "Building version $_mcversion, please wait..."
  619. if debug; then
  620. rpmbuild --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec"
  621. else
  622. rpmbuild --quiet --define="%_topdir $_outputdir" --define="%_libdir /usr/lib" -bb "$_outputdir/SPECS/mediacenter.spec" > /dev/null 2>&1
  623. fi
  624. # Check return code
  625. # shellcheck disable=SC2181
  626. if [[ $? -ne 0 || ! -f "$_mcrpm" ]]; then
  627. err "Build failed. Exiting..."
  628. echo "Removing source DEB"
  629. [[ -f "$DEBFILENAME" ]] && rm -f "$DEBFILENAME"
  630. exit 1
  631. else
  632. echo "Build successful. The RPM file is located at: $_mcrpm"
  633. fi
  634. }
  635. #######################################
  636. # Copy the RPM to createrepo-webroot and runs createrepo as the createrepo-user
  637. # Arguments:
  638. # Requires one argument, the path to the RPM file (typically _mcrpm)
  639. # Requires:
  640. # _createrepo_webroot
  641. # Returns:
  642. # 0 if createrepo is successful, 1 if not
  643. #######################################
  644. _runCreaterepo() {
  645. debug "Running: ${FUNCNAME[0]}"
  646. # Some additional commands specifically for createrepo (primarily to handle user rights)
  647. if [[ $_createrepo_user != "root" ]]; then
  648. if [[ -d "$_createrepo_webroot/repodata" ]]; then
  649. _createrepo_cmd(){ sudo -u "$_createrepo_user" createrepo -q --update "$@"; }
  650. else
  651. _createrepo_cmd(){ sudo -u "$_createrepo_user" createrepo -q "$@"; }
  652. fi
  653. _cr_mkdir_cmd(){ sudo -u "$_createrepo_user" mkdir -p "$@"; }
  654. _cr_cp_cmd(){ sudo -u "$_createrepo_user" cp -n "$@"; }
  655. else
  656. if [[ -d "$_createrepo_webroot/repodata" ]]; then
  657. _createrepo_cmd(){ createrepo -q --update "$@"; }
  658. else
  659. _createrepo_cmd(){ createrepo -q "$@"; }
  660. fi
  661. fi
  662. _installPackage createrepo_c
  663. local _rpmfile="$1"
  664. # If the webroot does not exist, create it
  665. if [[ ! -d "$_createrepo_webroot" ]]; then
  666. if ! _cr_mkdir_cmd "$_createrepo_webroot"; then
  667. err "Could not create the createrepo-webroot path!"
  668. err "Make sure that the createrepo-webroot is writeable by createrepo-user: $_createrepo_user"
  669. return 1
  670. fi
  671. fi
  672. # Copy built rpms to webroot
  673. if ! _cr_cp_cmd -f "$_rpmfile" "$_createrepo_webroot"; then
  674. err "Could not copy the RPM to the createrepo-webroot path"
  675. err "Make sure that the createrepo-webroot path is writeable by createrepo-user: $_createrepo_user"
  676. return 1
  677. fi
  678. # Run createrepo
  679. if _createrepo_cmd "$_createrepo_webroot"; then
  680. echo "Successfully updated repo"
  681. return 0
  682. else
  683. err "Update repo failed"
  684. return 1
  685. fi
  686. }
  687. #######################################
  688. # Symlink certificates where JRiver Media Center expects them to be on Fedora/CentOS
  689. # Returns:
  690. # 0 if symlinking is unecessary or successful, 1 if not
  691. #######################################
  692. _symlinkCerts() {
  693. debug "Running: ${FUNCNAME[0]}"
  694. if [[ ! -f /etc/ssl/certs/ca-certificates.crt && \
  695. -f /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem ]]; then
  696. if ! _ln_cmd /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem /etc/ssl/certs/ca-certificates.crt; then
  697. err "Symlinking certificates failed"
  698. return 1
  699. fi
  700. fi
  701. }
  702. #######################################
  703. # Automatically restore the mjr license file if it is found next to installJRMC or _restorefile
  704. # is set
  705. # Requires:
  706. # _restorefile OR _basedir
  707. # _mversion
  708. # Returns:
  709. # 0 if license restored successfully or skipped, 1 if unsuccessful
  710. #######################################
  711. _restoreLicense() {
  712. debug "Running: ${FUNCNAME[0]}"
  713. local _mjr
  714. # Allow user to drop an mjr file next to installJRMC
  715. if [[ ! -v _restorefile ]]; then
  716. for _mjr in "$PWD"/*.mjr; do
  717. [[ $_mjr -nt $_restorefile ]] && _restorefile="$_mjr"
  718. done
  719. fi
  720. # Restore license
  721. if [[ -f "$_restorefile" ]]; then
  722. if ! "mediacenter$_mversion" /RestoreFromFile "$_restorefile"; then
  723. err "Automatic license restore failed"
  724. return 1
  725. fi
  726. fi
  727. }
  728. #######################################
  729. # Opens ports using the system firewall tool
  730. # Arguments
  731. # Service to enable (pre-defined)
  732. # Requires:
  733. # ID
  734. # _bash_cmd
  735. # _firewall_cmd
  736. # _port
  737. # Returns:
  738. # 0 if ports opened sucessfully, 1 if not
  739. #######################################
  740. _openFirewall() {
  741. debug "Running: ${FUNCNAME[0]}" "$@"
  742. # Create OS-specific port rules based on argument (service) name
  743. local -a _f_ports # for firewall-cmd
  744. local _u_ports # for ufw
  745. if [[ "$1" == "jriver" ]]; then
  746. _f_ports=("52100-52200/tcp" "1900/udp")
  747. _u_ports="52100:52200/tcp|1900/udp"
  748. elif [[ "$1" =~ ^(jriver-x11vnc|jriver-xvnc)$ ]]; then
  749. _f_ports=("$_port/tcp" "1900/udp")
  750. _u_ports="$_port/tcp|1900/udp"
  751. fi
  752. # Open the ports
  753. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  754. [[ ! -x $(command -v firewall-cmd) ]] && _installPackage firewalld
  755. if ! _firewall_cmd --get-services | grep -q "$1"; then
  756. _firewall_cmd --permanent --new-service="$1" > /dev/null 2>&1
  757. _firewall_cmd --permanent --service="$1" --set-description="$1 installed by installJRMC" > /dev/null 2>&1
  758. _firewall_cmd --permanent --service="$1" --set-short="$1" > /dev/null 2>&1
  759. for _f_port in "${_f_ports[@]}"; do
  760. _firewall_cmd --permanent --service="$1" --add-port="$_f_port" > /dev/null 2>&1
  761. done
  762. _firewall_cmd --add-service "$1" --permanent > /dev/null 2>&1
  763. _firewall_cmd --reload > /dev/null 2>&1
  764. fi
  765. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  766. # Debian ufw package state is broken on fresh installations
  767. [[ ! -x $(command -v ufw) ]] && _installPackage ufw
  768. if [[ ! -f "/etc/ufw/applications.d/$1" ]]; then
  769. _bash_cmd "cat <<- EOF > /etc/ufw/applications.d/$1
  770. [$1]
  771. title=$1
  772. description=$1 installed by installJRMC
  773. ports=$_u_ports
  774. EOF"
  775. fi
  776. _firewall_cmd app update "$1"
  777. _firewall_cmd allow "$1" > /dev/null 2>&1
  778. fi
  779. # shellcheck disable=SC2181
  780. # Rationale: much more concise to check exit codes at the end
  781. if [[ $? -ne 0 ]]; then
  782. err "Firewall ports could not be opened"
  783. return 1
  784. fi
  785. }
  786. #######################################
  787. # Create the x11vnc password file
  788. # Globals:
  789. # _novncauth
  790. # Returns:
  791. # 0 if password created sucessfully, 1 if not
  792. #######################################
  793. _setX11VNCPass() {
  794. debug "Running: ${FUNCNAME[0]}"
  795. _vncpassfile="$HOME/.vnc/jrmc_passwd"
  796. [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}"
  797. if [[ -f "$_vncpassfile" ]]; then
  798. if [[ ! -v _vncpass ]]; then
  799. err "Refusing to overwrite existing $_vncpassfile with an empty password"
  800. err "Remove existing $_vncpassfile or set --vncpass to use an empty password"
  801. exit 1
  802. else
  803. rm -f "$_vncpassfile"
  804. fi
  805. fi
  806. if [[ -v _vncpass ]]; then
  807. if ! x11vnc -storepasswd "$_vncpass" "$_vncpassfile"; then
  808. err "Could not create VNC password file"
  809. return 1
  810. fi
  811. else
  812. _novncauth="true"
  813. fi
  814. }
  815. #######################################
  816. # Create the Xvnc password file
  817. # Returns:
  818. # 0 if password created sucessfully, 1 if not
  819. #######################################
  820. _setVNCPass() {
  821. debug "Running: ${FUNCNAME[0]}"
  822. _vncpassfile="$HOME/.vnc/jrmc_passwd"
  823. [[ ! -d "${_vncpassfile%/*}" ]] && mkdir -p "${_vncpassfile%/*}"
  824. if [[ -f "$_vncpassfile" ]]; then
  825. if [[ ! -v _vncpass ]]; then
  826. err "Refusing to overwrite existing $_vncpassfile with an empty password"
  827. err "Remove existing $_vncpassfile or set --vncpass to use an empty password"
  828. exit 1
  829. else
  830. rm -f "$_vncpassfile"
  831. fi
  832. fi
  833. if [[ -v _vncpass ]]; then
  834. if ! echo "$_vncpass" | vncpasswd -f > "$_vncpassfile"; then
  835. err "Could not create VNC password file"
  836. return 1
  837. fi
  838. else
  839. _novncauth="true"
  840. fi
  841. }
  842. #######################################
  843. # Set display and port variables
  844. # Globals:
  845. # _display
  846. # _displaynum
  847. # _next_display
  848. # _next_displaynum
  849. #######################################
  850. _setDisplay() {
  851. debug "Running: ${FUNCNAME[0]}"
  852. # Check _display, else DISPLAY, else set to :0 by default
  853. if [[ -v _display ]]; then
  854. _next_display="$_display"
  855. elif [[ -v DISPLAY ]]; then
  856. _display="${DISPLAY}"
  857. _displaynum="${_display#:}" # strip colon
  858. _displaynum="${_displaynum%.*}" # strip suffix
  859. _next_displaynum=$(( _displaynum + 1 ))
  860. _next_display=":$_next_displaynum"
  861. else
  862. _display=":0"
  863. _next_display=":1"
  864. fi
  865. _displaynum="${_display#:}" # strip colon
  866. _displaynum="${_displaynum%.*}" # strip suffix
  867. _next_displaynum=$(( _displaynum + 1 ))
  868. }
  869. #######################################
  870. # Create associated service variables based on service name
  871. # Requires:
  872. # _service_user
  873. # Globals:
  874. # _service_fname
  875. # _timer_fname
  876. # _service_name
  877. # _timer_name
  878. # _user_specifier
  879. #######################################
  880. _servicePrep() {
  881. debug "Running: ${FUNCNAME[0]}"
  882. if [[ "$_service_user" == "root" ]]; then
  883. _service_fname="/usr/lib/systemd/system/${1}.service"
  884. _timer_fname="/usr/lib/systemd/system/${1}.timer"
  885. _service_name="jriver-${1}.service"
  886. _timer_name="jriver-${1}}.timer"
  887. _user_specifier=""
  888. else
  889. _service_fname="/usr/lib/systemd/system/${1}@.service"
  890. _timer_fname="/usr/lib/systemd/system/${1}@.timer"
  891. _service_name="${1}@$_service_user.service"
  892. _timer_name="${1}@$_service_user.timer"
  893. _user_specifier="User=%I"
  894. fi
  895. }
  896. #######################################
  897. # Starts and enables (at startup) a JRiver Media Center service
  898. # Arguments:
  899. # Passes arguments as startup options to /usr/bin/mediacenter26
  900. # Requires:
  901. # XAUTHORITY
  902. #######################################
  903. _service_jriver-mediacenter() {
  904. debug "Running: ${FUNCNAME[0]}"
  905. _bash_cmd "cat <<- EOF > $_service_fname
  906. [Unit]
  907. Description=JRiver Media Center $_mversion
  908. After=graphical.target
  909. [Service]
  910. $_user_specifier
  911. Type=simple
  912. Environment=DISPLAY=$_display
  913. Environment=XAUTHORITY=$XAUTHORITY
  914. ExecStart=/usr/bin/mediacenter$_mversion $*
  915. Restart=always
  916. RestartSec=10
  917. KillSignal=SIGHUP
  918. TimeoutStopSec=30
  919. [Install]
  920. WantedBy=graphical.target
  921. EOF"
  922. _systemctl_reload && \
  923. _systemctl_enable "$_service_name" && \
  924. _openFirewall "jriver"
  925. }
  926. #######################################
  927. # Starts and enables (at startup) a JRiver Media Server service
  928. #######################################
  929. _service_jriver-mediaserver() {
  930. debug "Running: ${FUNCNAME[0]}"
  931. _service_jriver-mediacenter "/MediaServer"
  932. }
  933. #######################################
  934. # Starts and enables (at startup) JRiver Media Center in a new Xvnc session
  935. #######################################
  936. _service_jriver-xvnc-mediacenter() {
  937. debug "Running: ${FUNCNAME[0]}"
  938. _installPackage tigervnc-server
  939. _setVNCPass
  940. local _port=$(( _next_displaynum + 5900 ))
  941. if [[ -v _novncauth ]]; then
  942. _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -name jriver$_next_display -SecurityTypes None -autokill -xstartup /usr/bin/mediacenter$_mversion"
  943. else
  944. _exec_start_cmd="/usr/bin/vncserver $_next_display -geometry 1440x900 -alwaysshared -rfbauth $HOME/.vnc/jrmc_passwd -autokill -xstartup /usr/bin/mediacenter$_mversion"
  945. fi
  946. _bash_cmd "cat <<- EOF > $_service_fname
  947. [Unit]
  948. Description=Remote desktop service (VNC)
  949. After=syslog.target network.target
  950. [Service]
  951. Type=simple
  952. $_user_specifier
  953. ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill $_next_display > /dev/null 2>&1 || :'
  954. ExecStart=$_exec_start_cmd
  955. ExecStop=/usr/bin/vncserver -kill $_next_display
  956. Restart=always
  957. [Install]
  958. WantedBy=multi-user.target
  959. EOF"
  960. _systemctl_reload && \
  961. _systemctl_enable "$_service_name" && \
  962. echo "Xvnc running on localhost:$_port" && \
  963. _openFirewall "jriver-xvnc" && \
  964. _openFirewall "jriver"
  965. }
  966. #######################################
  967. # Starts and enables (at startup) JRiver Media Server and x11vnc sharing the local desktop
  968. #######################################
  969. _service_jriver-x11vnc() {
  970. debug "Running: ${FUNCNAME[0]}"
  971. _installPackage x11vnc
  972. _setX11VNCPass
  973. local _port=$(( _displaynum + 5900 ))
  974. # Get current desktop resolution
  975. # TODO: may need to break this out into its own function and get smarter at identifying multi-monitors
  976. _getResolution() {
  977. debug "Running: ${FUNCNAME[0]}"
  978. _installPackage xorg-x11-utils
  979. _res=$(xdpyinfo | grep dimensions | awk '{print $2}')
  980. }
  981. _getResolution
  982. if [[ -v _novncauth ]]; then
  983. _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -nopw"
  984. else
  985. _exec_start_cmd="/usr/bin/x11vnc -display $_display -noscr -geometry $_res -auth guess -forever -bg -rfbauth $HOME/.vnc/jrmc_passwd"
  986. fi
  987. _bash_cmd "cat <<-EOF > $_service_fname
  988. [Unit]
  989. Description=x11vnc
  990. After=multi.service
  991. [Service]
  992. $_user_specifier
  993. Type=forking
  994. Environment=DISPLAY=$_display
  995. ExecStart=$_exec_start_cmd
  996. Restart=always
  997. RestartSec=10
  998. [Install]
  999. WantedBy=multi-user.target
  1000. EOF"
  1001. _systemctl_reload && \
  1002. _systemctl_enable "$_service_name" && \
  1003. echo "x11vnc running on localhost:$_port" && \
  1004. _openFirewall "jriver-x11vnc"
  1005. }
  1006. #######################################
  1007. # Starts and enables (at startup) an hourly service to build the latest version of JRiver Media
  1008. # Center RPM from the source DEB and create/update an RPM repository
  1009. #######################################
  1010. _service_jriver-createrepo() {
  1011. debug "Running: ${FUNCNAME[0]}"
  1012. _bash_cmd "cat <<-EOF > $_service_fname
  1013. [Unit]
  1014. Description=Builds JRiver Media Center RPM file, moves it to the repo dir, and runs createrepo
  1015. [Service]
  1016. $_user_specifier
  1017. ExecStart=$PWD/installJRMC --outputdir $_outputdir --createrepo --createrepo-webroot $_createrepo_webroot --createrepo-user $_createrepo_user
  1018. [Install]
  1019. WantedBy=default.target
  1020. EOF"
  1021. _bash_cmd "cat <<-EOF > $_timer_fname
  1022. [Unit]
  1023. Description=Run JRiver MC rpmbuild hourly
  1024. [Timer]
  1025. OnCalendar=hourly
  1026. Persistent=true
  1027. [Install]
  1028. WantedBy=timers.target
  1029. EOF"
  1030. _systemctl_reload && \
  1031. _systemctl_enable "$_timer_name"
  1032. }
  1033. #######################################
  1034. # CONTAINERS
  1035. #######################################
  1036. # _containerCreaterepo() {
  1037. # :
  1038. # }
  1039. # _containerVNC() {
  1040. # :
  1041. # }
  1042. # _containerMC() {
  1043. # _installPackage buildah podman
  1044. # cnt=$(buildah from docker.io/jlesage/baseimage-gui:debian-10)
  1045. # podman_create_cmd=("podman" "create" "--name" "$CNAME")
  1046. # buildah_config_cmd=("buildah" "config" \
  1047. # "--author" "bryanroessler@gmail.com" \
  1048. # "--label" "maintainer=$MAINTAINER" \
  1049. # "--env" "TZ=$TZ" \
  1050. # "--workingdir" "/app" \
  1051. # "--cmd" "mediacenter$_mversion")
  1052. # mkcdirs() {
  1053. # local dir
  1054. # for dir in "$@"; do
  1055. # if [[ ! -d "$dir" ]]; then
  1056. # if ! mkdir -p "$dir"; then
  1057. # err "Could not create directory $dir, check your permissions"
  1058. # fi
  1059. # fi
  1060. # if ! chcon -t container_file_t -R "$dir"; then
  1061. # err "Could not set container_file_t attribute for $dir, check your permissions"
  1062. # fi
  1063. # done
  1064. # }
  1065. # mkcdirs "$HOME/.jriver"
  1066. # podman_create_cmd+=("-v" "$HOME/.jriver:/root/.jriver")
  1067. # podman_create_cmd+=("-v" "$DOWNLOAD_ROOT:/downloads:z")
  1068. # podman_create_cmd+=("-v" "$MONITOR_ROOT/nzbs:/nzbs")
  1069. # podman_create_cmd+=("-p" "${CONTAINER[HOST_PORT]}:${CONTAINER[CONTAINER_PORT]}")
  1070. # brc() { buildah run "$1" "${@:2}" || return 1; }
  1071. # brc add-pkg gnupg2 libxss1 wmctrl xdotool ca-certificates inotify-tools libgbm1
  1072. # brc add-pkg --virtual .build-deps wget
  1073. # brc sh -s <<- EOF
  1074. # wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | apt-key add - > /dev/null 2>&1
  1075. # EOF
  1076. # brc wget "http://dist.jriver.com/latest/mediacenter/mediacenter$_mversion.list" -O "/etc/apt/sources.list.d/mediacenter$_mversion.list"
  1077. # brc apt-get update -y -q0
  1078. # brc add-pkg "mediacenter$_mversion"
  1079. # brc del-pkg .build-deps
  1080. # }
  1081. #######################################
  1082. # Complete uninstall
  1083. #######################################
  1084. _uninstall() {
  1085. debug "Running: ${FUNCNAME[0]}"
  1086. read -r -p "Do you really want to uninstall JRiver Media Center? [y/N] " _response
  1087. _response=${_response,,} # tolower
  1088. [[ ! "$_response" =~ ^(yes|y)$ ]] && echo "Cancelling uninstall..." && exit 0
  1089. # Uninstall services
  1090. echo "Stopping and removing all associated Media Center services"
  1091. for _service in $(compgen -A "function" "_service"); do
  1092. _servicePrep "$_service"
  1093. _systemctl_disable "$_service_name"
  1094. _systemctl_disable "$_timer_name"
  1095. [[ -f "$_service_fname" ]] && _rm_cmd "$_service_fname"
  1096. [[ -f "$_timer_fname" ]] && _rm_cmd "$_timer_fname"
  1097. done
  1098. echo "Removing repo files"
  1099. [[ -f "/etc/yum.repos.d/jriver.repo" ]] \
  1100. && _rm_cmd "/etc/yum.repos.d/jriver.repo"
  1101. [[ -f "/etc/apt/sources.list.d/jriver.list" ]] \
  1102. && _rm_cmd "/etc/apt/sources.list.d/jriver.list"
  1103. echo "Removing firewall rules"
  1104. if [[ -x $(command -v firewall-cmd) ]]; then
  1105. _firewall_cmd --permanent --remove-service=jriver
  1106. _firewall_cmd --permanent --delete-service=jriver
  1107. _firewall_cmd --reload
  1108. elif [[ -x $(command -v ufw) ]]; then
  1109. _firewall_cmd delete allow jriver
  1110. [[ -f "/etc/ufw/applications.d/jriver" ]] \
  1111. && _rm_cmd /etc/ufw/applications.d/jriver
  1112. fi
  1113. echo "Uninstalling Media Center"
  1114. if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
  1115. _pkg_remove MediaCenter
  1116. elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
  1117. _pkg_remove "mediacenter$_mversion"
  1118. fi
  1119. echo "JRiver Media Center has been completely uninstalled"
  1120. echo "If you wish to remove your library files: rm -rf $HOME/.jriver"
  1121. echo "If you wish to remove your rpmbuild output files: rm -rf $_outputdir"
  1122. }
  1123. _main "$@"