Luigit
repositories / bugabinga.net

bugabinga.net

personal infrastructure for bugabinga!

owned by admin

scripts/local/klops.sh

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

usage() {
  cat >&2 <<'USAGE'
usage:
  klops.sh run-remote <host> <port> <user> <remote-script> [args...]
  klops.sh wg <host> <port> <wg-conf>
  klops.sh homepage <host> <port> <user> <homepage-dir> <icon-file>
  klops.sh quadlets <host> <port> <user> <quadlets-dir> <luigit-dir> <ddns> <soft-serve-quadlet> <soft-serve-env> <zot-config> <zot-htpasswd> <hallucygenie-env> <hallucygenie-basic-auth> <paperless-env> <quest-log-env> <remote-restart-script>
  klops.sh pkg-site <host> <port> <user> <site-dir>
  klops.sh site <host> <port> <user> <site-dir> <site-name>
  klops.sh site-index <host> <port> <user> <site-dir>
  klops.sh ci <host> <port> <publish-user> <ci-quadlets-dir> [luci-quadlet]
  klops.sh gc <host> <port> <service-user> <ci-user> <toad-user>
  klops.sh caddyfile <host> <port> <user> <caddyfile>
USAGE
  exit 2
}

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
brand_svg="${repo_root}/assets/bugabinga.min.svg"
nugu_css="${repo_root}/assets/nugu.css"
cmd="${1:-}"
[ -n "${cmd}" ] || usage
shift

run_with_ssh_cooldown() {
  local status=0
  "$@" || status=$?
  sleep 2
  return "${status}"
}

ssh_run() { run_with_ssh_cooldown ssh "$@"; }
scp_run() { run_with_ssh_cooldown scp "$@"; }
rsync_run() { run_with_ssh_cooldown rsync "$@"; }

run_remote() {
  [ "$#" -ge 4 ] || usage
  local host="$1" port="$2" user="$3" script="$4"
  shift 4
  ssh_run -p "${port}" "${user}@${host}" 'bash -s' -- "$@" <"${script}"
}

validate_luci_quadlet() (
  local source_dir="$1" luci_quadlet="$2" rendered
  rendered="$(mktemp -d)"
  trap 'rm -rf "${rendered}"' EXIT
  cp -a "${source_dir}/." "${rendered}/"
  cp "${luci_quadlet}" "${rendered}/luci.container"
  QUADLET_UNIT_DIRS="${rendered}" /usr/lib/systemd/system-generators/podman-system-generator --user --dryrun
)

