From b236b684863e5b284988aa507a000a8bcab05442 Mon Sep 17 00:00:00 2001 From: ray Date: Tue, 27 Oct 2026 12:49:13 +0000 Subject: [PATCH] update --- MOUNTS.md | 62 +++++++++++++++++++ user/backup-pass.service | 11 ++-- user/backup-pass.sh | 34 ++++++++++ user/backup-pass.timer | 1 + user/dunst.service | 1 - .../mango-tag-osd.service | 1 + .../swayidle.service | 1 + user/mango-tag-osd.service | 16 +++++ user/package-status-refresh.service | 12 ++++ user/package-status-refresh.sh | 59 ++++++++++++++++++ user/package-status-refresh.timer | 10 +++ user/swayidle.service | 14 +++++ user/ultracc-mount.service | 11 ++++ user/update-notifier.service | 9 --- user/update-notifier.timer | 8 --- user/wait-for-mount.sh | 15 +++++ user/wasabi-data-crypt.service | 12 ++++ user/wasabi-data-crypt.target | 4 ++ user/wasabi-data-mount.service | 10 +++ user/wasabi-media-mount.service | 10 +++ user/wasabi-peertube-mount.service | 10 +++ user/ydotoold.service | 13 ---- 22 files changed, 288 insertions(+), 36 deletions(-) create mode 100644 MOUNTS.md create mode 100644 user/backup-pass.sh delete mode 120000 user/dunst.service create mode 120000 user/mango-session.target.wants/mango-tag-osd.service create mode 120000 user/mango-session.target.wants/swayidle.service create mode 100644 user/mango-tag-osd.service create mode 100644 user/package-status-refresh.service create mode 100755 user/package-status-refresh.sh create mode 100644 user/package-status-refresh.timer create mode 100644 user/swayidle.service create mode 100644 user/ultracc-mount.service delete mode 100644 user/update-notifier.service delete mode 100644 user/update-notifier.timer create mode 100644 user/wait-for-mount.sh create mode 100644 user/wasabi-data-crypt.service create mode 100644 user/wasabi-data-crypt.target create mode 100644 user/wasabi-data-mount.service create mode 100644 user/wasabi-media-mount.service create mode 100644 user/wasabi-peertube-mount.service delete mode 100644 user/ydotoold.service diff --git a/MOUNTS.md b/MOUNTS.md new file mode 100644 index 0000000..7989c59 --- /dev/null +++ b/MOUNTS.md @@ -0,0 +1,62 @@ +# Remote mounts + +Remote storage under `/mnt` is managed with user-level systemd services. None +of these mounts starts automatically at login. + +Do not run the legacy `mount-*.sh` scripts while the corresponding systemd +service is active. Check current mounts with: + +```sh +findmnt | grep /mnt +``` + +## Encrypted Wasabi data + +The password-backup timer mounts encrypted Wasabi data automatically, performs +the backup, and unmounts it afterward. + +For interactive access, keep it mounted with the target: + +```sh +systemctl --user start wasabi-data-crypt.target +systemctl --user stop wasabi-data-crypt.target +``` + +Run or inspect the password backup with: + +```sh +systemctl --user start backup-pass.service +systemctl --user status backup-pass.service +journalctl --user -u backup-pass.service +``` + +## Other remote mounts + +Start and stop these only when needed: + +| Location | Start command | Stop command | +| --- | --- | --- | +| `/mnt/ultracc` | `systemctl --user start ultracc-mount.service` | `systemctl --user stop ultracc-mount.service` | +| `/mnt/wasabi-data` | `systemctl --user start wasabi-data-mount.service` | `systemctl --user stop wasabi-data-mount.service` | +| `/mnt/wasabi-media` | `systemctl --user start wasabi-media-mount.service` | `systemctl --user stop wasabi-media-mount.service` | +| `/mnt/wasabi-peertube.isnet` | `systemctl --user start wasabi-peertube-mount.service` | `systemctl --user stop wasabi-peertube-mount.service` | + +Inspect a service with: + +```sh +systemctl --user status SERVICE_NAME +journalctl --user -u SERVICE_NAME +``` + +## Borgmatic + +The Borgmatic repository mount remains a manual maintenance operation: + +```sh +cd /mnt +./mount-borgmatic.sh +fusermount3 -u /mnt/borgmatic +``` + +The maintained unit files and this document live in +`/home/ray/.config/systemd`. diff --git a/user/backup-pass.service b/user/backup-pass.service index e26e634..029c725 100644 --- a/user/backup-pass.service +++ b/user/backup-pass.service @@ -1,10 +1,11 @@ [Unit] Description=Backup kdbx password files +Requires=wasabi-data-crypt.service +After=wasabi-data-crypt.service [Service] -WorkingDirectory=/home/ray/.Sync/Pass/ -ExecStart=/home/ray/.Sync/Pass/backup.sh - -[Install] -WantedBy=default.target +Type=oneshot +WorkingDirectory=/home/ray/.Syncthing/Pass/ +ExecCondition=/usr/bin/mountpoint -q /mnt/wasabi-data-crypt +ExecStart=/bin/sh /home/ray/.config/systemd/user/backup-pass.sh diff --git a/user/backup-pass.sh b/user/backup-pass.sh new file mode 100644 index 0000000..c7be69c --- /dev/null +++ b/user/backup-pass.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +set -eu +umask 077 + +mountpoint_dir='/mnt/wasabi-data-crypt' +destination_dir="$mountpoint_dir/pass" +timestamp=$(date +%s) +copied=0 + +if ! mountpoint -q "$mountpoint_dir"; then + echo "Password backup aborted: $mountpoint_dir is not mounted" >&2 + exit 1 +fi + +if ! [ -d "$destination_dir" ]; then + echo "Password backup aborted: $destination_dir does not exist" >&2 + exit 1 +fi + +for source_file in ./*.kdbx; do + [ -e "$source_file" ] || continue + filename=${source_file#./} + cp -- "$source_file" "$destination_dir/$timestamp-$filename" + printf 'Backed up %s\n' "$filename" + copied=$((copied + 1)) +done + +if [ "$copied" -eq 0 ]; then + echo 'Password backup aborted: no .kdbx files found' >&2 + exit 1 +fi + +printf 'Password backup complete: %s file(s) copied to %s\n' "$copied" "$destination_dir" diff --git a/user/backup-pass.timer b/user/backup-pass.timer index a532888..72dcb00 100644 --- a/user/backup-pass.timer +++ b/user/backup-pass.timer @@ -4,6 +4,7 @@ Description=Periodically run backup-pass [Timer] OnCalendar=*-*-* 22:00:00 OnCalendar=*-*-* 10:00:00 +Persistent=true [Install] WantedBy=timers.target diff --git a/user/dunst.service b/user/dunst.service deleted file mode 120000 index dc1dc0c..0000000 --- a/user/dunst.service +++ /dev/null @@ -1 +0,0 @@ -/dev/null \ No newline at end of file diff --git a/user/mango-session.target.wants/mango-tag-osd.service b/user/mango-session.target.wants/mango-tag-osd.service new file mode 120000 index 0000000..b1507f5 --- /dev/null +++ b/user/mango-session.target.wants/mango-tag-osd.service @@ -0,0 +1 @@ +../mango-tag-osd.service \ No newline at end of file diff --git a/user/mango-session.target.wants/swayidle.service b/user/mango-session.target.wants/swayidle.service new file mode 120000 index 0000000..2eb3dea --- /dev/null +++ b/user/mango-session.target.wants/swayidle.service @@ -0,0 +1 @@ +/home/ray/.config/systemd/user/swayidle.service \ No newline at end of file diff --git a/user/mango-tag-osd.service b/user/mango-tag-osd.service new file mode 100644 index 0000000..6e3a27b --- /dev/null +++ b/user/mango-tag-osd.service @@ -0,0 +1,16 @@ +[Unit] +Description=Mango tag and monitor focus indicator +PartOf=mango-session.target +After=mango-session.target + +[Service] +Type=simple +Environment=LD_PRELOAD=/usr/lib/libgtk4-layer-shell.so +Environment=GSK_RENDERER=gl +ExecStartPre=/usr/bin/sh -c 'until [ -n "$WAYLAND_DISPLAY" ] && [ -S "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" ]; do sleep 0.2; done' +ExecStart=/home/ray/.config/mango/tag-osd.py +Restart=on-failure +RestartSec=1 + +[Install] +WantedBy=mango-session.target diff --git a/user/package-status-refresh.service b/user/package-status-refresh.service new file mode 100644 index 0000000..f1d8275 --- /dev/null +++ b/user/package-status-refresh.service @@ -0,0 +1,12 @@ +[Unit] +Description=Refresh cached package update and orphan counts +After=network-online.target + +[Service] +Type=oneshot +ExecStart=/home/ray/.config/systemd/user/package-status-refresh.sh +SuccessExitStatus=75 +Nice=10 +IOSchedulingClass=idle +TimeoutStartSec=2min + diff --git a/user/package-status-refresh.sh b/user/package-status-refresh.sh new file mode 100755 index 0000000..c59f146 --- /dev/null +++ b/user/package-status-refresh.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +set -uo pipefail + +readonly cache_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/package-status" +readonly cache_file="${cache_dir}/status" +readonly attempt_file="${cache_dir}/last-attempt" +readonly pacman_log="/var/log/pacman.log" +readonly pacman_lock="/var/lib/pacman/db.lck" + +mkdir -p "${cache_dir}" +chmod 700 "${cache_dir}" +touch "${attempt_file}" || exit 1 + +# Never inspect the package database while pacman is changing it. A later +# timer run or terminal startup will request another refresh. +if [[ -e "${pacman_lock}" ]]; then + exit 75 +fi + +pacman_log_signature_before=$(stat -c '%Y:%s:%i' "${pacman_log}" 2>/dev/null || printf '0:0:0') + +updates_output='' +updates_output=$(CHECKUPDATES_DB="${cache_dir}/checkupdates-db" checkupdates --nocolor 2>/dev/null) +checkupdates_status=$? + +case "${checkupdates_status}" in + 0) + updates_count=$(printf '%s\n' "${updates_output}" | awk 'NF { count++ } END { print count + 0 }') + ;; + 2) + updates_count=0 + ;; + *) + # A network or mirror failure must not replace a known-good cache. + exit "${checkupdates_status}" + ;; +esac + +orphans_count=$(pacman -Qdtq 2>/dev/null | awk 'NF { count++ } END { print count + 0 }') +pacman_log_signature_after=$(stat -c '%Y:%s:%i' "${pacman_log}" 2>/dev/null || printf '0:0:0') + +# Discard the result if a package operation overlapped this refresh. +if [[ -e "${pacman_lock}" || "${pacman_log_signature_before}" != "${pacman_log_signature_after}" ]]; then + exit 75 +fi + +umask 077 +temporary_file=$(mktemp "${cache_dir}/status.XXXXXX") +trap 'rm -f "${temporary_file}"' EXIT + +printf 'version=1\nupdates=%d\norphans=%d\nchecked_at=%d\npacman_log_signature=%s\n' \ + "${updates_count}" \ + "${orphans_count}" \ + "$(date +%s)" \ + "${pacman_log_signature_after}" > "${temporary_file}" + +mv -f "${temporary_file}" "${cache_file}" +trap - EXIT diff --git a/user/package-status-refresh.timer b/user/package-status-refresh.timer new file mode 100644 index 0000000..fa602a3 --- /dev/null +++ b/user/package-status-refresh.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Periodically refresh cached package status + +[Timer] +OnBootSec=2min +OnUnitActiveSec=30min +AccuracySec=1min + +[Install] +WantedBy=timers.target diff --git a/user/swayidle.service b/user/swayidle.service new file mode 100644 index 0000000..81aafe7 --- /dev/null +++ b/user/swayidle.service @@ -0,0 +1,14 @@ +[Unit] +Description=Wayland idle and sleep lock manager +Documentation=man:swayidle(1) +PartOf=mango-session.target +After=mango-session.target + +[Service] +Type=simple +ExecStart=/usr/bin/swayidle -w +Restart=on-failure +RestartSec=2 + +[Install] +WantedBy=mango-session.target diff --git a/user/ultracc-mount.service b/user/ultracc-mount.service new file mode 100644 index 0000000..337ed67 --- /dev/null +++ b/user/ultracc-mount.service @@ -0,0 +1,11 @@ +[Unit] +Description=Ultra.cc remote mount + +[Service] +Type=notify +ExecStart=/usr/bin/rclone mount ultra:/home/gabbaell /mnt/ultracc --config=/home/ray/.config/rclone/rclone.conf +ExecStop=/usr/bin/fusermount3 -u /mnt/ultracc +SuccessExitStatus=143 +Restart=on-failure +RestartSec=10 +TimeoutStopSec=30 diff --git a/user/update-notifier.service b/user/update-notifier.service deleted file mode 100644 index bc4445f..0000000 --- a/user/update-notifier.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Notify when updates are available - -[Service] -ExecStart=/usr/local/bin/notify-updates -n - -[Install] -WantedBy=default.target - diff --git a/user/update-notifier.timer b/user/update-notifier.timer deleted file mode 100644 index eac775a..0000000 --- a/user/update-notifier.timer +++ /dev/null @@ -1,8 +0,0 @@ -[Unit] -Description=Periodically run update-notifier - -[Timer] -OnCalendar=*-*-* 14:00:00 - -[Install] -WantedBy=timers.target diff --git a/user/wait-for-mount.sh b/user/wait-for-mount.sh new file mode 100644 index 0000000..4a3dc57 --- /dev/null +++ b/user/wait-for-mount.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -eu + +mountpoint_dir=$1 +attempt=0 + +while ! mountpoint -q "$mountpoint_dir"; do + attempt=$((attempt + 1)) + if [ "$attempt" -ge 100 ]; then + echo "Timed out waiting for mount: $mountpoint_dir" >&2 + exit 1 + fi + sleep 0.1 +done diff --git a/user/wasabi-data-crypt.service b/user/wasabi-data-crypt.service new file mode 100644 index 0000000..2854d19 --- /dev/null +++ b/user/wasabi-data-crypt.service @@ -0,0 +1,12 @@ +[Unit] +Description=Encrypted Wasabi data mount +StopWhenUnneeded=yes + +[Service] +Type=notify +ExecStart=/usr/bin/rclone mount crypt-data:/ /mnt/wasabi-data-crypt --config=/home/ray/.config/rclone/rclone.conf +ExecStop=/usr/bin/fusermount3 -u /mnt/wasabi-data-crypt +SuccessExitStatus=143 +Restart=on-failure +RestartSec=10 +TimeoutStopSec=30 diff --git a/user/wasabi-data-crypt.target b/user/wasabi-data-crypt.target new file mode 100644 index 0000000..a3004db --- /dev/null +++ b/user/wasabi-data-crypt.target @@ -0,0 +1,4 @@ +[Unit] +Description=Keep the encrypted Wasabi data mount available for interactive use +Requires=wasabi-data-crypt.service +After=wasabi-data-crypt.service diff --git a/user/wasabi-data-mount.service b/user/wasabi-data-mount.service new file mode 100644 index 0000000..3cefb5a --- /dev/null +++ b/user/wasabi-data-mount.service @@ -0,0 +1,10 @@ +[Unit] +Description=Wasabi data bucket mount + +[Service] +Type=simple +ExecStart=/usr/bin/s3fs data.isnet /mnt/wasabi-data -f -o passwd_file=/home/ray/.config/.s3fs-wasabi -o url=https://s3.eu-west-1.wasabisys.com -o use_path_request_style +ExecStartPost=/bin/sh /home/ray/.config/systemd/user/wait-for-mount.sh /mnt/wasabi-data +Restart=on-failure +RestartSec=10 +TimeoutStopSec=30 diff --git a/user/wasabi-media-mount.service b/user/wasabi-media-mount.service new file mode 100644 index 0000000..5ca813f --- /dev/null +++ b/user/wasabi-media-mount.service @@ -0,0 +1,10 @@ +[Unit] +Description=Wasabi media bucket mount + +[Service] +Type=simple +ExecStart=/usr/bin/s3fs media.isnet /mnt/wasabi-media -f -o passwd_file=/home/ray/.config/.s3fs-wasabi -o url=https://s3.eu-west-1.wasabisys.com -o use_path_request_style +ExecStartPost=/bin/sh /home/ray/.config/systemd/user/wait-for-mount.sh /mnt/wasabi-media +Restart=on-failure +RestartSec=10 +TimeoutStopSec=30 diff --git a/user/wasabi-peertube-mount.service b/user/wasabi-peertube-mount.service new file mode 100644 index 0000000..4e841d8 --- /dev/null +++ b/user/wasabi-peertube-mount.service @@ -0,0 +1,10 @@ +[Unit] +Description=Wasabi PeerTube bucket mount + +[Service] +Type=simple +ExecStart=/usr/bin/s3fs peertube.isnet /mnt/wasabi-peertube.isnet -f -o passwd_file=/home/ray/.config/.s3fs-wasabi -o url=https://s3.eu-west-1.wasabisys.com -o use_path_request_style +ExecStartPost=/bin/sh /home/ray/.config/systemd/user/wait-for-mount.sh /mnt/wasabi-peertube.isnet +Restart=on-failure +RestartSec=10 +TimeoutStopSec=30 diff --git a/user/ydotoold.service b/user/ydotoold.service deleted file mode 100644 index 60a5d14..0000000 --- a/user/ydotoold.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=ydotool daemon -After=default.target -PartOf=default.target - -[Service] -Type=simple -ExecStart=/usr/bin/ydotoold -Restart=on-failure -RestartSec=1 - -[Install] -WantedBy=default.target