Skip to content

Instantly share code, notes, and snippets.

@andre-st
Last active January 13, 2024 16:44
Show Gist options
  • Save andre-st/6c935abcd5e5cdf0158de4c1c712295d to your computer and use it in GitHub Desktop.
Save andre-st/6c935abcd5e5cdf0158de4c1c712295d to your computer and use it in GitHub Desktop.
Script creates udev and systemd configuration files for my auto-starting backup system. Beware: backup program is missing here!
#!/usr/bin/env bash
##############################################################################
#
# Manual configuration:
#
readonly IS_TEST=false
readonly CRYPTNAME=cryptback
readonly SOURCE_DIR=/mnt/data
readonly BACKUP_DIR=/mnt/backup
readonly BACKUP_DEVNAME=backup
readonly PROFILE=esprimo
##############################################################################
#
# Auto configuration and check of the prerequisites:
#
if ! timeout 1s xset q &>/dev/null || [ "${EUID}" -ne 0 ]
then
>&2 echo "[FATAL] Please run as root in your regular X user session."
exit 1
fi
readonly ABS_APP_DIR=$( dirname $( readlink -f "$0" ))
readonly BACKUP_CMD="${ABS_APP_DIR}/backup.sh"
readonly CRYPT_UUID=$( grep -Po "^\s*${CRYPTNAME}\s+UUID=\K[^\s]+" /etc/crypttab )
readonly X_USER=${USER}
if [ ! -f "${BACKUP_CMD}" ]
then
>&2 echo "[FATAL] Missing file ${BACKUP_CMD}"
exit 1
fi
if [ -z "${CRYPT_UUID}" ]
then
>&2 echo "[FATAL] Missing UUID for ${CRYPT_UUID} in /etc/crypttab"
exit 1
fi
if [ "${IS_TEST}" = true ]
then
readonly PREFIX="${ABS_APP_DIR}/test"
else
readonly PREFIX=
fi
mkdir -p "${PREFIX}/lib/systemd/system"
mkdir -p "${PREFIX}/etc/udev/rules.d"
##############################################################################
#
# Start installation:
#
echo "[INFO] Installing to '${PREFIX}/' directory..."
###########
#
# Config-files for our $BACKUP_CMD
#
cat > "${PREFIX}/etc/backup-${PROFILE}" << EOL
readonly X_USER=${X_USER}
readonly SOURCE_DIR="${SOURCE_DIR}"
readonly BACKUP_DIR="${BACKUP_DIR}"
readonly CRYPTNAME=${CRYPTNAME}
readonly LOGPATH="/var/log/backup-${PROFILE}.log"
readonly EXCLFILE_PATH="${PREFIX}/etc/backup-${PROFILE}.exclude"
readonly NOTIFY_ICOPATH="${ABS_APP_DIR}/icon.png"
EOL
cat > "${PREFIX}/etc/backup-${PROFILE}.exclude" << EOL
*.swp
*.spam
*.*~
EOL
###########
#
# This udev rule creates /dev/$BACKUP_DEVNAME
# (systemd recognizes devices tagged 'systemd')
# and executes $BACKUP_CMD by triggering our systemd unit.
# Calling $BACKUP_CMD directly via RUN+="..."
# would cause errors (long running, crypt-deps, ...).
#
cat > "${PREFIX}/etc/udev/rules.d/999-backup-${PROFILE}.rules" << EOL
ACTION=="add", \\
ENV{ID_FS_UUID}=="${CRYPT_UUID}", \\
TAG+="systemd", \\
SYMLINK+="${BACKUP_DEVNAME}", \\
ENV{SYSTEMD_WANTS}="backup-${PROFILE}.service"
EOL
###########
#
# Systemd-Unit:
# Environment variables are required for 'notify-send' from
# systemd as root user. Values stem from the regular X user.
# Don't save to /etc/systemd/system because you won't be
# able to run systemctl mask
# (which creates same-named symlinks in same dir)
#
cat > "${PREFIX}/lib/systemd/system/backup-${PROFILE}.service" << EOL
[Unit]
Description=Backup
After=dev-${BACKUP_DEVNAME}.device
Wants=dev-${BACKUP_DEVNAME}.device
[Service]
ExecStart=${BACKUP_CMD}
Environment=DISPLAY=${DISPLAY}
Environment=XAUTHORITY=${XAUTHORITY}
Environment=DBUS_SESSION_BUS_ADDRESS=${DBUS_SESSION_BUS_ADDRESS}
Type=oneshot
[Install]
WantedBy=user.target
EOL
###########
#
# Reload everything:
#
if [ "${IS_TEST}" = false ]
then
systemctl daemon-reload &&
udevadm control --reload &&
udevadm trigger
systemctl unmask backup-${PROFILE}
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment