~aasg/nixexprs

ref: 0b021297578a635bdf65f31b96e02ff38125a319 nixexprs/modules/services/cluster/ipfs-cluster/default.nix -rw-r--r-- 4.1 KiB
0b021297 — Aluísio Augusto Silva Gonçalves patches/ipfs-cluster: Patch to enable connecting to IPFS via Unix socket 10 months ago
                                                                                
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{ config, lib, pkgs, ... }:
with lib;
let
  settingsToEnv =
    let
      settingToNVP = prefix: name: value:
        let
          envName = toUpper "${prefix}_${name}";
        in
        if builtins.isAttrs value then
          settingsToNVP envName value
        else if builtins.isList value then
          nameValuePair envName (concatStringsSep "," value)
        else
          nameValuePair envName (toString value);
      settingsToNVP = prefix: settings:
        flatten (mapAttrsToList (settingToNVP prefix) settings);
    in
    settings: builtins.listToAttrs (settingsToNVP "cluster" settings);

  cfg = config.services.ipfs-cluster;

  # Is the cluster secret file in a home directory?
  secretInHome = cfg.secretFile != null && (
    hasPrefix "/root" cfg.secretFile || hasPrefix "/home" cfg.secretFile
  );
in
{
  options = {
    services.ipfs-cluster = {
      enable = mkEnableOption "IPFS Cluster daemon";

      package = mkOption {
        type = types.package;
        default = pkgs.ipfs-cluster;
        defaultText = "pkgs.ipfs-cluster";
        description = "ipfs-cluster package to use.";
      };

      user = mkOption {
        type = types.str;
        default = "ipfs";
        description = "User under which the IPFS Cluster daemon runs";
      };

      group = mkOption {
        type = types.str;
        default = "ipfs";
        description = "Group under which the IPFS Cluster daemon runs";
      };

      dataDir = mkOption {
        type = types.str;
        default = "/var/lib/ipfs-cluster";
        description = "Directory where cluster management data lives.";
      };

      secretFile = mkOption {
        type = with types; nullOr str;
        default = null;
        description = "File containing the cluster secret. If none is given, a secret is generated during cluster creation.";
      };

      consensus = mkOption {
        type = types.enum [ "crdt" "raft" ];
        description = "Consensus component utilized by the cluster. This option has no effect on already existing clusters.";
      };

      bootstrapPeers = mkOption {
        type = with types; listOf str;
        default = [ ];
        description = "List of peers to bootstrap the node with. This option has no effect on already existing clusters.";
      };

      settings = mkOption {
        type = types.attrs;
        default = { };
        description = "Additional IPFS Cluster settings. These follow the names for configuration environment variables, not for the service.json file.";
      };
    };
  };

  config = mkIf cfg.enable {
    environment.systemPackages = [ cfg.package ];

    systemd.services.ipfs-cluster = {
      description = "IPFS Cluster daemon";
      after = [ "network-online.target" "ipfs.service" ];
      wants = [ "network-online.target" ];
      wantedBy = [ "multi-user.target" ];
      environment = {
        IPFS_CLUSTER_PATH = cfg.dataDir;
      } // settingsToEnv cfg.settings;
      serviceConfig = {
        Type = "simple";
        User = cfg.user;
        Group = cfg.group;
        Restart = "on-abnormal";
        StartLimitInterval = 14400;
        StartLimitBurst = 10;
        AmbientCapabilities = "cap_net_bind_service";
        CapabilityBoundingSet = "cap_net_bind_service";
        NoNewPrivileges = true;
        LimitNPROC = 512;
        LimitNOFILE = 1048576;
        PrivateTmp = true;
        PrivateDevices = true;
        ProtectHome = if secretInHome then "read-only" else true;
        ProtectSystem = "full";
        ReadWriteDirectories = cfg.dataDir;
        TimeoutStopSec = "5s";
      };
      preStart = ''
        ${optionalString (cfg.secretFile != null) ''
          read -r CLUSTER_SECRET <${cfg.secretFile}
        ''}
        if [[ ! -f ${cfg.dataDir}/service.json ]]; then
          ${cfg.package}/bin/ipfs-cluster-service init \
            --consensus ${cfg.consensus} \
            ${optionalString (cfg.bootstrapPeers != [ ]) "--peers ${concatStringsSep "," cfg.bootstrapPeers}"}
        fi
      '';
      script = ''
        ${optionalString (cfg.secretFile != null) ''
          read -r CLUSTER_SECRET <${cfg.secretFile}
        ''}
        exec ${cfg.package}/bin/ipfs-cluster-service daemon
      '';
    };
  };
}