Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

scripts/remote/setup-ci-user.sh

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

user="${CI_USER:-ci}"
publish_user="${PUBLISH_USER:-${1:-}}"
home_dir="/home/${user}"

[[ "$#" -le 1 && -n "${publish_user}" ]] || {
  echo "usage: setup-ci-user.sh PUBLISH_USER" >&2
  exit 2
}
id -u "${publish_user}" >/dev/null
id -u "${user}" >/dev/null 2>&1 || useradd --create-home --shell /usr/bin/bash "${user}"

install -d -o "${user}" -g "${user}" -m 0755 "${home_dir}"
install -d -o "${user}" -g "${user}" -m 0755 \
  "${home_dir}/.config" \
  "${home_dir}/.config/containers/systemd" \
  "${home_dir}/.config/systemd/user/sockets.target.wants" \
  "${home_dir}/.local/share/containers" \
  /data/ci \
  /data/ci/inbox \
  /data/ci/events \
  /data/ci/live \
  /data/ci/logs \
  /data/ci/artifacts \
  /data/ci/cache \
  /data/ci/workspaces \
  /data/ci/secrets
install -d -m 0755 /data/pkg /data/sites
chown -R "${user}:${user}" "${home_dir}/.config" "${home_dir}/.local"
# Live runs mutate workspaces concurrently; recurse everywhere else only.
for entry in /data/ci/*; do
  [ -e "${entry}" ] || continue
  if [ "$(basename "${entry}")" = "workspaces" ]; then
    chown "${user}:${user}" "${entry}"
  else
    chown -R "${user}:${user}" "${entry}"
  fi
done
setfacl -R -m "u:${user}:rwX,u:${publish_user}:rwX" /data/pkg /data/sites
find /data/pkg /data/sites -type d -exec setfacl -m "d:u:${user}:rwx,d:u:${publish_user}:rwx" {} +

keys_tmp="$(mktemp)"
keys_lock=/data/ci/authorized_keys.lock
touch "${keys_lock}"
chown "${user}:${user}" "${keys_lock}"
awk '
  /^[[:space:]]*($|#)/ { next }
  {
    for (i = 1; i <= NF; i++) {
      if ($i ~ /^(ssh-|ecdsa-|sk-)/) {
        print
        next
      }
    }
  }
' /root/.ssh/authorized_keys | sort -u >"${keys_tmp}"
if [ ! -s "${keys_tmp}" ]; then
  echo "no root SSH public keys available for Luci" >&2
  rm -f "${keys_tmp}"
  exit 1
fi
(
  flock -x 9
  install -o "${user}" -g "${user}" -m 0644 "${keys_tmp}" /data/ci/authorized_keys
) 9>>"${keys_lock}"
rm -f "${keys_tmp}"
rm -rf /data/ci-auth

loginctl enable-linger "${user}" || true

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

for _ in $(seq 1 25); do
  [ -S "${runtime}/bus" ] && break
  sleep 0.2
done

socket_unit=/usr/lib/systemd/user/podman.socket
if [ ! -f "${socket_unit}" ]; then socket_unit=/lib/systemd/user/podman.socket; fi
if [ ! -f "${socket_unit}" ]; then
  echo "missing podman.socket user unit; install podman" >&2
  exit 1
fi
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" \
  bash -s <<'USER_SETUP'
set -euo pipefail
cd "${HOME}"
systemctl --user daemon-reload
systemctl --user disable --now laminar.service 2>/dev/null || true
rm -f "${HOME}/.config/containers/systemd/laminar.container"
systemctl --user daemon-reload
podman rm -f laminar 2>/dev/null || true
podman image rm -f localhost/bugabinga-laminar:latest 2>/dev/null || true
podman container prune -f
podman image prune -f
systemctl --user start podman.socket
USER_SETUP

rm -rf /data/Databases/laminar