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