case "${cmd}" in
  run-remote)
    run_remote "$@"
    ;;

  wg)
    [ "$#" -eq 3 ] || usage
    host="$1"
    port="$2"
    wg_conf="$3"
    scp_run -P "${port}" "${wg_conf}" "root@${host}:/root/wg0.conf"
    run_remote "${host}" "${port}" root "${repo_root}/scripts/remote/apply-wg.sh"
    ;;

  homepage)
    [ "$#" -eq 5 ] || usage
    host="$1"
    port="$2"
    user="$3"
    homepage_dir="$4"
    icon_file="$5"
    ssh_user="${user}@${host}"
    ssh_run -p "${port}" "${ssh_user}" 'mkdir -p /data/Databases/homepage/config /data/Databases/homepage/icons'
    rsync_run -az --no-owner --no-group -e "ssh -p ${port}" "${homepage_dir}/" "${ssh_user}:/data/Databases/homepage/config/"
    scp_run -P "${port}" "${nugu_css}" "${ssh_user}:/data/Databases/homepage/config/nugu.css"
    scp_run -P "${port}" "${icon_file}" "${ssh_user}:/data/Databases/homepage/icons/$(basename "${icon_file}")"
    ssh_run -p "${port}" "${ssh_user}" 'chmod 600 /data/Databases/homepage/config/homepage.env && systemctl --user try-restart homepage.service || true'
    ;;

  quadlets)
    [ "$#" -eq 16 ] || usage
    host="$1"
    port="$2"
    user="$3"
    quadlets_dir="$4"
    luigit_dir="$5"
    ddns_quadlet="$6"
    soft_serve_quadlet="$7"
    soft_serve_env="$8"
    zot_config="$9"
    zot_htpasswd="${10}"
    hallucygenie_env="${11}"
    hallucygenie_basic_auth="${12}"
    toad_basic_auth="${13}"
    paperless_env="${14}"
    quest_log_env="${15}"
    remote_restart_script="${16}"
    ssh_user="${user}@${host}"
    ssh_run -p "${port}" "${ssh_user}" 'mkdir -p ~/.config/containers/systemd/ ~/.config/systemd/user/ /data/Databases/soft-serve /data/Databases/zot /data/Databases/zot/storage /data/Databases/hallucygenie/data /data/Databases/quest-log/data /data/Databases/caddy/etc /data/Databases/jellyfin/config/config /data/vcs/public/repos /data/vcs/luigit-source /data/vcs/luigit-manifest /data/vcs/luigit-derived /data/pkg/arch /data/pkg/releases /data/pkg/www /data/sites /data/sites/registry-overrides/assets /data/sites/dawarich-overrides/assets && rm -f /data/Databases/vaultwarden/templates/scss/user.vaultwarden.scss.hbs'
    ssh_run -p "${port}" "root@${host}" 'mkdir -p /data/Databases/paperless/media/logo'
    scp_run -P "${port}" "${repo_root}/assets/jellyfin-branding.xml" "root@${host}:/data/Databases/jellyfin/config/config/branding.xml"
    scp_run -P "${port}" "${brand_svg}" "root@${host}:/data/Databases/paperless/media/logo/bugabinga-logo.svg"
    scp_run -P "${port}" "${repo_root}/assets/registry/index-BAkATJzA.css" "${ssh_user}:/data/sites/registry-overrides/assets/index-BAkATJzA.css"
    scp_run -P "${port}" "${repo_root}/assets/dawarich/application-b5a7662b4bd877f1de1fe5769d2b98adfa15a8095b784d392ae1154df6f3b865.js" "${ssh_user}:/data/sites/dawarich-overrides/assets/application-b5a7662b4bd877f1de1fe5769d2b98adfa15a8095b784d392ae1154df6f3b865.js"
    ssh_run -p "${port}" "root@${host}" "chown ${user}:${user} /data/Databases/jellyfin/config/config/branding.xml && chmod 0644 /data/Databases/jellyfin/config/config/branding.xml && chown --reference=/data/Databases/paperless/media /data/Databases/paperless/media/logo /data/Databases/paperless/media/logo/bugabinga-logo.svg && chmod 0755 /data/Databases/paperless/media/logo && chmod 0644 /data/Databases/paperless/media/logo/bugabinga-logo.svg && rm -f /data/Databases/paperless/media/overrides.css"
    rsync_run -az --delete --no-owner --no-group -e "ssh -p ${port}" "${quadlets_dir}/" "${ssh_user}:~/.config/containers/systemd/"
    ssh_run -p "${port}" "${ssh_user}" 'cp ~/.config/containers/systemd/*.timer ~/.config/systemd/user/ 2>/dev/null || true'
    rsync_run -az --delete --exclude target --no-owner --no-group -e "ssh -p ${port}" "${luigit_dir}/" "${ssh_user}:/data/vcs/luigit-source/"
    scp_run -P "${port}" "${nugu_css}" "${ssh_user}:/data/vcs/luigit-source/src/nugu.css"
    scp_run -P "${port}" "${ddns_quadlet}" "${ssh_user}:~/.config/containers/systemd/ddns.container"
    scp_run -P "${port}" "${soft_serve_quadlet}" "${ssh_user}:~/.config/containers/systemd/soft-serve.container"
    scp_run -P "${port}" "${soft_serve_env}" "${ssh_user}:/data/Databases/soft-serve/soft-serve.env"
    scp_run -P "${port}" "${zot_config}" "${ssh_user}:/data/Databases/zot/config.json"
    scp_run -P "${port}" "${zot_htpasswd}" "${ssh_user}:/data/Databases/zot/htpasswd"
    scp_run -P "${port}" "${hallucygenie_env}" "${ssh_user}:/data/Databases/hallucygenie/hallucygenie.env"
    scp_run -P "${port}" "${hallucygenie_basic_auth}" "${ssh_user}:/data/Databases/caddy/etc/genie-basicauth.caddy"
    scp_run -P "${port}" "${toad_basic_auth}" "${ssh_user}:/data/Databases/caddy/etc/toad-basicauth.caddy"
    scp_run -P "${port}" "${paperless_env}" "${ssh_user}:/data/Databases/paperless/paperless.env"
    scp_run -P "${port}" "${quest_log_env}" "${ssh_user}:/data/Databases/quest-log/quest-log.env"
    ssh_run -p "${port}" "${ssh_user}" 'podman build -t localhost/bugabinga-luigit:1 /data/vcs/luigit-source'
    ssh_run -p "${port}" "${ssh_user}" 'bash -s' <"${remote_restart_script}"
    ;;

  pkg-site)
    [ "$#" -eq 4 ] || usage
    host="$1"
    port="$2"
    user="$3"
    site_dir="$4"
    ssh_user="${user}@${host}"
    ssh_run -p "${port}" "${ssh_user}" 'mkdir -p /data/pkg/www'
    rsync_run -az --delete --no-owner --no-group -e "ssh -p ${port}" "${site_dir}/" "${ssh_user}:/data/pkg/www/"
    scp_run -P "${port}" "${brand_svg}" "${ssh_user}:/data/pkg/www/bugabinga.min.svg"
    scp_run -P "${port}" "${nugu_css}" "${ssh_user}:/data/pkg/www/nugu.css"
    ;;

  site)
    [ "$#" -eq 5 ] || usage
    host="$1"
    port="$2"
    user="$3"
    site_dir="$4"
    site_name="$5"
    ssh_user="${user}@${host}"
    ssh_run -p "${port}" "${ssh_user}" "mkdir -p /data/sites/${site_name}"
    rsync_run -az --delete --no-owner --no-group -e "ssh -p ${port}" "${site_dir}/" "${ssh_user}:/data/sites/${site_name}/"
    scp_run -P "${port}" "${brand_svg}" "${ssh_user}:/data/sites/${site_name}/bugabinga.min.svg"
    scp_run -P "${port}" "${nugu_css}" "${ssh_user}:/data/sites/${site_name}/nugu.css"
    ;;

  site-index)
    [ "$#" -eq 4 ] || usage
    host="$1"
    port="$2"
    user="$3"
    site_dir="$4"
    ssh_user="${user}@${host}"
    ssh_run -p "${port}" "${ssh_user}" 'mkdir -p /data/sites'
    rsync_run -az --no-owner --no-group --no-perms --omit-dir-times -e "ssh -p ${port}" "${site_dir}/" "${ssh_user}:/data/sites/"
    scp_run -P "${port}" "${nugu_css}" "${ssh_user}:/data/sites/nugu.css"
    ;;

  ci)
    [ "$#" -eq 4 ] || [ "$#" -eq 5 ] || usage
    host="$1"
    port="$2"
    publish_user="$3"
    ci_quadlets_dir="$4"
    luci_quadlet="${5:-}"
    if [ -n "${luci_quadlet}" ]; then
      validate_luci_quadlet "${ci_quadlets_dir}" "${luci_quadlet}"
    fi
    run_remote "${host}" "${port}" root "${repo_root}/scripts/remote/setup-ci-user.sh" "${publish_user}"
    scp_run -P "${port}" "${nugu_css}" "root@${host}:/data/ci/nugu.css"
    rsync_run -az --no-owner --no-group -e "ssh -p ${port}" "${ci_quadlets_dir}/" "root@${host}:/home/ci/.config/containers/systemd/"
    if [ -n "${luci_quadlet}" ]; then
      remote_luci=/home/ci/.config/containers/systemd/luci.container
      remote_stage="${remote_luci}.new.$$"
      scp_run -P "${port}" "${luci_quadlet}" "root@${host}:${remote_stage}"
      ssh_run -p "${port}" "root@${host}" "chown ci:ci '${remote_stage}' && chmod 0644 '${remote_stage}' && mv -f '${remote_stage}' '${remote_luci}'"
    fi
    run_remote "${host}" "${port}" root "${repo_root}/scripts/remote/start-luci.sh"
    ;;

  gc)
    [ "$#" -eq 5 ] || usage
    host="$1"
    port="$2"
    service_user="$3"
    ci_user="$4"
    toad_user="$5"
    scp_run -P "${port}" "${repo_root}/scripts/remote/check-maintenance.sh" "root@${host}:/usr/local/sbin/bugabinga-check-maintenance"
    ssh_run -p "${port}" "root@${host}" 'chmod 0755 /usr/local/sbin/bugabinga-check-maintenance'
    run_remote "${host}" "${port}" root "${repo_root}/scripts/remote/setup-garbage-collection.sh" "${service_user}" "${ci_user}" "${toad_user}"
    ;;

  caddyfile)
    [ "$#" -eq 4 ] || usage
    host="$1"
    port="$2"
    user="$3"
    caddyfile="$4"
    ssh_user="${user}@${host}"
    scp_run -P "${port}" "${caddyfile}" "${ssh_user}:/data/Databases/caddy/etc/Caddyfile"
    ssh_run -p "${port}" "${ssh_user}" 'systemctl --user restart caddy.service'
    ;;

  *)
    usage
    ;;
esac