20 Commits

Author SHA1 Message Date
29a1f665e9 1.35.14 release 2026-04-14 01:19:42 -04:00
fba72964fc Make createrepo service names explicit 2026-04-14 01:06:00 -04:00
32afb91dc9 Always run createrepo service as root 2026-04-14 00:58:43 -04:00
1eda1889a8 Don't run createrepo on service creation 2026-04-14 00:43:04 -04:00
dd19c0d794 Run rpmbuild as signing user 2026-04-14 00:37:27 -04:00
1f31922bb4 Always run createrepo service as user 2026-04-14 00:32:10 -04:00
04952eeea9 Surface rpmsign errors 2026-04-14 00:19:00 -04:00
26f09e0ae9 Let DNF handle key import 2026-04-14 00:00:21 -04:00
ed5e08fb20 Fix repo metadata temp file ownership 2026-04-13 23:46:15 -04:00
e8ac6048f3 Fix gpg repo signing command 2026-04-13 23:38:16 -04:00
d933d6bebc Add gpg signing debugging 2026-04-13 23:33:22 -04:00
edb281dad6 Skip running createrepo when generating service 2026-04-13 23:04:05 -04:00
0eebaf8fc0 Sign repomd_xml.asc to a temp file and move to webroot 2026-04-13 22:58:08 -04:00
3c43f546d0 Only install external repos for MC package install 2026-04-13 22:48:24 -04:00
f3a662f058 Pass --debug to createrepo service 2026-04-13 22:32:43 -04:00
6c6c0f6818 Use command array for createrepo service 2026-04-13 22:26:47 -04:00
7c4c36626f Debug webroot user 2026-04-13 22:13:06 -04:00
05c5a5299e Add missing webroot user 2026-04-13 21:56:29 -04:00
6e54c92103 jriver-createrepo: install script to /opt/installJRMC 2026-04-13 21:41:36 -04:00
93026c166b Add optional repo and rpm GPG signing 2026-04-13 21:26:27 -04:00
3 changed files with 338 additions and 105 deletions

View File

