#!/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