Add --service-type and rework permissions

This commit is contained in:
2022-01-10 15:03:11 -05:00
parent 76e1c5e908
commit a5ff3d9fe1
2 changed files with 122 additions and 96 deletions

View File

@@ -35,8 +35,8 @@ You can always find the latest supported options by running `installJRMC --help`
Enter beta team password for access to beta builds Enter beta team password for access to beta builds
--service, -s SERVICE --service, -s SERVICE
See SERVICES section below for the list of services to deploy See SERVICES section below for the list of services to deploy
--service-user USER --service-type user|system
Install systemd services and containers for user USER (Default: executing user) Starts services at boot (system) or at user login (user) (Default: boot)
--container, -c CONTAINER (TODO: Under construction) --container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of containers to deploy See CONTAINERS section below for a list of containers to deploy
--createrepo --createrepo
@@ -46,7 +46,7 @@ You can always find the latest supported options by running `installJRMC --help`
--createrepo-user USER --createrepo-user USER
The web server user (Default: current user) The web server user (Default: current user)
--compat --compat
Build/install RPM without minimum library specifiers. Build/install RPM without minimum library specifiers
--version, -v --version, -v
Print this script version and exit Print this script version and exit
--debug, -d --debug, -d
@@ -59,7 +59,7 @@ You can always find the latest supported options by running `installJRMC --help`
### services ### services
When installing systemd services it is important to execute `installJRMC` as the user you wish to run the services. Typically this is your normal user account but for some installations (container) it may be necessary to execute the script as root. If so, use `--service-user root` to override safety checks. When installing systemd services it is important to execute `installJRMC` as the user you wish to run the services. Typically this is your normal user account but for some installations (e.g. containers, servers) it may be necessary to run as root.
```text ```text
jriver-mediaserver jriver-mediaserver

View File