@@ -23,19 +23,19 @@ Specifying [tt]--build[/tt], [tt]--createrepo[/tt], [tt]--service[/tt], or [tt]-
[code]
$ installJRMC --help
--install, -i repo|local
repo: Install MC from repository, future updates will be handled by the system package manager.
local: Build and install MC package from official source package.
--build[=suse|fedora|centos]
repo: Install MC from repository, updates are handled by the system package manager.
local: Build and install MC locally from official source package.
--build[=suse|fedora|centos|mandriva]
Build RPM from source DEB but do not install.
Optionally, specify a target distro for cross-building (ex. --build=suse, note the '=').
--compat
Build/install MC without minimum dependency version requirements.
Build/install MC locally without minimum dependency version requirements.
--mcversion VERSION
Specify the MC version, ex. "33", "35.0.51", or "35.0.51-1" (default: latest).
Specify the MC version, ex. "35.0.68" or "35" (default: latest release).
--arch ARCH
Specify the target MC architecture, ex. "amd64", "arm64", etc (default: host architecture).
Specify the target MC architecture, ex. "amd64", "arm64", etc (default: host).
--mcrepo REPO
Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: host or official).
Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: auto).
--outputdir PATH
Generate reusable installJRMC output in this PATH (default: ./output).
--restorefile RESTOREFILE
@@ -43,30 +43,41 @@ $ installJRMC --help
--betapass PASSWORD
Enter beta team password for access to beta builds.
--service, -s SERVICE
See SERVICES section below for the list of services to deploy.
See SERVICES below for possible services to install.
--service-type user|system
Starts services at boot (system) or user login (user) (default: per-service, see SERVICES).
--container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of containers to deploy.
--createrepo[=suse|fedora|centos]
Build rpm, copy to webroot, and run createrepo.
Optionally, specify a target distro for non-native repo (ex. --createrepo=fedora, note the '=').
--createrepo-webroot PATH
The webroot directory to install the repo (default: /var/www/jriver/).
--createrepo-user USER
The web server user if different from the current user.
Starts services at boot (system) or at user login (user) (default: per service, see SERVICES).
--no-update
Disable the installJRMC update check.
Disable automatic installJRMC self-update.
--uninstall, -u
Uninstall JRiver MC, remove services, containers, and firewall rules (does not remove library files).
--yes, -y, --auto
Always assumes yes for questions.
Assume yes response to questions.
--version, -v
Print installJRMC version and exit.
--debug, -d
Print debug output.
--help, -h
Print help dialog and exit.
--uninstall, -u
Uninstall JRiver MC, service files, firewall rules, etc.
ADVANCED OPTIONS
--container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of possible services to install.
--createrepo[=suse|fedora|centos]
Build rpm, copy to webroot, and run createrepo.
Use in conjunction with --build=TARGET for crossbuilding repos.
Optionally, specify a target distro for non-native repo (ex. --createrepo=fedora).
--createrepo-webroot PATH
Specify the webroot directory to install the repo (default: /var/www/jriver).
--webroot-user USER
Owner/user for createrepo output in the webroot (default: current user).
--createrepo-user USER
Backward-compatible alias for --webroot-user.
--sign
Sign the built RPM and repodata/repomd.xml (if --createrepo).
--sign-user USER
User account used to run rpmsign and gpg signing (default: current user).
--sign-key KEYID
GPG key ID, fingerprint, or UID used for --sign.
[/code]
[size=18pt]Services[/size]
@@ -126,12 +137,14 @@ Install the latest version of MC33 from the best available repository with debug
Install a more widely-compatible version of the latest MC version.
[code]installJRMC --install repo --service jriver-mediacenter --service-type user[/code]
Install MC from the repository and start/enable jriver-mediacenter.service as a user service.
[code]installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 35.0.51[/code]
Build and install an MC 35.0.51 comptability RPM locally and activate it using the [tt]/path/to/license.mjr[/tt].
[code]installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user[/code]
[code]installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 35.0.68[/code]
Build and install an MC 35.0.68 comptability RPM locally and activate it using the [tt]/path/to/license.mjr[/tt].
[code]installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --webroot-user www-user[/code]
Build an RPM locally for the current distro, move it to the webroot, and run createrepo as www-user.
[code]installJRMC --service jriver-createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user[/code]
[code]installJRMC --service jriver-createrepo --createrepo-webroot /srv/jriver/repo --webroot-user www-user[/code]
Install the jriver-createrepo timer and service to build the RPM, move it to the webroot, and run createrepo as www-user hourly.
[code]installJRMC --createrepo --webroot-user nginx --sign --sign-user bryan --sign-key 0xDEADBEEF[/code]
Build/update the RPM repo, sign both RPM and repodata as bryan, and publish files owned by nginx.
[code]installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"[/code]
Install services to share the existing local desktop via VNC and automatically run MC on startup.
[code]installJRMC --install repo --service jriver-xvnc --display ":2"[/code]

View File

