repositories / bugabinga.net
bugabinga.net
personal infrastructure for bugabinga!
owned by admin
services/pufferpanel/deploy/setup-user.sh
Raw#!/usr/bin/env bash
set -euo pipefail
[[ "${EUID}" -eq 0 && "$#" -eq 1 && "$1" =~ ^[a-z_][a-z0-9_-]*$ ]] || {
echo "usage: setup-user.sh PUBLIC_PROXY_USER (as root)" >&2
exit 2
}
user=pufferpanel
public_proxy_user="$1"
home_dir=/home/pufferpanel
command -v semanage >/dev/null
command -v restorecon >/dev/null
command -v podman >/dev/null
if ! id -u "${user}" >/dev/null 2>&1; then
useradd --create-home --user-group --home-dir "${home_dir}" --shell /usr/sbin/nologin "${user}"
fi
uid="$(id -u "${user}")"
[[ "${uid}" -ge 1000 && "$(getent passwd "${user}" | cut -d: -f6)" == "${home_dir}" && "$(id -gn "${user}")" == "${user}" ]] || {
echo "refusing incompatible existing pufferpanel account" >&2
exit 1
}
for ranges in /etc/subuid /etc/subgid; do
awk -F: -v user="${user}" '$1 == user && $3 >= 65536 { found = 1 } END { exit !found }' "${ranges}" || {
echo "missing subordinate ID range in ${ranges}; configure before deployment" >&2
exit 1
}
done
directories=(
"${home_dir}" "${home_dir}/.config" "${home_dir}/.config/containers"
"${home_dir}/.config/containers/systemd" "${home_dir}/.local" "${home_dir}/.local/share"
"${home_dir}/.local/share/containers"
/data/pufferpanel /data/pufferpanel/config /data/pufferpanel/data /data/pufferpanel/logs /data/pufferpanel/theme
/data/pufferpanel-ingress
)
for directory in "${directories[@]}"; do
[[ ! -L "${directory}" ]] || {
echo "refusing symlinked deployment directory: ${directory}" >&2
exit 1
}
install -d -o "${user}" -g "${user}" -m 0750 "${directory}"
done
id -u "${public_proxy_user}" >/dev/null
install -d -o "${user}" -g "${user}" -m 0770 /data/pufferpanel-ingress
setfacl -m "u:${public_proxy_user}:rx,d:u:${public_proxy_user}:rw" /data/pufferpanel-ingress
# Game containers share server data, so use shared SELinux labels, not a private MCS category.
semanage fcontext -a -t container_file_t '/data/pufferpanel(/.*)?' 2>/dev/null ||
semanage fcontext -m -t container_file_t '/data/pufferpanel(/.*)?'
semanage fcontext -a -t container_file_t '/data/pufferpanel-ingress(/.*)?' 2>/dev/null ||
semanage fcontext -m -t container_file_t '/data/pufferpanel-ingress(/.*)?'
restorecon -RF /data/pufferpanel /data/pufferpanel-ingress
loginctl enable-linger "${user}"
systemctl start "user@${uid}.service"
runtime="/run/user/${uid}"
for _ in $(seq 1 25); do
[[ -S "${runtime}/bus" ]] && break
sleep 0.2
done
[[ -S "${runtime}/bus" ]] || {
echo "pufferpanel user bus did not start" >&2
exit 1
}
runuser -u "${user}" -- env \
HOME="${home_dir}" USER="${user}" LOGNAME="${user}" \
XDG_RUNTIME_DIR="${runtime}" DBUS_SESSION_BUS_ADDRESS="unix:path=${runtime}/bus" \
systemctl --user enable --now podman.socket podman-auto-update.timer