{ config, lib, pkgs, ... }: with lib; let cfg = config.local.environ; vtmp-sync = pkgs.writeShellScript "vtmp-sync" '' if [ $# -ne 3 ]; then echo "usage: $0 " >&2 exit 1 fi local="$2" remote="$1" boot_id="$(echo "$3" | ${pkgs.coreutils}/bin/head -c8)" rsync="${lib.getExe pkgs.rsync}" cd "$HOME/vtmp" mkdir -p "$remote" declare -a rsync_opts rsync_opts+=("-glprtxz") rsync_opts+=("--open-noatime") rsync_opts+=("--preallocate") rsync_opts+=("--max-size=1G") rsync_opts+=("--rsh=${lib.getExe pkgs.openssh} -o BatchMode=yes") rsync_opts+=("--log-file=$remote/.rsync.log") rsync_opts+=("--filter=- /$local.$boot_id/") rsync_opts+=("--filter=- /$remote/") # Push to $remote from $local "$rsync" "''${rsync_opts[@]}" -- ./ "$remote:vtmp/$local.$boot_id/" # Pull from $remote to $local "$rsync" "''${rsync_opts[@]}" -- "$remote:vtmp/" "./$remote/" ''; in { options.local.environ = { vtmpSyncHost = mkOption { type = with lib.types; nullOr str; default = null; }; }; config = mkMerge [ (mkIf cfg.enable { systemd.user.tmpfiles.rules = [ "d %t/vtmp 0700" ]; home.file = { "vtmp".source = config.lib.file.mkOutOfStoreSymlink "/run/user/${toString config.local.uid}/vtmp"; }; gtk.gtk3.bookmarks = [ "file://${config.home.homeDirectory}/vtmp" "file://${config.home.homeDirectory}/tmp" ]; }) (mkIf (cfg.enable && cfg.vtmpSyncHost != null) { programs.ssh = { extraOptionOverrides.PermitLocalCommand = "yes"; matchBlocks.${cfg.vtmpSyncHost}.extraOptions.LocalCommand = "systemctl --user import-environment SSH_AUTH_SOCK; " + "systemctl --user start vtmp-sync.timer"; }; systemd.user = { targets.vtmp-sync-failure = { Unit = { Conflicts = ["vtmp-sync.timer"]; }; }; services.vtmp-sync = { Unit = { OnFailure = ["vtmp-sync-failure.target"]; }; Service = { ExecStart = "${vtmp-sync} ${cfg.vtmpSyncHost} %l %b"; }; }; timers.vtmp-sync = { Timer = { OnActiveSec = "15s"; OnUnitInactiveSec = "1h"; }; }; }; }) ]; }