@@ -20,50 +20,61 @@ Specifying `--build`, `--createrepo`, `--service`, or `--uninstall` disables the
```text
$ installJRMC --help
--install, -i repo|local
repo: Install MC from repository, future updates will be handled by the system package manager.
local: Build and install MC package locally from official source package.
repo: Install MC from repository, updates are handled by the system package manager.
local: Build and install MC locally from official source package.
--build[=suse|fedora|centos|mandriva]
Build RPM from source DEB but do not install.
Optionally, specify a target distro for cross-building (ex. --build=suse, note the '=').
--compat
Build/install MC without minimum dependency version requirements.
Build/install MC locally without minimum dependency version requirements.
--mcversion VERSION
Build or install a specific MC version, ex. "35.0.51" or "33" (default: latest).
Specify the MC version, ex. "35.0.68" or "35" (default: latest release).
--mcrepo REPO
Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: latest official).
Specify the MC repository, ex. "bullseye", "bookworm", "noble", etc (default: auto).
--arch ARCH
Specify the MC architecture, ex. "amd64", "arm64", etc (default: host architecture).
Specify the target MC architecture, ex. "amd64", "arm64", etc (default: host).
--outputdir PATH
Generate rpmbuild output in this PATH (default: ./output).
--restorefile RESTOREFILE
Generate reusable installJRMC output in this PATH (default: ./output).
--restorefile MJR_FILE
Restore file location for automatic license registration.
--betapass PASSWORD
Enter beta team password for access to beta builds.
--service, -s SERVICE
See SERVICES section below for the list of services to deploy.
See SERVICES below for possible services to install.
--service-type user|system
Starts services at boot (system) or user login (user) (default: per-service, see SERVICES).
--container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of containers to deploy.
--createrepo[=suse|fedora|centos|mandriva]
Build rpm, copy to webroot, and run createrepo.
Optionally, specify a target distro for non-native repo (ex. --createrepo=fedora, note the '=').
--createrepo-webroot PATH
The webroot directory to install the repo (default: /var/www/jriver/).
--createrepo-user USER
The web server user if different from the current user.
Starts services at boot (system) or at user login (user) (default: per service, see SERVICES).
--no-update
Disable the installJRMC update check.
Disable automatic installJRMC self-update.
--uninstall, -u
Uninstall JRiver MC, remove services, containers, and firewall rules (does not remove library files).
--yes, -y, --auto
Always assume yes for questions.
Assume yes response to questions.
--version, -v
Print installJRMC version and exit.
--debug, -d
Print debug output.
--help, -h
Print help dialog and exit.
--uninstall, -u
Uninstall JRiver MC, service files, and firewall rules (does not remove library or media files).
ADVANCED OPTIONS
--container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of possible services to install.
--createrepo[=suse|fedora|centos|mandriva]
Build rpm, copy to webroot, and run createrepo.
Use in conjunction with --build=TARGET for crossbuilding repos.
Optionally, specify a target distro for non-native repo (ex. --createrepo=fedora).
--createrepo-webroot PATH
Specify the webroot directory to install the repo (default: /var/www/jriver).
--webroot-user USER
Owner/user for createrepo output in the webroot (default: current user).
--createrepo-user USER
Backward-compatible alias for --webroot-user.
--sign
Sign the built RPM and repodata/repomd.xml (if --createrepo).
--sign-user USER
User account used to run rpmsign and gpg signing (default: current user).
--sign-key KEYID
GPG key ID, fingerprint, or UID used for --sign.
```
### `--service=`
@@ -130,18 +141,22 @@ Multiple services (but not `--service-types`) can be installed at one time using
Install MC from the repository and start/enable `jriver-mediacenter.service` as a user service.
* `installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 35.0.51`
* `installJRMC --install local --compat --restorefile /path/to/license.mjr --mcversion 35.0.68`
Build and install an MC 35.0.51 compatibility RPM locally and activate it using the `/path/to/license.mjr`.
Build and install an MC 35.0.68 compatibility RPM locally and activate it using the `/path/to/license.mjr`.
* `installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user`
* `installJRMC --createrepo --createrepo-webroot /srv/jriver/repo --webroot-user www-user`
Build an RPM locally for the current distro, move it to the webroot, and run createrepo as `www-user`.
* `installJRMC --service jriver-createrepo --createrepo-webroot /srv/jriver/repo --createrepo-user www-user`
* `installJRMC --service jriver-createrepo --createrepo-webroot /srv/jriver/repo --webroot-user www-user`
Install the jriver-createrepo timer and service to build the RPM, move it to the webroot, and run createrepo as `www-user` hourly.
* `installJRMC --createrepo --webroot-user nginx --sign --sign-user bryan --sign-key 0xDEADBEEF`
Build/update the RPM repo, sign both RPM and repodata as `bryan`, and publish files owned by `nginx`.
* `installJRMC --install repo --service jriver-x11vnc --service jriver-mediacenter --vncpass "letmein"`
Install services to share the existing local desktop via VNC and automatically run MC on startup.

View File