@@ -19,10 +19,11 @@
shopt -s extglob shopt -s extglob
SCRIPTVERSION="1.0b6" declare -g SCRIPTVERSION="1.0b6"
OUTPUTDIR="$PWD/output" declare -g OUTPUTDIR="$PWD/output"
CREATEREPO_WEBROOT="/var/www/jriver" declare -g CREATEREPO_WEBROOT="/var/www/jriver"
SERVICEDIR="/usr/lib/systemd/system" declare -g USER && USER="${USER:-$(id -un)}"
declare -g USER_HOME && USER_HOME=$(grep "$USER" < /etc/passwd | cut -d":" -f6)
# MC version # MC version
# MCVERSION="28.0.87" # to set manually, if unset use automatic latest check # MCVERSION="28.0.87" # to set manually, if unset use automatic latest check
@@ -47,17 +48,15 @@ printHelp() {
--mcversion VERSION --mcversion VERSION
Specify the MC version, ex. "28.0.94" (Default: latest) Specify the MC version, ex. "28.0.94" (Default: latest)
--outputdir PATH --outputdir PATH
Generate rpmbuild output in this directory (Default: $PWD/output) Generate rpmbuild output in this directory (Default: ./output)
--restorefile RESTOREFILE --restorefile RESTOREFILE
Restore file location for automatic license registration (Default: skip registration) Restore file location for automatic license registration (Default: skip registration)
--betapass PASSWORD --betapass PASSWORD
Enter beta team password for access to beta builds Enter beta team password for access to beta builds
--service, -s SERVICE --service, -s SERVICE
See SERVICES section below for a list of possible services to install See SERVICES section below for a list of possible services to install
--service-user USER
Install systemd services and containers for user USER (Default: current user)
--service-type user|system --service-type user|system
Installs service(s) as a system or user service (Default: per-service) Starts services at boot (system) or at user login (user) (Default: boot)
--container, -c CONTAINER (TODO: Under construction) --container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of possible services to install See CONTAINERS section below for a list of possible services to install
--createrepo --createrepo
@@ -65,7 +64,7 @@ printHelp() {
--createrepo-webroot PATH --createrepo-webroot PATH
Specify the webroot directory to install the repo (Default: /var/www/jriver) Specify the webroot directory to install the repo (Default: /var/www/jriver)
--createrepo-user USER --createrepo-user USER
Specify the web server user Specify the web server user if it differs from $USER
--compat --compat
Build/install RPM without minimum library specifiers Build/install RPM without minimum library specifiers
--version, -v --version, -v
@@ -108,51 +107,44 @@ init() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare version_source declare version_source
declare -g USER SERVICE_USER CREATEREPO_USER MCVERSION MVERSION MCPKG declare -g MCVERSION MVERSION MCPKG
declare -g CREATEREPO_USER="${CREATEREPO_USER:-$USER}"
getOS getOS
USER="${USER:-$(id -un)}"
SERVICE_USER="${SERVICE_USER:-$USER}"
CREATEREPO_USER="${CREATEREPO_USER:-$USER}"
# Make sure universe repo is installed on Ubuntu # Make sure universe repo is installed on Ubuntu
if [[ "$ID" == "ubuntu" ]]; then if [[ "$ID" == "ubuntu" ]]; then
if ! grep ^deb /etc/apt/sources.list|grep -q universe; then if ! grep ^deb /etc/apt/sources.list|grep -q universe; then
ifSudo add-apt-repository universe sudo add-apt-repository universe
fi fi
fi fi
# Agnostic commands # Agnostic commands
bash_cmd(){ ifSudo bash -c "$@"; } bash_cmd(){ sudo bash -c "$@"; }
rm_cmd(){ ifSudo rm -rf "$@"; } cp_cmd(){ sudo cp -nf "$@"; }
cp_cmd(){ ifSudo cp -n -f "$@"; } mkdir_cmd(){ sudo mkdir -p "$@"; }
mkdir_cmd(){ ifSudo mkdir -p "$@"; } chown_cmd(){ sudo chown "$1":"$1" -R "${@:2}"; }
chown_cmd(){ ifSudo chown "$1":"$1" -R "${@:2}"; } ln_cmd(){ sudo ln -s "$@"; }
ln_cmd(){ ifSudo ln -s "$@"; }
systemctl_reload(){ ifSudo systemctl daemon-reload; }
systemctl_enable(){ ifSudo systemctl enable --now "$@"; }
systemctl_disable(){ ifSudo systemctl disable --now "$@"; }
# OS-specific commands # OS-specific commands
if [[ "$ID" =~ ^(fedora|centos)$ ]]; then if [[ "$ID" =~ ^(fedora|centos)$ ]]; then
pkg_install(){ ifSudo dnf install -y "$@"; } pkg_install(){ sudo dnf install -y "$@"; }
pkg_remove(){ ifSudo dnf remove -y "$@"; } pkg_remove(){ sudo dnf remove -y "$@"; }
pkg_update(){ ifSudo dnf makecache; } pkg_update(){ sudo dnf makecache; }
pkg_query(){ rpm -q "$@"; } pkg_query(){ rpm -q "$@"; }
firewall_cmd(){ ifSudo firewall-cmd "$@"; } firewall_cmd(){ sudo firewall-cmd "$@"; }
elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
pkg_install(){ ifSudo apt-get install -y -q0 "$@"; } pkg_install(){ sudo apt-get install -y -q0 "$@"; }
pkg_remove(){ ifSudo apt-get remove --auto-remove -y -q0 "$@"; } pkg_remove(){ sudo apt-get remove --auto-remove -y -q0 "$@"; }
pkg_update(){ ifSudo apt-get update -y -q0; } pkg_update(){ sudo apt-get update -y -q0; }
pkg_query(){ dpkg -s "$@"; } pkg_query(){ dpkg -s "$@"; }
firewall_cmd(){ ifSudo ufw "$@"; } firewall_cmd(){ sudo ufw "$@"; }
elif [[ "$ID" =~ ^opensuse.* ]]; then elif [[ "$ID" =~ ^opensuse.* ]]; then
pkg_install(){ ifSudo zypper --non-interactive -q install --force --no-confirm "$@"; } pkg_install(){ sudo zypper --non-interactive -q install --force --no-confirm "$@"; }
pkg_remove(){ ifSudo zypper --non-interactive -q remove --clean-deps "$@"; } pkg_remove(){ sudo zypper --non-interactive -q remove --clean-deps "$@"; }
pkg_update(){ ifSudo zypper --non-interactive -q refresh jriver; } pkg_update(){ sudo zypper --non-interactive -q refresh jriver; }
pkg_query(){ rpm -q "$@"; } pkg_query(){ rpm -q "$@"; }
firewall_cmd(){ ifSudo firewall-cmd "$@"; } firewall_cmd(){ sudo firewall-cmd "$@"; }
fi fi
parseInput "$@" parseInput "$@"
@@ -166,7 +158,7 @@ init() {
[[ ! "$MCVERSION" =~ ([0-9]+.[0-9]+.[0-9]+) ]] && err "Invalid version number" && exit 1 [[ ! "$MCVERSION" =~ ([0-9]+.[0-9]+.[0-9]+) ]] && err "Invalid version number" && exit 1
echo "Using MC version $MCVERSION determined by $version_source" echo "Using MC version $MCVERSION determined by $version_source"
[[ "$version_source" != "user input" ]] && echo "To override, use --MCVERSION" [[ "$version_source" != "user input" ]] && echo "To override, use --mcversion"
# Extract major version number # Extract major version number
MVERSION="${MCVERSION%%.*}" MVERSION="${MCVERSION%%.*}"
@@ -194,7 +186,6 @@ askOk() {
return $? return $?
} }
getOS() { getOS() {
debug "Running: ${FUNCNAME[0]}"
if [[ -e "/etc/os-release" ]]; then if [[ -e "/etc/os-release" ]]; then
source "/etc/os-release" source "/etc/os-release"
else else
@@ -206,36 +197,40 @@ getOS() {
} }
ifSudo() { # ifSudo() {
declare user="root" # declare user="root"
if [[ $# == 0 ]]; then # if [[ $# == 0 ]]; then
[[ "$USER" == "root" ]] # [[ "$USER" == "root" ]]
return $? # return $?
elif [[ $# -eq 2 && "$1" == "-u" ]]; then # elif [[ $# -eq 2 && "$1" == "-u" ]]; then
user="$2" # user="$2"
[[ "$USER" == "$user" ]] # [[ "$USER" == "$user" ]]
return $? # return $?
elif [[ $# -gt 2 && "$1" == "-u" ]]; then # elif [[ $# -gt 2 && "$1" == "-u" ]]; then
user="$2" # user="$2"
shift 2 # shift 2
fi # fi
if [[ "$user" == "$USER" ]]; then # if [[ "$user" == "$USER" ]]; then
"$@" # "$@"
else # else
sudo -u "$user" "$@" # sudo -u "$user" "$@"
fi # fi
} # }
parseInput() { parseInput() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare -g BUILD_SWITCH COMPAT_SWITCH CREATEREPO_SWITCH UNINSTALL_SWITCH
declare -g INSTALL_TYPE TARGET OUTPUTDIR MCVERSION RESTOREFILE BETAPASS SERVICE_TYPE VNCPASS USER_DISPLAY CREATEREPO_WEBROOT CREATEREPO_USER
declare -ga SERVICES CONTAINERS
if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then if [[ $# -eq 0 ]] || [[ $# -eq 1 && "$1" =~ ^(--debug|-d)$ ]]; then
echo "No options passed, defaulting to repo installation method" echo "No options passed, defaulting to repo installation method"
INSTALL_TYPE="repo" INSTALL_TYPE="repo"
fi fi
if _input=$(getopt -o +i:vdhus:c: -l install:,build,target:,outputdir:,mcversion:,restorefile:,betapass:,service-user:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container:,tests,compat -- "$@"); then if _input=$(getopt -o +i:vdhus:c: -l install:,build,target:,outputdir:,mcversion:,restorefile:,betapass:,service-type:,service:,version,debug,help,uninstall,createrepo,createrepo-webroot:,createrepo-user:,vncpass:,display:,container:,tests,compat -- "$@"); then
eval set -- "$_input" eval set -- "$_input"
while true; do while true; do
case "$1" in case "$1" in
@@ -268,8 +263,8 @@ parseInput() {
--betapass) --betapass)
shift && BETAPASS="$1" shift && BETAPASS="$1"
;; ;;
--service-user) --service-type)
shift && SERVICE_USER="$1" shift && SERVICE_TYPE="$1"
;; ;;
--service|-s) --service|-s)
shift && SERVICES+=("$1") shift && SERVICES+=("$1")
@@ -336,6 +331,7 @@ getLatestVersion() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare -g MCVERSION BASE BOARDURL declare -g MCVERSION BASE BOARDURL
declare cnt
# Latest defaults # Latest defaults
BASE="buster" # For container method BASE="buster" # For container method
@@ -381,16 +377,16 @@ getLatestVersion() {
# Use a containerized package manager # Use a containerized package manager
# TODO but how to determine build distro ($BASE=buster)? # TODO but how to determine build distro ($BASE=buster)?
installPackage --silent buildah installPackage --silent buildah
if CNT=$(buildah from debian:$BASE) &>/dev/null; then if cnt=$(buildah from debian:$BASE) &>/dev/null; then
buildah run "$CNT" -- bash -c \ buildah run "$cnt" -- bash -c \
"echo 'deb [trusted=no arch=amd64,i386,armhf,arm64] http://dist.jriver.com/latest/mediacenter/ $BASE main' > /etc/apt/sources.list 2>&1" "echo 'deb [trusted=no arch=amd64,i386,armhf,arm64] http://dist.jriver.com/latest/mediacenter/ $BASE main' > /etc/apt/sources.list 2>&1"
buildah run "$CNT" -- bash -c \ buildah run "$cnt" -- bash -c \
"apt-get update --allow-insecure-repositories &>/dev/null" "apt-get update --allow-insecure-repositories &>/dev/null"
if MCVERSION=$(buildah run "$CNT" -- apt-cache policy mediacenter?? | grep Candidate | awk '{print $2}' | sort -V | tail -n1) \ if MCVERSION=$(buildah run "$CNT" -- apt-cache policy mediacenter?? | grep Candidate | awk '{print $2}' | sort -V | tail -n1) \
&& [[ "$MCVERSION" =~ ([0-9]+.[0-9]+.[0-9]+) ]]; then && [[ "$MCVERSION" =~ ([0-9]+.[0-9]+.[0-9]+) ]]; then
version_source="containerized package manager" version_source="containerized package manager"
fi fi
buildah rm "$CNT" &>/dev/null buildah rm "$cnt" &>/dev/null
return 0 return 0
fi fi
# Scrape from Interact # Scrape from Interact
@@ -504,10 +500,10 @@ addRepo() {
elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then elif [[ "$ID" =~ ^(debian|ubuntu|linuxmint)$ ]]; then
# MVERSION depends on $BASE unless --mcversion is passed # MVERSION depends on $BASE unless --mcversion is passed
installPackage wget installPackage wget
wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | ifSudo apt-key add - &>/dev/null wget -q "http://dist.jriver.com/mediacenter@jriver.com.gpg.key" -O- | sudo apt-key add - &>/dev/null
ifSudo wget "http://dist.jriver.com/latest/mediacenter/mediacenter$MVERSION.list" -O "/etc/apt/sources.list.d/mediacenter$MVERSION.list" &>/dev/null sudo wget "http://dist.jriver.com/latest/mediacenter/mediacenter$MVERSION.list" -O "/etc/apt/sources.list.d/mediacenter$MVERSION.list" &>/dev/null
elif [[ "$ID" =~ ^opensuse.* ]]; then elif [[ "$ID" =~ ^opensuse.* ]]; then
ifSudo zypper addrepo --no-gpgcheck "https://repos.bryanroessler.com/jriver" jriver &>/dev/null sudo zypper addrepo --no-gpgcheck "https://repos.bryanroessler.com/jriver" jriver &>/dev/null
fi fi
} }
@@ -814,7 +810,7 @@ runCreaterepo() {
[[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_cmd+=" --update" [[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_cmd+=" --update"
debug "$cr_cmd $CREATEREPO_WEBROOT" || cr_cmd+=" &>/dev/null" debug "$cr_cmd $CREATEREPO_WEBROOT" || cr_cmd+=" &>/dev/null"
if ! eval "$cr_cmd $CREATEREPO_WEBROOT"; then if ! eval "$cr_cmd $CREATEREPO_WEBROOT"; then
cr_cmd="ifSudo createrepo -q" cr_cmd="sudo createrepo -q"
[[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_cmd+=" --update" [[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_cmd+=" --update"
debug "$cr_cmd $CREATEREPO_WEBROOT" || cr_cmd+=" &>/dev/null" debug "$cr_cmd $CREATEREPO_WEBROOT" || cr_cmd+=" &>/dev/null"
if ! eval "$cr_cmd $CREATEREPO_WEBROOT"; then if ! eval "$cr_cmd $CREATEREPO_WEBROOT"; then
@@ -1010,19 +1006,44 @@ setDisplay() {
setServiceVars() { setServiceVars() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare -g SERVICE_FNAME TIMER_FNAME SERVICE_NAME SERVICE_FNAME USER_STRING declare -g SERVICE_NAME SERVICE_FNAME TIMER_NAME TIMER_FNAME USER_STRING
if [[ "$SERVICE_USER" == "root" ]]; then declare service_system_dir="/usr/lib/systemd/system"
SERVICE_FNAME="$SERVICEDIR/${1}.service" declare service_user_dir="$USER_HOME/.config/systemd/user"
TIMER_FNAME="$SERVICEDIR/${1}.timer"
SERVICE_TYPE="${SERVICE_TYPE:-'system'}"
if [[ "$USER" == "root" && "$SERVICE_TYPE" == "user" ]]; then
err "Trying to install user service as root"
err "Use --service-type service and/or execute installJRMC as non-root user"
return 1
fi
if [[ "$SERVICE_TYPE" == "system" ]]; then # i.e. systemd system service
service_dir="$service_system_dir"
systemctl_reload_cmd(){ sudo systemctl daemon-reload; }
systemctl_enable_cmd(){ sudo systemctl enable --now "$@"; }
systemctl_disable_cmd(){ sudo systemctl disable --now "$@"; }
elif [[ "$SERVICE_TYPE" == "user" ]]; then # i.e. systemd user service
service_dir="$service_user_dir"
systemctl_reload_cmd(){ systemctl --user daemon-reload; }
systemctl_enable_cmd(){ systemctl --user enable --now "$@"; }
systemctl_disable_cmd(){ systemctl --user disable --now "$@"; }
fi
[[ ! -d "$service_dir" ]] && mkdir_cmd "$service_dir"
if [[ "$USER" == "root" || "$SERVICE_TYPE" == "user" ]]; then
SERVICE_NAME="${1}.service" SERVICE_NAME="${1}.service"
TIMER_NAME="${1}.timer" TIMER_NAME="${1}.timer"
SERVICE_FNAME="$service_dir/${SERVICE_NAME}"
TIMER_FNAME="$service_dir/${TIMER_NAME}"
USER_STRING="" USER_STRING=""
else else
SERVICE_FNAME="$SERVICEDIR/${1}@.service" SERVICE_FNAME="$service_dir/${1}@.service"
TIMER_FNAME="$SERVICEDIR/${1}@.timer" TIMER_FNAME="$service_dir/${1}@.timer"
SERVICE_NAME="${1}@$SERVICE_USER.service" SERVICE_NAME="${1}@$USER.service"
TIMER_NAME="${1}@$SERVICE_USER.timer" TIMER_NAME="${1}@$USER.timer"
USER_STRING="User=%I" USER_STRING="User=%I"
fi fi
} }
@@ -1105,7 +1126,7 @@ service_jriver-xvnc() {
Restart=always Restart=always
[Install] [Install]
WantedBy=multi-user.target WantedBy=default.target
EOF" EOF"
systemctl_reload && \ systemctl_reload && \
@@ -1158,7 +1179,7 @@ service_jriver-x11vnc() {
RestartSec=10 RestartSec=10
[Install] [Install]
WantedBy=multi-user.target WantedBy=default.target
EOF" EOF"
systemctl_reload && \ systemctl_reload && \
@@ -1375,7 +1396,9 @@ uninstall() {
debug "Stopping and removing all associated Media Center services" debug "Stopping and removing all associated Media Center services"
for service in $(compgen -A "function" "service"); do for service in $(compgen -A "function" "service"); do
service="${service##service_}" service="${service##service_}"
setServiceVars "$service" if ! setServiceVars "$service"; then
continue
fi
for unit in "$SERVICE_NAME" "$TIMER_NAME"; do for unit in "$SERVICE_NAME" "$TIMER_NAME"; do
if systemctl is-active -q "$unit" &>/dev/null || systemctl is-enabled -q "$unit" &>/dev/null; then if systemctl is-active -q "$unit" &>/dev/null || systemctl is-enabled -q "$unit" &>/dev/null; then
debug "Disabling $unit" debug "Disabling $unit"
@@ -1394,7 +1417,7 @@ uninstall() {
[[ -f "/etc/apt/sources.list.d/jriver.list" ]] \ [[ -f "/etc/apt/sources.list.d/jriver.list" ]] \
&& rm_cmd "/etc/apt/sources.list.d/jriver.list" && rm_cmd "/etc/apt/sources.list.d/jriver.list"
if [[ "$ID" =~ ^opensuse.* ]]; then if [[ "$ID" =~ ^opensuse.* ]]; then
ifSudo zypper rr jriver &>/dev/null sudo zypper rr jriver &>/dev/null
fi fi
debug "Removing firewall rules" debug "Removing firewall rules"
@@ -1442,6 +1465,8 @@ tests() {
main() { main() {
debug "Running: ${FUNCNAME[0]}" debug "Running: ${FUNCNAME[0]}"
declare service
init "$@" init "$@"
# Uninstall and exit # Uninstall and exit
@@ -1503,14 +1528,15 @@ main() {
# Install services # Install services
if [[ "${#SERVICES[@]}" -gt 0 ]]; then if [[ "${#SERVICES[@]}" -gt 0 ]]; then
setDisplay setDisplay
! [[ -d "$SERVICEDIR" ]] && ifSudo mkdir -p "$SERVICEDIR" for service in "${SERVICES[@]}"; do
for _service in "${SERVICES[@]}"; do if ! setServiceVars "$service"; then
setServiceVars "$_service" continue
if ! "service_$_service"; then fi
if ! "service_$service"; then
if [[ $? -eq 127 ]]; then if [[ $? -eq 127 ]]; then
err "Service $_service does not exist, check your service name" err "Service $service does not exist, check your service name"
else else
err "Failed to create service: $_service" err "Failed to create service: $service"
fi fi
fi fi
done done