Compare commits
9 Commits
29e94c7488
...
a406bf82e9
| Author | SHA1 | Date | |
|---|---|---|---|
| a406bf82e9 | |||
| 7658b9e803 | |||
| 51282e0472 | |||
| df980f103c | |||
| c5f6ec51cc | |||
| 50ec81710b | |||
| b6eb4281e6 | |||
| 2aa5fe56f4 | |||
| 95695fc7b0 |
@@ -6,9 +6,7 @@ This program will install [JRiver Media Center](https://www.jriver.com/) (JRMC)
|
|||||||
|
|
||||||
`installJRMC [--option [ARGUMENT]]`
|
`installJRMC [--option [ARGUMENT]]`
|
||||||
|
|
||||||
Running `installJRMC` without any options will install the latest version of JRiver Media Center from the official JRiver repository (Ubuntu/Debian) or my [unofficial repository](https://repos.bryanroessler.com/jriver/) (Fedora/CentOS) using the system package manager (`--install repo`). If any other option is specified, then the default install method (i.e. `--install repo` or `--install local`) will need to be explicitly specified. This makes it possible to install services and containers independent of MC.
|
Running `installJRMC` without any options will install the latest version of JRiver Media Center (MC) from the official JRiver repository (Ubuntu/Debian) or my [unofficial repository](https://repos.bryanroessler.com/jriver/) (Fedora/CentOS) using the system package manager (`--install repo`). If any other option is specified, then the default install method (i.e. `--install repo` or `--install local`) will need to be explicitly specified. This makes it possible to install services and containers independent of MC.
|
||||||
|
|
||||||
**Note**: As of v1.0b14 major version library migrations are performed if the destination config directory `$HOME/.jriver/Media Center XX` is missing for major release `XX`. However, it is still a good idea to create a manual library backup before migrating major versions.
|
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
@@ -24,6 +22,8 @@ $ installJRMC --help
|
|||||||
Build/install MC without minimum dependency version requirements
|
Build/install MC without minimum dependency version requirements
|
||||||
--mcversion VERSION
|
--mcversion VERSION
|
||||||
Build or install a specific MC version, ex. "30.0.55" (default: latest version)
|
Build or install a specific MC version, ex. "30.0.55" (default: latest version)
|
||||||
|
--arch ARCH
|
||||||
|
Specify the MC architecture, ex. "amd64", "arm64", etc (default: host architecture)
|
||||||
--outputdir PATH
|
--outputdir PATH
|
||||||
Generate rpmbuild output in this PATH (default: ./output)
|
Generate rpmbuild output in this PATH (default: ./output)
|
||||||
--restorefile RESTOREFILE
|
--restorefile RESTOREFILE
|
||||||
@@ -136,6 +136,6 @@ Multiple services (but not `--service-types`) can be installed at one time using
|
|||||||
|
|
||||||
## Additional Info
|
## Additional Info
|
||||||
|
|
||||||
Did you find `installJRMC` useful? [Buy me a coffee!](https://paypal.me/bryanroessler?locale.x=en_US)
|
Did you find `installJRMC` useful? [Buy me a coffee!](https://paypal.me/bryanroessler)
|
||||||
|
|
||||||
Did you find a bug? Let me know on [Interact!](https://yabb.jriver.com/interact/index.php/topic,134152.0.html)
|
Did you find a bug? Let me know on [Interact!](https://yabb.jriver.com/interact/index.php/topic,134152.0.html)
|
||||||
|
|||||||
309
installJRMC
309
installJRMC
@@ -6,6 +6,10 @@
|
|||||||
# This software is released under the Apache License.
|
# This software is released under the Apache License.
|
||||||
# https://www.apache.org/licenses/LICENSE-2.0
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# TODO (v1)
|
||||||
|
# 1. Finish refactoring
|
||||||
|
#
|
||||||
# TODO (v2)
|
# TODO (v2)
|
||||||
# 1. Interactive installation (ncurses?)
|
# 1. Interactive installation (ncurses?)
|
||||||
# 2. Additional containerization (createrepo and rpmbuild)
|
# 2. Additional containerization (createrepo and rpmbuild)
|
||||||
@@ -16,11 +20,9 @@
|
|||||||
|
|
||||||
shopt -s extglob
|
shopt -s extglob
|
||||||
|
|
||||||
declare -g SCRIPTVERSION="1.0-rc5"
|
declare -g SCRIPTVERSION="1.0-dev"
|
||||||
declare -g OUTPUTDIR="$PWD/output"
|
declare -g OUTPUTDIR="$PWD/output"
|
||||||
|
declare -g BOARDURL="https://yabb.jriver.com/interact/index.php/board,76.0.html" # MC30
|
||||||
# MC30 (Buster)
|
|
||||||
declare -g BOARDURL="https://yabb.jriver.com/interact/index.php/board,76.0.html"
|
|
||||||
declare -g DEBIANBASE="buster"
|
declare -g DEBIANBASE="buster"
|
||||||
declare -g MCVERSION_HARDCODE="${MCVERSION:-"30.0.55"}" # Hardcoded fallback
|
declare -g MCVERSION_HARDCODE="${MCVERSION:-"30.0.55"}" # Hardcoded fallback
|
||||||
declare -g CREATEREPO_WEBROOT="/var/www/jriver"
|
declare -g CREATEREPO_WEBROOT="/var/www/jriver"
|
||||||
@@ -46,7 +48,9 @@ printHelp() {
|
|||||||
--compat
|
--compat
|
||||||
Build/install MC locally without minimum dependency version requirements
|
Build/install MC locally without minimum dependency version requirements
|
||||||
--mcversion VERSION
|
--mcversion VERSION
|
||||||
Specify the MC version, ex. 30.0.55" (default: latest version)
|
Specify the MC version, ex. "30.0.55" (default: latest version)
|
||||||
|
--arch VERSION
|
||||||
|
Specify the MC architecture, ex. "amd64", "arm64", etc (default: host architecture)
|
||||||
--outputdir PATH
|
--outputdir PATH
|
||||||
Generate rpmbuild output in this directory (default: ./output)
|
Generate rpmbuild output in this directory (default: ./output)
|
||||||
--restorefile RESTOREFILE
|
--restorefile RESTOREFILE
|
||||||
@@ -111,9 +115,11 @@ askOk() {
|
|||||||
[[ "${response,,}" =~ ^(yes|y)$ ]]
|
[[ "${response,,}" =~ ^(yes|y)$ ]]
|
||||||
}
|
}
|
||||||
execute() {
|
execute() {
|
||||||
declare cmd="$*"
|
if debug "$*"; then
|
||||||
debug "$cmd" || cmd+=" &>/dev/null"
|
eval "$*"
|
||||||
eval "${cmd[*]}"
|
else
|
||||||
|
eval "$* &>/dev/null"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -125,7 +131,7 @@ parseInput() {
|
|||||||
|
|
||||||
declare -g BUILD_SWITCH REPO_INSTALL_SWITCH COMPAT_SWITCH TEST_SWITCH
|
declare -g BUILD_SWITCH REPO_INSTALL_SWITCH COMPAT_SWITCH TEST_SWITCH
|
||||||
declare -g LOCAL_INSTALL_SWITCH CREATEREPO_SWITCH UNINSTALL_SWITCH
|
declare -g LOCAL_INSTALL_SWITCH CREATEREPO_SWITCH UNINSTALL_SWITCH
|
||||||
declare -g USER_VERSION_SWITCH
|
declare -g USER_VERSION_SWITCH USER_ARCH
|
||||||
declare -g OUTPUTDIR RESTOREFILE BETAPASS SERVICE_TYPE
|
declare -g OUTPUTDIR RESTOREFILE BETAPASS SERVICE_TYPE
|
||||||
declare -g VNCPASS USER_DISPLAY CREATEREPO_WEBROOT
|
declare -g VNCPASS USER_DISPLAY CREATEREPO_WEBROOT
|
||||||
declare -ga SERVICES CONTAINERS
|
declare -ga SERVICES CONTAINERS
|
||||||
@@ -135,9 +141,9 @@ parseInput() {
|
|||||||
declare -g TARGET=${TARGET:-$ID}
|
declare -g TARGET=${TARGET:-$ID}
|
||||||
declare -g CREATEREPO_USER="${CREATEREPO_USER:-$USER}"
|
declare -g CREATEREPO_USER="${CREATEREPO_USER:-$USER}"
|
||||||
|
|
||||||
if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then
|
if [[ $# -eq 0 ]] || [[ $# -eq 1 && " $1 " =~ ^( --debug | -d )$ ]]; then
|
||||||
REPO_INSTALL_SWITCH=1
|
REPO_INSTALL_SWITCH=1
|
||||||
elif [[ $# -eq 1 && "$1" =~ ^(--compat)$ ]]; then
|
elif [[ $# -eq 1 && " $1 " =~ ^( --compat )$ ]]; then
|
||||||
BUILD_SWITCH=1
|
BUILD_SWITCH=1
|
||||||
LOCAL_INSTALL_SWITCH=1
|
LOCAL_INSTALL_SWITCH=1
|
||||||
fi
|
fi
|
||||||
@@ -145,9 +151,12 @@ parseInput() {
|
|||||||
long_opts="install:,build::,outputdir:,mcversion:,restorefile:,betapass:,"
|
long_opts="install:,build::,outputdir:,mcversion:,restorefile:,betapass:,"
|
||||||
long_opts+="service-type:,service:,services:,version,debug,help,uninstall,"
|
long_opts+="service-type:,service:,services:,version,debug,help,uninstall,"
|
||||||
long_opts+="createrepo::,createrepo-webroot:,createrepo-user:,"
|
long_opts+="createrepo::,createrepo-webroot:,createrepo-user:,"
|
||||||
long_opts+="vncpass:,display:,container:,tests,compat"
|
long_opts+="vncpass:,display:,container:,tests,compat,arch:"
|
||||||
short_opts="+i:vb::dhus:c:"
|
short_opts="+i:vb::dhus:c:"
|
||||||
|
|
||||||
|
# Redeclare DEBUG and catch permanently with getopt
|
||||||
|
declare -g DEBUG=0
|
||||||
|
|
||||||
if input=$(getopt -o $short_opts -l $long_opts -- "$@"); then
|
if input=$(getopt -o $short_opts -l $long_opts -- "$@"); then
|
||||||
eval set -- "$input"
|
eval set -- "$input"
|
||||||
while true; do
|
while true; do
|
||||||
@@ -176,6 +185,10 @@ parseInput() {
|
|||||||
MCVERSION="$1"
|
MCVERSION="$1"
|
||||||
USER_VERSION_SWITCH=1
|
USER_VERSION_SWITCH=1
|
||||||
;;
|
;;
|
||||||
|
--arch)
|
||||||
|
shift
|
||||||
|
USER_ARCH="$1"
|
||||||
|
;;
|
||||||
--restorefile)
|
--restorefile)
|
||||||
shift && RESTOREFILE="$1"
|
shift && RESTOREFILE="$1"
|
||||||
;;
|
;;
|
||||||
@@ -249,10 +262,11 @@ parseInput() {
|
|||||||
init() {
|
init() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
|
|
||||||
declare -g ID RPM_MGR
|
declare -g ID RPM_MGR ARCH
|
||||||
|
declare -ga PKG_INSTALL PKG_REMOVE PKG_UPDATE
|
||||||
|
|
||||||
echo "Starting installJRMC"
|
echo "Starting installJRMC"
|
||||||
debug || echo "To enable debugging output, use --debug or -d"
|
(( DEBUG )) || echo "To enable debugging output, use --debug or -d"
|
||||||
|
|
||||||
if [[ -e "/etc/os-release" ]]; then
|
if [[ -e "/etc/os-release" ]]; then
|
||||||
source "/etc/os-release"
|
source "/etc/os-release"
|
||||||
@@ -263,7 +277,16 @@ init() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
debug "Detected host platform: $ID $VERSION_ID"
|
# Detect architecture and translate to MC convention
|
||||||
|
# Also catch user input in getopt
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
case "$ARCH" in
|
||||||
|
x86_64)
|
||||||
|
ARCH="amd64"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
debug "Detected host platform: $ID $VERSION_ID $ARCH"
|
||||||
|
|
||||||
# normalize ID and set distro-specific vars
|
# normalize ID and set distro-specific vars
|
||||||
case "$ID" in
|
case "$ID" in
|
||||||
@@ -289,7 +312,7 @@ init() {
|
|||||||
ID="debian"
|
ID="debian"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
err "Autodetecting distro, this is unreliable and --compat may also be required"
|
err "Autodetecting distro, this is unreliable and --compat may be required"
|
||||||
if hash dnf &>/dev/null; then
|
if hash dnf &>/dev/null; then
|
||||||
ID="fedora"
|
ID="fedora"
|
||||||
RPM_MGR="dnf"
|
RPM_MGR="dnf"
|
||||||
@@ -312,33 +335,32 @@ init() {
|
|||||||
# Abstract distro-specific package manager commands
|
# Abstract distro-specific package manager commands
|
||||||
case "$ID" in
|
case "$ID" in
|
||||||
fedora|centos)
|
fedora|centos)
|
||||||
pkg_install(){ sudo "$RPM_MGR" install -y "$@"; }
|
PKG_INSTALL=(sudo "$RPM_MGR" install -y)
|
||||||
pkg_install_local() { installMCRPM; }
|
PKG_REMOVE=(sudo "$RPM_MGR" remove -y)
|
||||||
pkg_remove(){ sudo "$RPM_MGR" remove -y "$@"; }
|
PKG_UPDATE=(sudo "$RPM_MGR" makecache)
|
||||||
pkg_update(){ sudo "$RPM_MGR" makecache; }
|
PKG_QUERY(){ rpm -q "$@"; }
|
||||||
pkg_swap() { sudo dnf swap -y "$1" "$2"; }
|
PKG_INSTALL_LOCAL(){ installMCRPM; }
|
||||||
pkg_query(){ rpm -q "$@"; }
|
|
||||||
;;
|
;;
|
||||||
debian|ubuntu)
|
debian|ubuntu)
|
||||||
pkg_install(){ sudo apt-get install -y -q0 "$@"; }
|
PKG_INSTALL=(sudo apt-get -f install -y -q0)
|
||||||
pkg_install_local() { installMCDEB; }
|
PKG_REMOVE=(sudo apt-get remove --auto-remove -y -q0)
|
||||||
pkg_remove(){ sudo apt-get remove --auto-remove -y -q0 "$@"; }
|
PKG_UPDATE=(sudo apt-get update -y -q0)
|
||||||
pkg_update(){ sudo apt-get update -y -q0; }
|
PKG_QUERY(){ dpkg -s "$@"; }
|
||||||
pkg_query(){ dpkg -s "$@"; }
|
PKG_INSTALL_LOCAL(){ installMCDEB; }
|
||||||
;;
|
;;
|
||||||
suse)
|
suse)
|
||||||
pkg_install(){ sudo zypper --non-interactive -q install --force --no-confirm "$@"; }
|
PKG_INSTALL=(sudo zypper --non-interactive -q install --force --no-confirm)
|
||||||
pkg_install_local() { installMCRPM; }
|
PKG_REMOVE=(sudo zypper --non-interactive -q remove --clean-deps)
|
||||||
pkg_remove(){ sudo zypper --non-interactive -q remove --clean-deps "$@"; }
|
PKG_UPDATE=(sudo zypper --non-interactive -q refresh jriver)
|
||||||
pkg_update(){ sudo zypper --non-interactive -q refresh jriver; }
|
PKG_QUERY(){ rpm -q "$@"; }
|
||||||
pkg_query(){ rpm -q "$@"; }
|
PKG_INSTALL_LOCAL(){ installMCRPM; }
|
||||||
;;
|
;;
|
||||||
arch)
|
arch)
|
||||||
pkg_install(){ sudo pacman -Sy --noconfirm "$@"; }
|
PKG_INSTALL=(sudo pacman -Sy --noconfirm)
|
||||||
pkg_install_local() { installMCARCH; }
|
PKG_REMOVE=(sudo pacman -Rs --noconfirm)
|
||||||
pkg_remove(){ sudo pacman -Rs --noconfirm "$@"; }
|
PKG_UPDATE=(sudo pacman -Syy)
|
||||||
pkg_update(){ sudo pacman -Syy ; }
|
PKG_QUERY(){ sudo pacman -Qs "$@"; }
|
||||||
pkg_query(){ sudo pacman -Qs "$@"; }
|
PKG_INSTALL_LOCAL(){ installMCARCH; }
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -406,27 +428,27 @@ setMCVersion() {
|
|||||||
# Arguments:
|
# Arguments:
|
||||||
# One or more package names
|
# One or more package names
|
||||||
# Options:
|
# Options:
|
||||||
# --skip-check-installed: Do not check if package is already installed
|
# --no-install-check: Do not check if package is already installed
|
||||||
# --no-gpg-check: Disable GPG checks for RPM based distros
|
# --no-gpg-check: Disable GPG checks for RPM based distros
|
||||||
# --allow-downgrades: Useful for installing specific MC versions
|
# --allow-downgrades: Useful for installing specific MC versions
|
||||||
# --silent, -s: Do not report errors (useful if package is not strictly required and errors are noisy)
|
# --silent, -s: Do not print errors (useful for optional packages)
|
||||||
#######################################
|
#######################################
|
||||||
installPackage() {
|
installPackage() {
|
||||||
debug "Running: ${FUNCNAME[0]}" "$@"
|
debug "Running: ${FUNCNAME[0]}" "$@"
|
||||||
|
|
||||||
declare -a pkg_array install_flags pkg_install_cmd
|
declare -a pkg_array install_flags
|
||||||
declare long_opts input pkg
|
declare long_opts input pkg
|
||||||
declare skip_check_installed allow_downgrades silent refresh no_gpg_check
|
declare no_install_check allow_downgrades silent refresh no_gpg_check
|
||||||
declare -A pkg_aliases
|
declare -A pkg_aliases
|
||||||
|
|
||||||
long_opts="skip-check-installed,allow-downgrades,no-gpg-check,refresh,silent"
|
long_opts="no-install-check,allow-downgrades,no-gpg-check,refresh,silent"
|
||||||
|
|
||||||
if input=$(getopt -o +s -l "$long_opts" -- "$@"); then
|
if input=$(getopt -o +s -l "$long_opts" -- "$@"); then
|
||||||
eval set -- "$input"
|
eval set -- "$input"
|
||||||
while true; do
|
while true; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--skip-check-installed)
|
--no-install-check)
|
||||||
skip_check_installed=1
|
no_install_check=1
|
||||||
;;
|
;;
|
||||||
--allow-downgrades)
|
--allow-downgrades)
|
||||||
allow_downgrades=1
|
allow_downgrades=1
|
||||||
@@ -466,9 +488,9 @@ installPackage() {
|
|||||||
if [[ -v pkg_aliases[$pkg] ]]; then
|
if [[ -v pkg_aliases[$pkg] ]]; then
|
||||||
pkg=${pkg_aliases[$pkg]}
|
pkg=${pkg_aliases[$pkg]}
|
||||||
fi
|
fi
|
||||||
if (( skip_check_installed )) ||
|
if (( no_install_check )) ||
|
||||||
! (hash "$pkg" &>/dev/null ||
|
! (hash "$pkg" &>/dev/null ||
|
||||||
pkg_query "$pkg" &>/dev/null); then
|
PKG_QUERY "$pkg" &>/dev/null); then
|
||||||
pkg_array+=("$pkg")
|
pkg_array+=("$pkg")
|
||||||
else
|
else
|
||||||
debug "$pkg already installed, skipping installation"
|
debug "$pkg already installed, skipping installation"
|
||||||
@@ -492,7 +514,7 @@ installPackage() {
|
|||||||
|
|
||||||
# Install packages from package array
|
# Install packages from package array
|
||||||
if [[ ${#pkg_array[@]} -ge 1 ]]; then
|
if [[ ${#pkg_array[@]} -ge 1 ]]; then
|
||||||
if ! execute "pkg_install ${install_flags[*]} ${pkg_array[*]}"; then
|
if ! execute "${PKG_INSTALL[*]} ${install_flags[*]} ${pkg_array[*]}"; then
|
||||||
(( silent )) || err "Failed to install ${pkg_array[*]}. Attempting to continue"
|
(( silent )) || err "Failed to install ${pkg_array[*]}. Attempting to continue"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -507,8 +529,6 @@ installPackage() {
|
|||||||
installMCFromRepo() {
|
installMCFromRepo() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
|
|
||||||
declare -a pkg_install_cmd
|
|
||||||
|
|
||||||
case "$ID" in
|
case "$ID" in
|
||||||
fedora|centos)
|
fedora|centos)
|
||||||
sudo bash -c "cat <<-EOF > /etc/yum.repos.d/jriver.repo
|
sudo bash -c "cat <<-EOF > /etc/yum.repos.d/jriver.repo
|
||||||
@@ -519,8 +539,8 @@ installMCFromRepo() {
|
|||||||
EOF"
|
EOF"
|
||||||
;;
|
;;
|
||||||
debian|ubuntu)
|
debian|ubuntu)
|
||||||
repo_dir="/etc/apt/sources.list.d"
|
declare repo_dir="/etc/apt/sources.list.d"
|
||||||
[[ -d $repo_dir ]] || execute "sudo mkdir -p /etc/apt/sources.list.d"
|
[[ -d $repo_dir ]] || execute "sudo mkdir -p $repo_dir"
|
||||||
sudo rm -rf "$repo_dir"/mediacenter*.list
|
sudo rm -rf "$repo_dir"/mediacenter*.list
|
||||||
installPackage wget
|
installPackage wget
|
||||||
sudo bash -c "cat <<-EOF > $repo_dir/jriver.list
|
sudo bash -c "cat <<-EOF > $repo_dir/jriver.list
|
||||||
@@ -536,22 +556,19 @@ installMCFromRepo() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if ! execute "pkg_update"; then
|
if ! execute "${PKG_UPDATE[@]}"; then
|
||||||
err "Package update failed!"
|
err "Package update failed!"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install mesa-va-drivers-freeworld separately from the RPM for dnf swap
|
# Install mesa-va-drivers-freeworld separately from the RPM using dnf swap
|
||||||
installMesa
|
installMesa
|
||||||
|
|
||||||
pkg_install_cmd=(
|
if ! execute installPackage \
|
||||||
installPackage
|
--no-install-check \
|
||||||
--skip-check-installed
|
--allow-downgrades \
|
||||||
--allow-downgrades
|
--no-gpg-check \
|
||||||
--no-gpg-check
|
"$MCPKG"; then
|
||||||
"$MCPKG"
|
|
||||||
)
|
|
||||||
if ! execute "${pkg_install_cmd[*]}"; then
|
|
||||||
err "Package install failed!"
|
err "Package install failed!"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -564,7 +581,9 @@ installMCFromRepo() {
|
|||||||
acquireDeb() {
|
acquireDeb() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
|
|
||||||
declare -g MCDEB="$OUTPUTDIR/SOURCES/MediaCenter-$MCVERSION-amd64.deb"
|
declare -g MCDEB="$OUTPUTDIR/SOURCES/MediaCenter-$MCVERSION-${USER_ARCH:-$ARCH}.deb"
|
||||||
|
|
||||||
|
debug "MCDEB=$MCDEB"
|
||||||
|
|
||||||
# If necessary, create SOURCES dir
|
# If necessary, create SOURCES dir
|
||||||
[[ -d "$OUTPUTDIR/SOURCES" ]] || execute "mkdir -p $OUTPUTDIR/SOURCES"
|
[[ -d "$OUTPUTDIR/SOURCES" ]] || execute "mkdir -p $OUTPUTDIR/SOURCES"
|
||||||
@@ -577,13 +596,13 @@ acquireDeb() {
|
|||||||
|
|
||||||
if [[ -v BETAPASS ]] &&
|
if [[ -v BETAPASS ]] &&
|
||||||
echo "Checking beta repo for DEB package" && wget -q -O "$MCDEB" \
|
echo "Checking beta repo for DEB package" && wget -q -O "$MCDEB" \
|
||||||
"https://files.jriver.com/mediacenter/channels/v$MVERSION/beta/$BETAPASS/MediaCenter-$MCVERSION-amd64.deb"; then
|
"https://files.jriver.com/mediacenter/channels/v$MVERSION/beta/$BETAPASS/MediaCenter-$MCVERSION-${USER_ARCH:-$ARCH}.deb"; then
|
||||||
echo "Found!"
|
echo "Found!"
|
||||||
elif echo "Checking latest repo for DEB package" && wget -q -O "$MCDEB" \
|
elif echo "Checking latest repo for DEB package" && wget -q -O "$MCDEB" \
|
||||||
"https://files.jriver.com/mediacenter/channels/v$MVERSION/latest/MediaCenter-$MCVERSION-amd64.deb"; then
|
"https://files.jriver.com/mediacenter/channels/v$MVERSION/latest/MediaCenter-$MCVERSION-${USER_ARCH:-$ARCH}.deb"; then
|
||||||
echo "Found!"
|
echo "Found!"
|
||||||
elif echo "Checking test repo for DEB package" && wget -q -O "$MCDEB" \
|
elif echo "Checking test repo for DEB package" && wget -q -O "$MCDEB" \
|
||||||
"https://files.jriver.com/mediacenter/test/MediaCenter-$MCVERSION-amd64.deb"; then
|
"https://files.jriver.com/mediacenter/test/MediaCenter-$MCVERSION-${USER_ARCH:-$ARCH}.deb"; then
|
||||||
echo "Found!"
|
echo "Found!"
|
||||||
else
|
else
|
||||||
err "Cannot find DEB file"
|
err "Cannot find DEB file"
|
||||||
@@ -712,7 +731,7 @@ buildRPM() {
|
|||||||
Release: 1
|
Release: 1
|
||||||
Summary: JRiver Media Center
|
Summary: JRiver Media Center
|
||||||
Group: Applications/Media
|
Group: Applications/Media
|
||||||
Source0: http://files.jriver.com/mediacenter/channels/v$MVERSION/latest/MediaCenter-$MCVERSION-amd64.deb
|
Source0: http://files.jriver.com/mediacenter/channels/v$MVERSION/latest/MediaCenter-$MCVERSION-${USER_ARCH:-$ARCH}.deb
|
||||||
BuildArch: x86_64
|
BuildArch: x86_64
|
||||||
%define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm
|
%define _rpmfilename %%{ARCH}/%%{NAME}-%%{version}.%%{ARCH}.rpm
|
||||||
|
|
||||||
@@ -779,11 +798,6 @@ buildRPM() {
|
|||||||
installMCDEB() {
|
installMCDEB() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
|
|
||||||
declare pkg_install_cmd
|
|
||||||
pkg_install_cmd=(installPackage
|
|
||||||
--skip-check-installed
|
|
||||||
--no-gpg-check
|
|
||||||
--allow-downgrades)
|
|
||||||
if (( COMPAT_SWITCH )); then
|
if (( COMPAT_SWITCH )); then
|
||||||
declare extract_dir && extract_dir="$(mktemp -d)"
|
declare extract_dir && extract_dir="$(mktemp -d)"
|
||||||
pushd "$extract_dir" &>/dev/null || return
|
pushd "$extract_dir" &>/dev/null || return
|
||||||
@@ -800,8 +814,12 @@ installMCDEB() {
|
|||||||
popd &>/dev/null || return
|
popd &>/dev/null || return
|
||||||
rm -rf "$extract_dir"
|
rm -rf "$extract_dir"
|
||||||
fi
|
fi
|
||||||
pkg_install_cmd+=("$MCDEB")
|
|
||||||
execute "${pkg_install_cmd[*]}"
|
execute installPackage \
|
||||||
|
--no-install-check \
|
||||||
|
--no-gpg-check \
|
||||||
|
--allow-downgrades \
|
||||||
|
"$MCDEB"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -814,7 +832,7 @@ installMCRPM() {
|
|||||||
# Install mesa-va-freeworld separately from the RPM for dnf swap
|
# Install mesa-va-freeworld separately from the RPM for dnf swap
|
||||||
installMesa
|
installMesa
|
||||||
|
|
||||||
installPackage --skip-check-installed --no-gpg-check --allow-downgrades "$MCRPM"
|
installPackage --no-install-check --no-gpg-check --allow-downgrades "$MCRPM"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -824,24 +842,19 @@ installMCRPM() {
|
|||||||
installMesa() {
|
installMesa() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
|
|
||||||
declare -a pkg_swap_cmd
|
|
||||||
|
|
||||||
# Currently only necessary in Fedora/CentOS
|
# Currently only necessary in Fedora/CentOS
|
||||||
case "$ID" in
|
case "$ID" in
|
||||||
fedora|centos)
|
fedora|centos)
|
||||||
if ! pkg_query mesa-va-drivers-freeworld &>/dev/null; then
|
if ! PKG_QUERY mesa-va-drivers-freeworld &>/dev/null; then
|
||||||
if pkg_query mesa-va-drivers &>/dev/null; then
|
if PKG_QUERY mesa-va-drivers &>/dev/null; then
|
||||||
pkg_swap_cmd=(
|
if ! execute sudo dnf swap -y \
|
||||||
pkg_swap
|
mesa-va-drivers \
|
||||||
mesa-va-drivers
|
mesa-va-drivers-freeworld; then
|
||||||
mesa-va-drivers-freeworld
|
|
||||||
)
|
|
||||||
if ! execute "${pkg_swap_cmd[*]}"; then
|
|
||||||
err "Package swap failed!"
|
err "Package swap failed!"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
pkg_install mesa-va-drivers-freeworld
|
execute "${PKG_INSTALL[@]}" mesa-va-drivers-freeworld
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
@@ -855,9 +868,6 @@ installMesa() {
|
|||||||
installMCARCH() {
|
installMCARCH() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
|
|
||||||
declare -a makepkg_cmd
|
|
||||||
|
|
||||||
echo "Arch install under construction"
|
|
||||||
[[ -d "$OUTPUTDIR/PKGBUILD" ]] || mkdir -p "$OUTPUTDIR/PKGBUILD"
|
[[ -d "$OUTPUTDIR/PKGBUILD" ]] || mkdir -p "$OUTPUTDIR/PKGBUILD"
|
||||||
cat <<-EOF > "$OUTPUTDIR/PKGBUILD/mediacenter.pkgbuild"
|
cat <<-EOF > "$OUTPUTDIR/PKGBUILD/mediacenter.pkgbuild"
|
||||||
pkgname=mediacenter$MVERSION
|
pkgname=mediacenter$MVERSION
|
||||||
@@ -877,7 +887,7 @@ installMCARCH() {
|
|||||||
'vorbis-tools: ogg vorbis support'
|
'vorbis-tools: ogg vorbis support'
|
||||||
'musepack-tools: musepack support'
|
'musepack-tools: musepack support'
|
||||||
)
|
)
|
||||||
source=("http://files.jriver.com/mediacenter/channels/v30/latest/MediaCenter-$MCVERSION-amd64.deb")
|
source=("http://files.jriver.com/mediacenter/channels/v$MVERSION/latest/MediaCenter-$MCVERSION-${USER_ARCH:-$ARCH}.deb")
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
cd "\$srcdir"
|
cd "\$srcdir"
|
||||||
@@ -885,20 +895,19 @@ installMCARCH() {
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
makepkg_cmd=(makepkg --install
|
|
||||||
--syncdeps
|
|
||||||
--clean
|
|
||||||
--cleanbuild
|
|
||||||
--skipinteg
|
|
||||||
--force
|
|
||||||
--noconfirm
|
|
||||||
-p mediacenter.pkgbuild)
|
|
||||||
|
|
||||||
pushd "$OUTPUTDIR/PKGBUILD" &>/dev/null || return
|
pushd "$OUTPUTDIR/PKGBUILD" &>/dev/null || return
|
||||||
|
|
||||||
if ! execute "${makepkg_cmd[*]}"; then
|
if ! execute makepkg \
|
||||||
|
--install \
|
||||||
|
--syncdeps \
|
||||||
|
--clean \
|
||||||
|
--cleanbuild \
|
||||||
|
--skipinteg \
|
||||||
|
--force \
|
||||||
|
--noconfirm \
|
||||||
|
-p mediacenter.pkgbuild; then
|
||||||
echo "makepkg failed"
|
echo "makepkg failed"
|
||||||
exit
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
popd &>/dev/null || return
|
popd &>/dev/null || return
|
||||||
@@ -943,7 +952,7 @@ runCreaterepo() {
|
|||||||
[[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_cmd+=(--update)
|
[[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_cmd+=(--update)
|
||||||
if ! (execute "${cr_cmd[*]}" &&
|
if ! (execute "${cr_cmd[*]}" &&
|
||||||
execute "sudo chown -R $CREATEREPO_USER:$CREATEREPO_USER $CREATEREPO_WEBROOT"); then
|
execute "sudo chown -R $CREATEREPO_USER:$CREATEREPO_USER $CREATEREPO_WEBROOT"); then
|
||||||
err "Createrepo failed"
|
err "createrepo failed"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -956,49 +965,64 @@ runCreaterepo() {
|
|||||||
symlinkCerts() {
|
symlinkCerts() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
|
|
||||||
declare mc_cert_link="/usr/lib/jriver/MC30/ca-certificates.crt"
|
declare mc_cert_link="/usr/lib/jriver/MC$MVERSION/ca-certificates.crt"
|
||||||
declare target_cert
|
declare target_cert f
|
||||||
declare -a ln_cmd
|
declare -a source_certs=(
|
||||||
|
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"
|
||||||
|
"/var/lib/ca-certificates/ca-bundle.pem")
|
||||||
|
|
||||||
target_cert=$(readlink -f "$mc_cert_link")
|
target_cert=$(readlink -f "$mc_cert_link")
|
||||||
|
|
||||||
[[ -f $target_cert ]] && return 0
|
[[ -f $target_cert ]] && return 0
|
||||||
|
|
||||||
if [[ -f /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem ]]; then
|
for f in "${source_certs[@]}"; do
|
||||||
ln_cmd=(sudo ln -fs /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem "$mc_cert_link") # For RHEL/CentOS
|
if [[ -f "$f" ]]; then
|
||||||
elif [[ -f /var/lib/ca-certificates/ca-bundle.pem ]]; then
|
if ! execute ln -fs "$f" "$mc_cert_link"; then
|
||||||
ln_cmd=(sudo ln -fs /var/lib/ca-certificates/ca-bundle.pem "$mc_cert_link") # For SUSE
|
err "Symlinking certificate failed"
|
||||||
fi
|
|
||||||
|
|
||||||
if ! execute "${ln_cmd[*]}"; then
|
|
||||||
err "Symlinking certificates failed"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Restore the mjr license file if it is next to installJRMC or RESTOREFILE is set
|
# Restore the mjr license file from RESTOREFILE or other common locations
|
||||||
#######################################
|
#######################################
|
||||||
restoreLicense() {
|
restoreLicense() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
|
|
||||||
declare mjrfile
|
declare f newest
|
||||||
|
|
||||||
# Allow user to put the mjr file next to installJRMC
|
# Glob mjr files from common directories
|
||||||
if [[ ! -v RESTOREFILE ]]; then
|
shopt -s nullglob
|
||||||
for mjrfile in "$PWD"/*.mjr; do
|
declare -a mjrfiles=(
|
||||||
[[ $mjrfile -nt $RESTOREFILE ]] && RESTOREFILE="$mjrfile"
|
"$PWD"/*.mjr
|
||||||
|
"$OUTPUTDIR"/*.mjr
|
||||||
|
"$HOME"/[dD]ownloads/*.mjr
|
||||||
|
"$HOME"/[dD]ocuments/*.mjr
|
||||||
|
)
|
||||||
|
shopt -u nullglob
|
||||||
|
|
||||||
|
debug "mjrfiles=(${mjrfiles[*]})"
|
||||||
|
|
||||||
|
# Sort globbed files by time, newest first
|
||||||
|
newest=${mjrfiles[0]}
|
||||||
|
for f in "${mjrfiles[@]}"; do
|
||||||
|
if [[ -f $f && $f -nt $newest ]]; then
|
||||||
|
newest=$f
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
fi
|
|
||||||
|
|
||||||
# Restore license
|
debug "Latest mjrfile: $newest"
|
||||||
if [[ -f "$RESTOREFILE" ]]; then
|
|
||||||
if ! "mediacenter$MVERSION" /RestoreFromFile "$RESTOREFILE"; then
|
for f in "$RESTOREFILE" "$newest"; do
|
||||||
err "Automatic license restore failed"
|
if [[ -f "$f" ]]; then
|
||||||
return 1
|
if execute "mediacenter$MVERSION" "/RestoreFromFile" "$f"; then
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1062,7 +1086,7 @@ setVNCPass() {
|
|||||||
if [[ ! -v VNCPASS ]]; then
|
if [[ ! -v VNCPASS ]]; then
|
||||||
err "Refusing to overwrite existing $vncpassfile with an empty password"
|
err "Refusing to overwrite existing $vncpassfile with an empty password"
|
||||||
err "Remove existing $vncpassfile or use --vncpass ''"
|
err "Remove existing $vncpassfile or use --vncpass ''"
|
||||||
exit 1
|
return 1
|
||||||
else
|
else
|
||||||
rm -f "$vncpassfile"
|
rm -f "$vncpassfile"
|
||||||
fi
|
fi
|
||||||
@@ -1110,7 +1134,6 @@ setServiceVars() {
|
|||||||
declare -g USER_STRING DISPLAY_STRING GRAPHICAL_TARGET
|
declare -g USER_STRING DISPLAY_STRING GRAPHICAL_TARGET
|
||||||
declare -g RELOAD ENABLE DISABLE IS_ENABLED IS_ACTIVE
|
declare -g RELOAD ENABLE DISABLE IS_ENABLED IS_ACTIVE
|
||||||
declare -a systemctl_prefix
|
declare -a systemctl_prefix
|
||||||
|
|
||||||
declare service_name="$1"
|
declare service_name="$1"
|
||||||
declare service_type="${2:-${SERVICE_TYPE:-system}}"
|
declare service_type="${2:-${SERVICE_TYPE:-system}}"
|
||||||
declare service_dir="/usr/lib/systemd/$service_type"
|
declare service_dir="/usr/lib/systemd/$service_type"
|
||||||
@@ -1343,15 +1366,15 @@ service_jriver-x11vnc() {
|
|||||||
EOF"
|
EOF"
|
||||||
|
|
||||||
execute "$RELOAD" &&
|
execute "$RELOAD" &&
|
||||||
execute "$ENABLE $SERVICE_NAME" &&
|
execute "$ENABLE" "$SERVICE_NAME" &&
|
||||||
echo "x11vnc running on localhost:$PORT" &&
|
echo "x11vnc running on localhost:$PORT" &&
|
||||||
openFirewall "jriver-x11vnc" "$PORT/tcp"
|
openFirewall "jriver-x11vnc" "$PORT/tcp"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Starts and enables (at startup) an hourly service to build the latest version of JRiver Media
|
# Starts and enables (at startup) an hourly service to build the latest version of
|
||||||
# Center RPM from the source DEB and create/update an RPM repository
|
# JRiver Media Center RPM from the source DEB and create/update an RPM repository
|
||||||
#######################################
|
#######################################
|
||||||
service_jriver-createrepo() {
|
service_jriver-createrepo() {
|
||||||
debug "Running: ${FUNCNAME[0]}"
|
debug "Running: ${FUNCNAME[0]}"
|
||||||
@@ -1387,7 +1410,7 @@ service_jriver-createrepo() {
|
|||||||
EOF"
|
EOF"
|
||||||
|
|
||||||
execute "$RELOAD" &&
|
execute "$RELOAD" &&
|
||||||
execute "$ENABLE $TIMER_NAME"
|
execute "$ENABLE" "$TIMER_NAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1495,7 +1518,7 @@ disableCoW() {
|
|||||||
[[ -d "$dir" ]] || return
|
[[ -d "$dir" ]] || return
|
||||||
if [[ $(stat -f -c %T "$dir") == "btrfs" ]] &&
|
if [[ $(stat -f -c %T "$dir") == "btrfs" ]] &&
|
||||||
! lsattr -d "$dir" | cut -f1 -d" " | grep -q C; then
|
! lsattr -d "$dir" | cut -f1 -d" " | grep -q C; then
|
||||||
echo "Disabling CoW for $dir"
|
echo "Disabling Btrfs CoW for $dir"
|
||||||
execute "sudo chattr +C $dir"
|
execute "sudo chattr +C $dir"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -1516,7 +1539,7 @@ migrateLibrary() {
|
|||||||
[[ -d "$previous_config_path" ]] &&
|
[[ -d "$previous_config_path" ]] &&
|
||||||
mkdir -p "$current_config_path"; then
|
mkdir -p "$current_config_path"; then
|
||||||
echo "Migrating $previous_config_path to $current_config_path"
|
echo "Migrating $previous_config_path to $current_config_path"
|
||||||
cp -fa "$previous_config_path"/* "$current_config_path" &>/dev/null
|
execute cp -fa "$previous_config_path"/* "$current_config_path"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1571,7 +1594,7 @@ uninstall() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Uninstalling JRiver Media Center package"
|
echo "Uninstalling JRiver Media Center package"
|
||||||
if execute "pkg_remove $MCPKG"; then
|
if execute "${PKG_REMOVE[@]}" "$MCPKG"; then
|
||||||
echo "JRiver Media Center has been completely uninstalled"
|
echo "JRiver Media Center has been completely uninstalled"
|
||||||
echo "To remove your library files, run: rm -rf $HOME/.jriver"
|
echo "To remove your library files, run: rm -rf $HOME/.jriver"
|
||||||
elif [[ $? -eq 100 ]]; then
|
elif [[ $? -eq 100 ]]; then
|
||||||
@@ -1595,10 +1618,8 @@ main() {
|
|||||||
|
|
||||||
parseInput "$@"
|
parseInput "$@"
|
||||||
|
|
||||||
if (( DEBUG )); then
|
debug "Debugging on"
|
||||||
echo "Debugging on"
|
debug "installJRMC version: $SCRIPTVERSION"
|
||||||
echo "installJRMC version: $SCRIPTVERSION"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ((TEST_SWITCH)); then
|
if ((TEST_SWITCH)); then
|
||||||
echo "Running tests, all other options are skipped"
|
echo "Running tests, all other options are skipped"
|
||||||
@@ -1632,14 +1653,14 @@ main() {
|
|||||||
echo "Adding EPEL repository"
|
echo "Adding EPEL repository"
|
||||||
installPackage epel-release
|
installPackage epel-release
|
||||||
fi
|
fi
|
||||||
if ! pkg_query rpmfusion-free-release &>/dev/null; then
|
if ! PKG_QUERY rpmfusion-free-release &>/dev/null; then
|
||||||
installPackage --skip-check-installed \
|
installPackage --no-install-check \
|
||||||
"https://download1.rpmfusion.org/free/el/rpmfusion-free-release-$VERSION_ID.noarch.rpm"
|
"https://download1.rpmfusion.org/free/el/rpmfusion-free-release-$VERSION_ID.noarch.rpm"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
fedora)
|
fedora)
|
||||||
if ! pkg_query rpmfusion-free-release &>/dev/null; then
|
if ! PKG_QUERY rpmfusion-free-release &>/dev/null; then
|
||||||
installPackage --skip-check-installed \
|
installPackage --no-install-check \
|
||||||
"https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$VERSION_ID.noarch.rpm"
|
"https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$VERSION_ID.noarch.rpm"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
@@ -1670,7 +1691,7 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if (( LOCAL_INSTALL_SWITCH )); then
|
if (( LOCAL_INSTALL_SWITCH )); then
|
||||||
if pkg_install_local; then
|
if PKG_INSTALL_LOCAL; then
|
||||||
echo "JRiver Media Center installed successfully from local package"
|
echo "JRiver Media Center installed successfully from local package"
|
||||||
else
|
else
|
||||||
err "JRiver Media Center local package installation failed"
|
err "JRiver Media Center local package installation failed"
|
||||||
@@ -1715,7 +1736,7 @@ main() {
|
|||||||
# done
|
# done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Quickly turn debugging on, also use getopt in parseInput()
|
# Roughly turn debugging on, reparse in getInput() with getopt
|
||||||
[[ " $* " =~ ( --debug | -d ) ]] && declare -g DEBUG=1
|
[[ " $* " =~ ( --debug | -d ) ]] && declare -g DEBUG=1
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user