@@ -16,13 +16,14 @@
# NOTES
# * Be careful with tabs in heredocs
# * Avoid execute() for stdout
# * RPM repo creation requires rpmbuild and rpmsign
#
# Allow indirection to match service names to their functions
# shellcheck disable=SC2329
shopt -s extglob
declare -g SCRIPT_VERSION="1.35.13"
declare -g MC_VERSION_HARDCODE="35.0.51" # do find all replace
declare -g SCRIPT_VERSION="1.35.14"
declare -g MC_VERSION_HARDCODE="35.0.68" # do find all replace
declare -g MC_REPO_HARDCODE="bookworm" # should match the MC_VERSION_HARDCODE
declare -g BOARD_ID="92.0" # MC35 board ID for fallback latest version detection
declare -gi SELF_UPDATE_SWITCH=1 # 0 to disable installJRMC self-update
@@ -41,7 +42,7 @@ print_help() {
USAGE:
installJRMC [[OPTION] [VALUE]]...
installJRMC defaults to --install=repo on platforms with a JRiver repository and --install=local on all others.
installJRMC defaults to --install=repo on platforms with a JRiver repository and --install=local on others.
Specifying --build, --createrepo, --service, or --uninstall disables the default install method.
OPTIONS
@@ -66,19 +67,9 @@ print_help() {
--betapass PASSWORD
Enter beta team password for access to beta builds.
--service, -s SERVICE
See SERVICES section below for a list of possible services to install.
See SERVICES below for possible services to install.
--service-type user|system
Starts services at boot (system) or at user login (user) (default: per service, see SERVICES).
--container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of possible services to install.
--createrepo[=suse|fedora|centos|mandriva]
Build rpm, copy to webroot, and run createrepo.
Use in conjunction with --build=TARGET for crossbuilding repos.
Optionally, specify a target distro for non-native repo (ex. --createrepo=fedora, note the '=').
--createrepo-webroot PATH
Specify the webroot directory to install the repo (default: /var/www/jriver).
--createrepo-user USER
Specify the web server user if it differs from \$USER.
--no-update
Disable automatic installJRMC self-update.
--uninstall, -u
@@ -111,6 +102,26 @@ print_help() {
current display incremented by 1 (Xvnc)).
jriver-createrepo (system)
Install hourly service to build latest MC RPM and run createrepo.
ADVANCED OPTIONS
--container, -c CONTAINER (TODO: Under construction)
See CONTAINERS section below for a list of possible services to install.
--createrepo[=suse|fedora|centos|mandriva]
Build rpm, copy to webroot, and run createrepo.
Use in conjunction with --build=TARGET for crossbuilding repos.
Optionally, specify a target distro for non-native repo (ex. --createrepo=fedora).
--createrepo-webroot PATH
Specify the webroot directory to install the repo (default: /var/www/jriver).
--webroot-user USER
Owner/user for createrepo output in the webroot (default: current user).
--createrepo-user USER
Backward-compatible alias for --webroot-user.
--sign
Sign the built RPM and repodata/repomd.xml (if --createrepo).
--sign-user USER
User account used to run rpmsign and gpg signing (default: current user).
--sign-key KEYID
GPG key ID, fingerprint, or UID used for --sign.
EOF
}
@@ -120,15 +131,18 @@ parse_input() {
debug "${FUNCNAME[0]}()" "$@"
declare -gi BUILD_SWITCH REPO_INSTALL_SWITCH LOCAL_INSTALL_SWITCH \
CONTAINER_INSTALL_SWITCH CREATEREPO_SWITCH SNAP_INSTALL_SWITCH \
APPIMAGE_INSTALL_SWITCH COMPAT_SWITCH UNINSTALL_SWITCH YES_SWITCH DEBUG=0
APPIMAGE_INSTALL_SWITCH COMPAT_SWITCH UNINSTALL_SWITCH YES_SWITCH \
SIGN_SWITCH DEBUG=0
declare -g MC_VERSION_USER MC_MVERSION_USER MC_RELEASE_USER MC_REPO_USER USER_ARCH MJR_FILE \
BETAPASS SERVICE_TYPE VNCPASS USER_DISPLAY BUILD_TARGET CREATEREPO_TARGET
BETAPASS SERVICE_TYPE VNCPASS USER_DISPLAY BUILD_TARGET CREATEREPO_TARGET \
WEBROOT_USER SIGN_USER SIGN_KEY
local long_opts short_opts input
long_opts="install:,build::,outputdir:,mcversion:,arch:,mcrepo:,compat,"
long_opts+="restorefile:,betapass:,"
long_opts+="service-type:,service:,services:,"
long_opts+="version,debug,verbose,help,uninstall,yes,auto,no-update,"
long_opts+="createrepo::,createrepo-webroot:,createrepo-user:,"
long_opts+="createrepo::,createrepo-webroot:,webroot-user:,createrepo-user:,"
long_opts+="sign,sign-user:,sign-key:,"
long_opts+="vncpass:,display:,container:"
short_opts="+i:b::s:c:uyvdh"
@@ -196,7 +210,10 @@ parse_input() {
--createrepo) shift; CREATEREPO_TARGET="$1"; BUILD_TARGET="$1"
BUILD_SWITCH=1; CREATEREPO_SWITCH=1 ;;
--createrepo-webroot) shift; CREATEREPO_WEBROOT="$1" ;;
--createrepo-user) shift; CREATEREPO_USER="$1" ;;
--webroot-user|--createrepo-user) shift; WEBROOT_USER="$1" ;;
--sign) SIGN_SWITCH=1 ;;
--sign-user) shift; SIGN_USER="$1" ;;
--sign-key) shift; SIGN_KEY="$1" ;;
--vncpass) shift; VNCPASS="$1" ;;
--display) shift; USER_DISPLAY="$1" ;;
--compat) COMPAT_SWITCH=1; BUILD_SWITCH=1 ;;
@@ -227,6 +244,14 @@ parse_input() {
echo "Warning: not all repositories have beta channels"
echo "If the MC package is unavailable, try using --mcrepo to select another repository"
fi
# If jriver-createrepo is being installed as a service, treat --createrepo
# as service configuration only and defer build/repo execution to the timer.
if [[ " ${SERVICES[*]} " =~ [[:space:]]jriver-createrepo[[:space:]] ]] && ((CREATEREPO_SWITCH)); then
debug "Deferring --createrepo execution while configuring jriver-createrepo service"
BUILD_SWITCH=0
CREATEREPO_SWITCH=0
fi
}
# @description Perform OS detection and generate OS-specific functions
@@ -243,7 +268,8 @@ init() {
declare -g OUTPUT_DIR="$SCRIPT_DIR/output"
declare -g CREATEREPO_WEBROOT="/var/www/jriver"
declare -g CREATEREPO_USER="$USER" # can be root
declare -g WEBROOT_USER # can be root
declare -g SIGN_USER
declare -g ID VERSION_ID UBUNTU_CODENAME VERSION_CODENAME ARCH MC_ARCH NAME
declare -g MC_MVERSION MC_RELEASE MC_PKG MC_RPM MC_ROOT
declare -ga PKG_INSTALL PKG_REMOVE PKG_UPDATE PKG_QUERY
@@ -253,7 +279,7 @@ init() {
# Try to save users from themselves
if [[ $EUID -eq 0 ]]; then
err "Running as root but attempting to continue"
echo "Warning: running as root"
ask_ok "Continue as root user (not recommended)?" || exit 1
elif [[ -n $SUDO_USER ]]; then
err "Sudo detected, installJRMC should not be run with sudo but attempting to continue"
@@ -261,6 +287,10 @@ init() {
USER="${SUDO_USER:-$USER}"
fi
# Default webroot/signing contexts to the account currently running installJRMC.
WEBROOT_USER="${WEBROOT_USER:-$USER}"
SIGN_USER="${SIGN_USER:-$(id -un)}"
# Run the self-updater if enabled
((SELF_UPDATE_SWITCH)) && ((! SCRIPT_IS_PIPED)) && update "$@"
@@ -872,7 +902,8 @@ build_rpm() {
# shellcheck disable=SC2178
declare -n requires_arr="$1" recommends_arr="$2"
local requires_str recommends_str
local i rpmbuild_cmd stub
local i rpmbuild_cmd sign_cmd stub sign_output
local -a build_prefix sign_prefix
local spec_file="$OUTPUT_DIR/SPECS/mediacenter$MC_MVERSION-$MC_VERSION-$MC_RELEASE-$BUILD_TARGET-$ARCH.spec"
# skip rebuilding the rpm if it already exists
@@ -966,8 +997,64 @@ build_rpm() {
"$spec_file"
)
# Build as signing user when running as root with a non-root SIGN_USER.
# This keeps RPM ownership aligned with rpmsign and avoids permission mismatches.
if [[ $(id -un) == "$SIGN_USER" ]]; then
build_prefix=()
else
build_prefix=(sudo -H -u "$SIGN_USER")
execute chown -R "$SIGN_USER:$SIGN_USER" "$OUTPUT_DIR"
fi
# Run rpmbuild and verify output RPM exists
execute "${rpmbuild_cmd[@]}" && [[ -f $MC_RPM ]]
execute "${build_prefix[@]}" "${rpmbuild_cmd[@]}" && [[ -f $MC_RPM ]] || return 1
# Optionally sign the built RPM with the configured key
if ((SIGN_SWITCH)); then
command -v rpmsign &>/dev/null || { err "rpmsign command missing (install rpm-sign/rpm-build)"; return 1; }
command -v gpg &>/dev/null || { err "gpg command missing"; return 1; }
if ! id "$SIGN_USER" &>/dev/null; then
err "Signing user does not exist: $SIGN_USER"
return 1
fi
if [[ $(id -un) == "$SIGN_USER" ]]; then
sign_prefix=()
else
# Use target HOME so rpmsign reads the expected user keyring.
sign_prefix=(sudo -H -u "$SIGN_USER")
fi
if [[ -n $SIGN_KEY ]] && ! "${sign_prefix[@]}" gpg --batch --list-secret-keys --with-colons "$SIGN_KEY" 2>/dev/null | grep -q '^sec'; then
err "Signing key not found in $SIGN_USER keyring: $SIGN_KEY"
err "Import the private key for $SIGN_USER or adjust --sign-user/--sign-key"
return 1
fi
sign_cmd=(rpmsign --addsign)
if [[ -n $SIGN_KEY ]]; then
if rpmsign --help 2>&1 | grep -q -- '--key-id'; then
sign_cmd+=(--key-id "$SIGN_KEY")
else
sign_cmd+=(--define "_gpg_name $SIGN_KEY")
fi
fi
sign_cmd+=("$MC_RPM")
echo "Signing RPM: $MC_RPM"
debug "${sign_prefix[*]} ${sign_cmd[*]}"
if ! sign_output=$("${sign_prefix[@]}" "${sign_cmd[@]}" 2>&1); then
err "RPM signing failed"
[[ -n $sign_output ]] && echo "$sign_output" >&2
err "Hint: for non-interactive service runs, ensure $SIGN_USER can access an unlocked GPG key"
return 1
fi
((DEBUG)) && [[ -n $sign_output ]] && echo "$sign_output"
fi
return 0
}
# @description Creates the Arch PKGBUILD file for Media Center
@@ -1111,20 +1198,36 @@ install_mc_arch() {
popd &>/dev/null || return
}
# @description Copy the RPM to createrepo-webroot and run createrepo as the createrepo-user
# @description Copy the RPM to createrepo-webroot and run createrepo as the webroot-user
run_createrepo() {
debug "${FUNCNAME[0]}()"
local -a cr_opts gpg_cmd sign_prefix
local repomd_xml repomd_asc pubkey_file
install_package createrepo_c
# Ensure WEBROOT_USER exists or offer to create it
if ! id "$WEBROOT_USER" &>/dev/null; then
err "Specified --webroot-user '$WEBROOT_USER' does not exist"
if ask_ok "Create local user '$WEBROOT_USER'?"; then
if ! execute sudo useradd "$WEBROOT_USER"; then
err "Failed to create user '$WEBROOT_USER'"
return 1
fi
else
err "Cannot continue without a valid --webroot-user"
return 1
fi
fi
# Ensure the webroot exists
if [[ ! -d $CREATEREPO_WEBROOT ]]; then
if ! execute sudo -u "$CREATEREPO_USER" mkdir -p "$CREATEREPO_WEBROOT"; then
if ! execute sudo -u "$WEBROOT_USER" mkdir -p "$CREATEREPO_WEBROOT"; then
if ! (execute sudo mkdir -p "$CREATEREPO_WEBROOT" ||
execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"); then
execute sudo chown -R "$WEBROOT_USER:$WEBROOT_USER" "$CREATEREPO_WEBROOT"); then
err "Could not create the createrepo-webroot path!"
err "Make sure that the webroot $CREATEREPO_WEBROOT is writable by user $CREATEREPO_USER"
err "Or change the repo ownership with --createrepo-user"
err "Make sure that the webroot $CREATEREPO_WEBROOT is writable by user $WEBROOT_USER"
err "Or change the repo ownership with --webroot-user"
return 1
fi
fi
@@ -1132,20 +1235,72 @@ run_createrepo() {
# Copy built RPMs to webroot
if ! execute sudo cp -nf "$MC_RPM" "$CREATEREPO_WEBROOT" ||
! execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"; then
! execute sudo chown -R "$WEBROOT_USER:$WEBROOT_USER" "$CREATEREPO_WEBROOT"; then
err "Could not copy $MC_RPM to $CREATEREPO_WEBROOT"
return 1
fi
# Run createrepo
local -a cr_opts=(--update)
cr_opts=(--update)
# [[ -d "$CREATEREPO_WEBROOT/repodata" ]] && cr_opts+=(--update) # TODO temporarily disabled for legacy createrepo
if ! execute sudo -u "$CREATEREPO_USER" createrepo "${cr_opts[@]}" "$CREATEREPO_WEBROOT"; then
if ! (execute sudo createrepo "${cr_opts[@]}" "$CREATEREPO_WEBROOT" && execute sudo chown -R "$CREATEREPO_USER:$CREATEREPO_USER" "$CREATEREPO_WEBROOT"); then
if ! execute sudo -u "$WEBROOT_USER" createrepo "${cr_opts[@]}" "$CREATEREPO_WEBROOT"; then
if ! (execute sudo createrepo "${cr_opts[@]}" "$CREATEREPO_WEBROOT" && execute sudo chown -R "$WEBROOT_USER:$WEBROOT_USER" "$CREATEREPO_WEBROOT"); then
err "createrepo failed"
return 1
fi
fi
# Optionally sign repodata so clients can use repo_gpgcheck=1
if ((SIGN_SWITCH)); then
command -v gpg &>/dev/null || { err "gpg command missing"; return 1; }
repomd_xml="$CREATEREPO_WEBROOT/repodata/repomd.xml"
repomd_asc="$repomd_xml.asc"
[[ -f $repomd_xml ]] || { err "repomd.xml missing after createrepo"; return 1; }
[[ -n $SIGN_KEY ]] || { err "--sign requires --sign-key for repodata signing"; return 1; }
if [[ $(id -un) == "$SIGN_USER" ]]; then
sign_prefix=()
else
sign_prefix=(sudo -H -u "$SIGN_USER")
fi
# Sign repo.md to a temp file first and then move to webroot
local repomd_asc_tmp
if ! repomd_asc_tmp=$("${sign_prefix[@]}" mktemp); then
err "Failed to create temp file for signature"
return 1
fi
gpg_cmd=(gpg --batch --yes --pinentry-mode loopback --default-key "$SIGN_KEY" --armor --detach-sign --output "$repomd_asc_tmp")
((DEBUG)) && gpg_cmd+=(--verbose)
gpg_cmd+=("$repomd_xml")
echo "Signing repodata: $repomd_xml"
if ! execute "${sign_prefix[@]}" "${gpg_cmd[@]}"; then
rm -f "$repomd_asc_tmp"
err "Repodata signing failed"
return 1
fi
execute sudo install -m 0644 "$repomd_asc_tmp" "$repomd_asc"
execute sudo chown "$WEBROOT_USER:$WEBROOT_USER" "$repomd_asc"
rm -f "$repomd_asc_tmp"
# Export public key so clients can import it via repo gpgkey URL
pubkey_file="$CREATEREPO_WEBROOT/RPM-GPG-KEY-jriver.asc"
local pubkey_tmp
if ! pubkey_tmp=$("${sign_prefix[@]}" mktemp); then
err "Failed to create temp file for public key"
return 1
fi
if ! execute "${sign_prefix[@]}" gpg --batch --yes --armor --output "$pubkey_tmp" --export "$SIGN_KEY"; then
rm -f "$pubkey_tmp"
err "Public key export failed for SIGN_KEY=$SIGN_KEY"
return 1
fi
execute sudo install -m 0644 "$pubkey_tmp" "$pubkey_file"
execute sudo chown "$WEBROOT_USER:$WEBROOT_USER" "$pubkey_file"
rm -f "$pubkey_tmp"
fi
}
# @description Symlink certificates if they do not exist in default location
@@ -1522,21 +1677,61 @@ service_jriver-x11vnc() {
# JRiver Media Center RPM from the source DEB and create/update an RPM repository
service_jriver-createrepo() {
debug "${FUNCNAME[0]}()"
local -a sign_args start_cmd
local service_script start_cmd
CREATEREPO_SWITCH=0 # skip running createrepo when generating service
if [[ $CREATEREPO_USER != "$USER" ]]; then
USER="root" set_service_vars "${FUNCNAME[0]##*_}" "system"
else
set_service_vars "${FUNCNAME[0]##*_}" "system"
# jriver-createrepo must run as root, not templated per-user
SERVICE_NAME="jriver-createrepo.service"
TIMER_NAME="jriver-createrepo.timer"
SERVICE_FNAME="/usr/lib/systemd/system/jriver-createrepo.service"
TIMER_FNAME="/usr/lib/systemd/system/jriver-createrepo.timer"
USER_STRING=""
# System services cannot exec files from home directories (SELinux).
# If the script lives under /home/, copy it to a system path first.
if [[ $SCRIPT_PATH == /home/* ]]; then
service_script="/opt/installJRMC/installJRMC"
echo "Script is in a home directory; installing to $service_script for system service"
if ! { execute sudo mkdir -p "/opt/installJRMC" && execute sudo install -m 0755 "$SCRIPT_PATH" "$service_script"; }; then
err "Could not install script to $service_script; the service may fail to start"
service_script="$SCRIPT_PATH"
fi
else
service_script="$SCRIPT_PATH"
fi
sign_args=()
((SIGN_SWITCH)) && sign_args+=(--sign)
[[ -n $SIGN_USER ]] && sign_args+=(--sign-user="$SIGN_USER")
[[ -n $SIGN_KEY ]] && sign_args+=(--sign-key="$SIGN_KEY")
start_cmd=(
"$service_script"
--outputdir="$OUTPUT_DIR"
--createrepo="$CREATEREPO_TARGET"
--createrepo-webroot="$CREATEREPO_WEBROOT"
--webroot-user="$WEBROOT_USER"
--mcrepo="$MC_REPO"
"${sign_args[@]}"
--yes
--no-update
)
# Pass --debug to service file if it was set for the main script
((DEBUG)) && start_cmd+=("--debug")
debug "ExecStart=${start_cmd[*]}"
sudo bash -c "cat <<-EOF > $SERVICE_FNAME
[Unit]
Description=Builds JRiver Media Center RPM, moves it to the repo dir, and runs createrepo
[Service]
$USER_STRING
ExecStart=$SCRIPT_DIR/installJRMC --outputdir=$OUTPUT_DIR --createrepo=$CREATEREPO_TARGET \
--createrepo-webroot=$CREATEREPO_WEBROOT --createrepo-user=$CREATEREPO_USER --mcrepo=$MC_REPO --yes --no-update
ExecStart=${start_cmd[*]}
[Install]
WantedBy=multi-user.target
@@ -1779,21 +1974,26 @@ main() {
exit 0
fi
install_external_repos
if ((REPO_INSTALL_SWITCH)); then
echo "Installing JRiver Media Center from remote repository"
local repo_file
install_external_repos
case $ID in
fedora|centos)
repo_file="/etc/yum.repos.d/jriver.repo"
local keyurl="https://repos.bryanroessler.com/jriver/RPM-GPG-KEY-jriver.asc"
local keyfile="/etc/pki/rpm-gpg/RPM-GPG-KEY-jriver"
echo "Installing repository file: $repo_file"
repo_file="/etc/yum.repos.d/jriver.repo"
sudo tee "$repo_file" &>/dev/null <<-EOF
[jriver]
baseurl = https://repos.bryanroessler.com/jriver
enabled = 1
gpgcheck = 0
gpgcheck = 1
repo_gpgcheck = 1
gpgkey = $keyurl
name = JRiver Media Center hosted by BryanC
EOF
;;
@@ -1844,7 +2044,7 @@ main() {
fi
echo "Installing $MC_PKG package"
if install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_PKG"; then
if install_package --no-install-check --allow-downgrades "$MC_PKG"; then
echo "Successfully installed JRiver Media Center from repository"
else
err "MC failed to install"
@@ -1893,9 +2093,14 @@ main() {
if ((LOCAL_INSTALL_SWITCH)); then
echo "Installing JRiver Media Center from local package"
install_external_repos
# Install MC package
case $ID in
fedora|centos|mandriva|suse) install_package --no-install-check --no-gpg-check --allow-downgrades "$MC_RPM" ;;
fedora|centos|mandriva|suse)
local -a gpg_flag; ((SIGN_SWITCH)) || gpg_flag=(--no-gpg-check)
install_package --no-install-check "${gpg_flag[@]}" --allow-downgrades "$MC_RPM"
;;
debian|ubuntu) install_mc_deb "$@" ;;
arch) install_mc_arch ;;
unknown) install_mc_generic ;;
@@ -1913,14 +2118,6 @@ main() {
open_firewall "jriver-mediacenter" "52100-52200/tcp" "1900/udp"
fi
if ((CREATEREPO_SWITCH)); then
if run_createrepo; then
echo "Successfully updated repo"
else
err "Repo creation failed"
fi
fi
if [[ ${#SERVICES[@]} -gt 0 ]]; then
declare service
for service in "${SERVICES[@]}"; do
@@ -1936,6 +2133,14 @@ main() {
done
unset service
fi
if ((CREATEREPO_SWITCH)); then
if run_createrepo; then
echo "Successfully updated repo"
else
err "Repo creation failed"
fi
fi
}
# @section Helper functions