nixos/preload: init
[NixPkgs.git] / nixos / modules / services / network-filesystems / kbfs.nix
blob33ff283d5e81d2cc7420177a3a5a6d5fee66fe5b
1 { config, lib, pkgs, ... }:
2 with lib;
3 let
4   inherit (config.security) wrapperDir;
5   cfg = config.services.kbfs;
7 in {
9   ###### interface
11   options = {
13     services.kbfs = {
15       enable = mkOption {
16         type = types.bool;
17         default = false;
18         description = lib.mdDoc "Whether to mount the Keybase filesystem.";
19       };
21       enableRedirector = mkOption {
22         type = types.bool;
23         default = false;
24         description = lib.mdDoc ''
25           Whether to enable the Keybase root redirector service, allowing
26           any user to access KBFS files via `/keybase`,
27           which will show different contents depending on the requester.
28         '';
29       };
31       mountPoint = mkOption {
32         type = types.str;
33         default = "%h/keybase";
34         example = "/keybase";
35         description = lib.mdDoc "Mountpoint for the Keybase filesystem.";
36       };
38       extraFlags = mkOption {
39         type = types.listOf types.str;
40         default = [];
41         example = [
42           "-label kbfs"
43           "-mount-type normal"
44         ];
45         description = lib.mdDoc ''
46           Additional flags to pass to the Keybase filesystem on launch.
47         '';
48       };
50     };
51   };
53   ###### implementation
55   config = mkIf cfg.enable (mkMerge [
56     {
57       # Upstream: https://github.com/keybase/client/blob/master/packaging/linux/systemd/kbfs.service
58       systemd.user.services.kbfs = {
59         description = "Keybase File System";
61         # Note that the "Requires" directive will cause a unit to be restarted whenever its dependency is restarted.
62         # Do not issue a hard dependency on keybase, because kbfs can reconnect to a restarted service.
63         # Do not issue a hard dependency on keybase-redirector, because it's ok if it fails (e.g., if it is disabled).
64         wants = [ "keybase.service" ] ++ optional cfg.enableRedirector "keybase-redirector.service";
65         path = [ "/run/wrappers" ];
66         unitConfig.ConditionUser = "!@system";
68         serviceConfig = {
69           Type = "notify";
70           # Keybase notifies from a forked process
71           EnvironmentFile = [
72             "-%E/keybase/keybase.autogen.env"
73             "-%E/keybase/keybase.env"
74           ];
75           ExecStartPre = [
76             "${pkgs.coreutils}/bin/mkdir -p \"${cfg.mountPoint}\""
77             "-${wrapperDir}/fusermount -uz \"${cfg.mountPoint}\""
78           ];
79           ExecStart = "${pkgs.kbfs}/bin/kbfsfuse ${toString cfg.extraFlags} \"${cfg.mountPoint}\"";
80           ExecStop = "${wrapperDir}/fusermount -uz \"${cfg.mountPoint}\"";
81           Restart = "on-failure";
82           PrivateTmp = true;
83         };
84         wantedBy = [ "default.target" ];
85       };
87       services.keybase.enable = true;
89       environment.systemPackages = [ pkgs.kbfs ];
90     }
92     (mkIf cfg.enableRedirector {
93       security.wrappers."keybase-redirector".source = "${pkgs.kbfs}/bin/redirector";
95       systemd.tmpfiles.rules = [ "d /keybase 0755 root root 0" ];
97       # Upstream: https://github.com/keybase/client/blob/master/packaging/linux/systemd/keybase-redirector.service
98       systemd.user.services.keybase-redirector = {
99         description = "Keybase Root Redirector for KBFS";
100         wants = [ "keybase.service" ];
101         unitConfig.ConditionUser = "!@system";
103         serviceConfig = {
104           EnvironmentFile = [
105             "-%E/keybase/keybase.autogen.env"
106             "-%E/keybase/keybase.env"
107           ];
108           # Note: The /keybase mount point is not currently configurable upstream.
109           ExecStart = "${wrapperDir}/keybase-redirector /keybase";
110           Restart = "on-failure";
111           PrivateTmp = true;
112         };
114         wantedBy = [ "default.target" ];
115       };
116     })
117   ]);