Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

services/toad/deploy/setup-user.sh

Raw
#!/usr/bin/env bash
set -euo pipefail

[[ "$#" -eq 1 && "$1" =~ ^[a-z_][a-z0-9_-]*$ ]] || {
  echo "usage: setup-user.sh PUBLIC_PROXY_USER" >&2
  exit 2
}

user=toad
public_proxy_user="$1"
home_dir=/home/toad

id -u "${public_proxy_user}" >/dev/null
version="$(podman version --format '{{.Client.Version}}')"
major="${version%%.*}"
[[ "${major}" =~ ^[0-9]+$ && "${major}" -ge 5 ]] || {
  echo "toad requires Podman 5 or newer, found ${version}" >&2
  exit 1
}

id -u "${user}" >/dev/null 2>&1 || useradd --create-home --shell /usr/sbin/nologin "${user}"
install -d -o "${user}" -g "${user}" -m 0750 \
  "${home_dir}" \
  "${home_dir}/.config" \
  "${home_dir}/.config/containers/systemd" \
  "${home_dir}/.config/systemd/user/sockets.target.wants" \
  "${home_dir}/.local/share/containers" \
  /data/toad
install -d -o "${user}" -g "${user}" -m 0770 /data/toad-ingress
setfacl -m "u:${public_proxy_user}:rwx,d:u:${public_proxy_user}:rwx" /data/toad-ingress

semanage fcontext -a -t container_file_t '/data/toad-ingress(/.*)?' 2>/dev/null ||
  semanage fcontext -m -t container_file_t '/data/toad-ingress(/.*)?'
for shared_file in /data/toad/gateway.Caddyfile /data/toad/ingress.env; do
  semanage fcontext -a -t container_file_t "${shared_file}" 2>/dev/null ||
    semanage fcontext -m -t container_file_t "${shared_file}"
done
restorecon -RF /data/toad-ingress

loginctl enable-linger "${user}"
uid="$(id -u "${user}")"
runtime="/run/user/${uid}"
install -d -o "${user}" -g "${user}" -m 0700 "${runtime}"
systemctl start "user@${uid}.service"

for _ in $(seq 1 25); do
  [[ -S "${runtime}/bus" ]] && break
  sleep 0.2
done
[[ -S "${runtime}/bus" ]] || {
  echo "toad user bus did not start" >&2
  exit 1
}

socket_unit=/usr/lib/systemd/user/podman.socket
[[ -f "${socket_unit}" ]] || socket_unit=/lib/systemd/user/podman.socket
[[ -f "${socket_unit}" ]] || {
  echo "missing podman.socket user unit" >&2
  exit 1
}
ln -sf "${socket_unit}" "${home_dir}/.config/systemd/user/sockets.target.wants/podman.socket"
chown -h "${user}:${user}" "${home_dir}/.config/systemd/user/sockets.target.wants/podman.socket"

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 daemon-reload
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 start podman.socket

cat >/usr/local/bin/toad <<'WRAPPER'
#!/usr/bin/env bash
set -euo pipefail

[[ "${EUID}" -eq 0 ]] || {
  echo "toad host wrapper must run as root" >&2
  exit 1
}
uid="$(id -u toad)"
cd /home/toad
exec runuser -u toad -- env \
  HOME=/home/toad \
  USER=toad \
  LOGNAME=toad \
  XDG_RUNTIME_DIR="/run/user/${uid}" \
  DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus" \
  podman exec toad /toad "$@"
WRAPPER
chmod 0755 /usr/local/bin/toad