aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetri Hienonen <petri.hienonen@gmail.com>2026-01-08 15:28:31 +0200
committerPetri Hienonen <petri.hienonen@gmail.com>2026-01-08 15:28:31 +0200
commita84fad525618fe6a92c2adc5506bad8979f774d0 (patch)
tree260713ad6be9594b6c8552166724d97c8725c1ef
parente36e260b039045fa10a0e669c918ef2feddfb0ab (diff)
downloadnixos-a84fad525618fe6a92c2adc5506bad8979f774d0.tar.zst
Add automount
-rw-r--r--roles/shared.nix146
1 files changed, 130 insertions, 16 deletions
diff --git a/roles/shared.nix b/roles/shared.nix
index 45a092d..35f0d44 100644
--- a/roles/shared.nix
+++ b/roles/shared.nix
@@ -189,7 +189,10 @@
"d /run/pam_timestamp 0700 root root -"
];
services = {
- "systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug";
+ systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
+ nix-daemon = {
+ environment.TMPDIR = "/var/tmp";
+ };
};
settings.Manager = {
DefaultTimeoutStopSec = 10;
@@ -206,10 +209,6 @@
AllowSuspendThenHibernate=yes
HibernateDelaySec=3600
'';
-
- services.nix-daemon = {
- environment.TMPDIR = "/var/tmp";
- };
};
powerManagement = {
@@ -682,6 +681,10 @@
SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="55d3", MODE:="0666"
# ESP32S3 waveshare
SUBSYSTEM=="usb", ATTR{idVendor}=="303a", ATTR{idProduct}=="1001", MODE:="0666"
+ # Automount
+ KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="add", RUN+="${pkgs.systemd}/bin/systemctl start usb-mount@%k.service"
+ # Autoremove
+ KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="${pkgs.systemd}/bin/systemctl stop usb-mount@%k.service"
'';
getty.autologinUser = "${vars.user}";
kmscon = {
@@ -795,6 +798,106 @@
};
environment.etc = {
+ "usb-mount.sh" = {
+ mode = "0755";
+ source = pkgs.writeShellScript "usb-mount" ''
+ # This script is called from our systemd unit file to mount or unmount
+ # a USB drive.
+
+ usage()
+ {
+ echo "Usage: $0 {add|remove} device_name (e.g. sdb1)"
+ exit 1
+ }
+
+ if [[ $# -ne 2 ]]; then
+ usage
+ fi
+
+ ACTION=$1
+ DEVBASE=$2
+ DEVICE="/dev/$DEVBASE"
+
+ # See if this drive is already mounted, and if so where
+ MOUNT_POINT=$(${pkgs.util-linux}/bin/mount | ${pkgs.gnugrep}/bin/grep $DEVICE | ${pkgs.gawk}/bin/awk '{ print $3 }')
+
+ do_mount()
+ {
+ if [[ -n $MOUNT_POINT ]]; then
+ echo "Warning: $DEVICE is already mounted at $MOUNT_POINT"
+ exit 1
+ fi
+
+ # Get info for this drive: $ID_FS_LABEL, $ID_FS_UUID, and $ID_FS_TYPE
+ eval $(${pkgs.util-linux}/bin/blkid -o udev $DEVICE)
+
+ # Figure out a mount point to use
+ LABEL=$ID_FS_LABEL
+ if [[ -z "$LABEL" ]]; then
+ LABEL=$DEVBASE
+ elif ${pkgs.gnugrep}/bin/grep -q " /media/$LABEL " /etc/mtab; then
+ # Already in use, make a unique one
+ LABEL+="-$DEVBASE"
+ fi
+ MOUNT_POINT="/media/$LABEL"
+
+ echo "Mount point: $MOUNT_POINT"
+
+ ${pkgs.coreutils}/bin/mkdir -p $MOUNT_POINT
+
+ # Global mount options
+ OPTS="rw,relatime"
+
+ # File system type specific mount options
+ if [[ $ID_FS_TYPE == "vfat" ]]; then
+ OPTS+=",users,gid=100,umask=000,shortname=mixed,utf8=1,flush"
+ fi
+
+ if ! /bin/mount -o $OPTS $DEVICE $MOUNT_POINT; then
+ echo "Error mounting $DEVICE (status = $?)"
+ ${pkgs.coreutils}/bin/rmdir $MOUNT_POINT
+ exit 1
+ fi
+
+ echo "**** Mounted $DEVICE at $MOUNT_POINT ****"
+ }
+
+ do_unmount()
+ {
+ if [[ -z $MOUNT_POINT ]]; then
+ echo "Warning: $DEVICE is not mounted"
+ else
+ ${pkgs.coreutils}/bin/umount -l $DEVICE
+ echo "**** Unmounted $DEVICE"
+ fi
+
+ # Delete all empty dirs in /media that aren't being used as mount
+ # points. This is kind of overkill, but if the drive was unmounted
+ # prior to removal we no longer know its mount point, and we don't
+ # want to leave it orphaned...
+ for f in /media/* ; do
+ if [[ -n $(${pkgs.findutils}/bin/find "$f" -maxdepth 0 -type d -empty) ]]; then
+ if ! ${pkgs.gnugrep}/bin/grep -q " $f " /etc/mtab; then
+ echo "**** Removing mount point $f"
+ ${pkgs.coreutils}/bin/rmdir "$f"
+ fi
+ fi
+ done
+ }
+
+ case "$ACTION" in
+ add)
+ do_mount
+ ;;
+ remove)
+ do_unmount
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ '';
+ };
"greetd/hyprland-wrapper.sh" = {
source = pkgs.writeShellScript "hyperland-wrapper" ''
export XDG_SESSION_TYPE=wayland
@@ -844,17 +947,28 @@
};
};
- systemd.services.bluetooth-tether = {
- description = "Auto-connect to Bluetooth tethering PAN if device is detected";
- after = [ "bluetooth.service" ];
- partOf = [ "bluetooth.service" ];
- wantedBy = [ "multi-user.target" ];
- serviceConfig = {
- Type = "oneshot";
- ExecStart = "/etc/bluetooth-tether.sh";
- RemainAfterExit = true;
- Restart = "on-failure";
- RestartSec = "30s"; # Retry every 30 seconds if the device isn't found
+ systemd.services = {
+ bluetooth-tether = {
+ description = "Auto-connect to Bluetooth tethering PAN if device is detected";
+ after = [ "bluetooth.service" ];
+ partOf = [ "bluetooth.service" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ Type = "oneshot";
+ ExecStart = "/etc/bluetooth-tether.sh";
+ RemainAfterExit = true;
+ Restart = "on-failure";
+ RestartSec = "30s"; # Retry every 30 seconds if the device isn't found
+ };
+ };
+ "usb-mount@" = {
+ description = "Mount USB Drive on %i";
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ ExecStart = "/etc/usb-mount.sh add %i";
+ ExecStop = "/etc/usb-mount.sh remove %i";
+ };
};
};
}