continuous-integration/drone/push Build encountered an error
Go: - staticcheck 399 -> 0 with staticcheck.conf (style checks ST1000/1003/ 1005/1016/1020/1021/1022 excluded; error strings are shown in the UI). - io/ioutil and rand.Seed removed; CloseNotifier kept with a lint-ignore until the Phase 2 context rewrite. - Dead code deleted: Auto handler, getStreamByChannelID, updateXEPG, indexOfInt, jsonToMapInt64, removeOldSystemData, randomTime, and the commented-out blocks in struct-buffer.go and internal/authentication. - Duplicates folded: cacheImagesInBackground(), one addErrorToStream(). - Bugs found by SA4006/SA5001: os.Create handle leaked per ffmpeg segment (buffer.go), http.NewRequest error unchecked (buffer.go), xepg.json migration wrote null on read error (migrate.go), WriteUserData errors silently dropped (authentication.go), defer Close before error check (buffer.go, toolchain.go). checkFilePermission results were discarded; an unwritable config or temp dir is now fatal at start-up. - gofmt applied repo-wide; Drone runs gofmt check and staticcheck. Docker: - Entrypoint starts as root, applies PUID/PGID (falls back to XTEVE_UID/ XTEVE_GID, then image defaults), fixes config ownership only when it differs, then drops to xteve via su-exec. --user starts skip all of it. - /xteve removed from LEGACY_CONFIG_DIRS (it is the parent of the default). - mwader/static-ffmpeg pinned to 7.1.1; VOLUME /xteve/config. - Compose files pull registry.coadcorp.com/nathan/xteve:latest, use PUID/PGID/TZ, and explain that SSDP needs host networking. - .dockerignore excludes the npm toolchain (bundle stays in html/js). Docs: README rewritten for the fork (about, registry, compose, env vars, security notes); README-DEV gains a container section.
202 lines
6.3 KiB
Bash
Executable File
202 lines
6.3 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
DEFAULT_CONFIG_DIR="/xteve/config"
|
|
# Older images and other Docker images kept the config in one of these.
|
|
# /xteve itself is not listed because it is the parent of the default dir.
|
|
LEGACY_CONFIG_DIRS="/config /home/xteve/.xteve"
|
|
|
|
RUN_USER="xteve"
|
|
XTEVE_BIN="/usr/local/bin/xteve"
|
|
|
|
log() {
|
|
echo "[entrypoint] $*"
|
|
}
|
|
|
|
resolve_config_dir() {
|
|
if [ -n "${XTEVE_CONFIG:-}" ] && [ "${XTEVE_CONFIG}" != "${DEFAULT_CONFIG_DIR}" ]; then
|
|
printf "%s" "${XTEVE_CONFIG}"
|
|
return
|
|
fi
|
|
|
|
if [ -f "${DEFAULT_CONFIG_DIR}/settings.json" ]; then
|
|
printf "%s" "${DEFAULT_CONFIG_DIR}"
|
|
return
|
|
fi
|
|
|
|
for dir in ${LEGACY_CONFIG_DIRS}; do
|
|
if [ -f "${dir}/settings.json" ]; then
|
|
printf "%s" "${dir}"
|
|
return
|
|
fi
|
|
done
|
|
|
|
printf "%s" "${DEFAULT_CONFIG_DIR}"
|
|
}
|
|
|
|
copy_if_missing() {
|
|
src="$1"
|
|
dst="$2"
|
|
|
|
if [ -e "${src}" ] && [ ! -e "${dst}" ]; then
|
|
cp -R "${src}" "${dst}"
|
|
fi
|
|
}
|
|
|
|
settings_initialized() {
|
|
file="$1"
|
|
|
|
if [ ! -s "${file}" ]; then
|
|
return 1
|
|
fi
|
|
|
|
if grep -q '"uuid"' "${file}" 2>/dev/null; then
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
is_number() {
|
|
case "$1" in
|
|
''|*[!0-9]*) return 1 ;;
|
|
*) return 0 ;;
|
|
esac
|
|
}
|
|
|
|
# Apply PUID/PGID to the xteve user and group. Only called when running as root.
|
|
# Falls back to XTEVE_UID/XTEVE_GID (the old variable names), then to the ids
|
|
# baked into the image at build time.
|
|
apply_ids() {
|
|
current_uid="$(id -u "${RUN_USER}")"
|
|
current_gid="$(id -g "${RUN_USER}")"
|
|
|
|
want_uid="${PUID:-${XTEVE_UID:-${current_uid}}}"
|
|
want_gid="${PGID:-${XTEVE_GID:-${current_gid}}}"
|
|
|
|
if ! is_number "${want_uid}" || ! is_number "${want_gid}"; then
|
|
log "ERROR: PUID/PGID must be numeric (got PUID=${want_uid} PGID=${want_gid})" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${want_gid}" != "${current_gid}" ]; then
|
|
# Edit /etc/group in place. deluser/delgroup on busybox refuse to remove
|
|
# a group that still has members, so sed is the safest option.
|
|
sed -i "s/^${RUN_USER}:\([^:]*\):${current_gid}:/${RUN_USER}:\1:${want_gid}:/" /etc/group
|
|
fi
|
|
|
|
if [ "${want_uid}" != "${current_uid}" ] || [ "${want_gid}" != "${current_gid}" ]; then
|
|
sed -i "s/^${RUN_USER}:\([^:]*\):${current_uid}:${current_gid}:/${RUN_USER}:\1:${want_uid}:${want_gid}:/" /etc/passwd
|
|
fi
|
|
|
|
new_uid="$(id -u "${RUN_USER}")"
|
|
new_gid="$(id -g "${RUN_USER}")"
|
|
if [ "${new_uid}" != "${want_uid}" ] || [ "${new_gid}" != "${want_gid}" ]; then
|
|
log "ERROR: failed to set ${RUN_USER} to UID:GID ${want_uid}:${want_gid} (now ${new_uid}:${new_gid})" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Make sure the config directory belongs to the xteve user. The directory is
|
|
# small (settings, cache, backups), so a recursive chown is acceptable, but it
|
|
# is skipped when the ownership is already right.
|
|
fix_config_owner() {
|
|
dir="$1"
|
|
uid="$2"
|
|
gid="$3"
|
|
|
|
owner="$(stat -c '%u:%g' "${dir}" 2>/dev/null || echo "")"
|
|
if [ "${owner}" != "${uid}:${gid}" ] || [ "${MIGRATED}" = "1" ]; then
|
|
log "Setting ownership of ${dir} to ${uid}:${gid}"
|
|
chown -R "${uid}:${gid}" "${dir}" || log "WARNING: chown of ${dir} failed; continuing"
|
|
fi
|
|
}
|
|
|
|
CONFIG_DIR="$(resolve_config_dir)"
|
|
PORT="${XTEVE_PORT:-34400}"
|
|
|
|
# The binary uses XTEVE_CONFIG to detect that it runs in a container and to
|
|
# default ffmpeg.path to /usr/local/bin/ffmpeg. Keep it in sync with the
|
|
# resolved directory so both agree.
|
|
export XTEVE_CONFIG="${CONFIG_DIR}"
|
|
|
|
mkdir -p "${CONFIG_DIR}"
|
|
|
|
# Set to 1 when files were copied from a legacy directory. When that happens as
|
|
# root the copies are root-owned, so the ownership fix below must not be skipped.
|
|
MIGRATED=0
|
|
|
|
if ! settings_initialized "${CONFIG_DIR}/settings.json"; then
|
|
for legacy_dir in ${LEGACY_CONFIG_DIRS}; do
|
|
if [ "${legacy_dir}" = "${CONFIG_DIR}" ]; then
|
|
continue
|
|
fi
|
|
|
|
if settings_initialized "${legacy_dir}/settings.json"; then
|
|
log "Migrating existing configuration from ${legacy_dir} to ${CONFIG_DIR}"
|
|
|
|
for file in authentication.json pms.json settings.json xepg.json urls.json; do
|
|
if [ "${file}" = "settings.json" ] || [ "${file}" = "xepg.json" ] || [ "${file}" = "urls.json" ]; then
|
|
cp -f "${legacy_dir}/${file}" "${CONFIG_DIR}/${file}" 2>/dev/null || true
|
|
else
|
|
copy_if_missing "${legacy_dir}/${file}" "${CONFIG_DIR}/${file}"
|
|
fi
|
|
done
|
|
|
|
for dir_name in data cache backup tmp; do
|
|
copy_if_missing "${legacy_dir}/${dir_name}" "${CONFIG_DIR}/${dir_name}"
|
|
done
|
|
|
|
MIGRATED=1
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ "$(id -u)" = "0" ]; then
|
|
# Started as root (the default): apply PUID/PGID, fix ownership, drop privileges.
|
|
apply_ids
|
|
RUN_UID="$(id -u "${RUN_USER}")"
|
|
RUN_GID="$(id -g "${RUN_USER}")"
|
|
fix_config_owner "${CONFIG_DIR}" "${RUN_UID}" "${RUN_GID}"
|
|
|
|
if ! su-exec "${RUN_USER}:${RUN_USER}" touch "${CONFIG_DIR}/.xteve-write-test" 2>/dev/null; then
|
|
log "ERROR: Config directory is not writable: ${CONFIG_DIR}" >&2
|
|
log "xteve would run as UID:GID ${RUN_UID}:${RUN_GID}" >&2
|
|
ls -ld "${CONFIG_DIR}" >&2 || true
|
|
log "Hint: set PUID/PGID to the owner of the host directory, or fix its ownership/permissions on the host." >&2
|
|
exit 1
|
|
fi
|
|
rm -f "${CONFIG_DIR}/.xteve-write-test"
|
|
|
|
log "Using config directory: ${CONFIG_DIR}"
|
|
log "Running as UID:GID ${RUN_UID}:${RUN_GID} (PUID/PGID)"
|
|
if [ -f "${CONFIG_DIR}/settings.json" ]; then
|
|
log "settings.json details: $(ls -l "${CONFIG_DIR}/settings.json" | awk '{print $1, $3, $4, $5, $9}')"
|
|
fi
|
|
|
|
exec su-exec "${RUN_USER}:${RUN_USER}" "${XTEVE_BIN}" -config "${CONFIG_DIR}" -port "${PORT}" "$@"
|
|
fi
|
|
|
|
# Started with --user: keep the given identity, no id or ownership changes.
|
|
if [ -n "${PUID:-}${PGID:-}${XTEVE_UID:-}${XTEVE_GID:-}" ]; then
|
|
log "Container started as non-root; PUID/PGID are ignored"
|
|
fi
|
|
|
|
if ! touch "${CONFIG_DIR}/.xteve-write-test" 2>/dev/null; then
|
|
log "ERROR: Config directory is not writable: ${CONFIG_DIR}" >&2
|
|
log "Running as UID:GID $(id -u):$(id -g)" >&2
|
|
ls -ld "${CONFIG_DIR}" >&2 || true
|
|
log "Hint: ensure the host path ownership/permissions allow this UID:GID to write, or drop --user and set PUID/PGID instead." >&2
|
|
exit 1
|
|
fi
|
|
rm -f "${CONFIG_DIR}/.xteve-write-test"
|
|
|
|
log "Using config directory: ${CONFIG_DIR}"
|
|
log "Running as UID:GID $(id -u):$(id -g)"
|
|
if [ -f "${CONFIG_DIR}/settings.json" ]; then
|
|
log "settings.json details: $(ls -l "${CONFIG_DIR}/settings.json" | awk '{print $1, $3, $4, $5, $9}')"
|
|
fi
|
|
|
|
exec "${XTEVE_BIN}" -config "${CONFIG_DIR}" -port "${PORT}" "$@"
|