summaryrefslogtreecommitdiff
path: root/home/environ/vtmp.nix
blob: e15778d20b5aafb68977a3d2b923c07106367d8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.local.environ;

  vtmp-sync = pkgs.writeShellScript "vtmp-sync" ''
    if [ $# -ne 3 ]; then
      echo "usage: $0 <remote hostname> <local hostname> <boot id>" >&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";
          };
        };
      };
    })
  ];
}