~aasg/nixexprs

ref: 965f83e6ba0ba9a4962a622a05de6098afb047d9 nixexprs/modules/services/cluster/ipfs-cluster.nix -rw-r--r-- 4.1 KiB
965f83e6 — Aluísio Augusto Silva Gonçalves ipfs-cluster: Use secret file in new clusters 4 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
{ 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";
        AmbientCapabilities = "cap_net_bind_service";
        CapabilityBoundingSet = "cap_net_bind_service";
        NoNewPrivileges = true;
        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}
        export CLUSTER_SECRET
        ''}
        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}
        export CLUSTER_SECRET
        ''}
        exec ${cfg.package}/bin/ipfs-cluster-service daemon
      '';
    };
  };
}