Skip to content

Commit 657dd8d

Browse files
nixos/ipfs-cluster: init (NixOS#292290)
2 parents 194d448 + 950324a commit 657dd8d

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

nixos/doc/manual/release-notes/rl-2505.section.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@
206206

207207
- [Pareto Security](https://paretosecurity.com/) is an alternative to corporate compliance solutions for companies that care about security but know it doesn't have to be invasive. Available as [services.paretosecurity](#opt-services.paretosecurity.enable)
208208

209+
- [ipfs-cluster](https://ipfscluster.io/), Pinset orchestration for IPFS. Available as [services.ipfs-cluster](#opt-services.ipfs-cluster.enable)
210+
209211
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
210212

211213
## Backward Incompatibilities {#sec-release-25.05-incompatibilities}

nixos/modules/module-list.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,7 @@
10191019
./services/network-filesystems/kubo.nix
10201020
./services/network-filesystems/litestream/default.nix
10211021
./services/network-filesystems/moosefs.nix
1022+
./services/network-filesystems/ipfs-cluster.nix
10221023
./services/network-filesystems/netatalk.nix
10231024
./services/network-filesystems/nfsd.nix
10241025
./services/network-filesystems/openafs/client.nix
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
{
2+
config,
3+
lib,
4+
pkgs,
5+
options,
6+
...
7+
}:
8+
let
9+
cfg = config.services.ipfs-cluster;
10+
11+
# secret is by envvar, not flag
12+
initFlags = toString [
13+
(lib.optionalString (cfg.initPeers != [ ]) "--peers")
14+
(lib.strings.concatStringsSep "," cfg.initPeers)
15+
];
16+
in
17+
{
18+
options = {
19+
20+
services.ipfs-cluster = {
21+
22+
enable = lib.mkEnableOption "Pinset orchestration for IPFS - requires ipfs daemon to be useful";
23+
24+
consensus = lib.mkOption {
25+
type = lib.types.enum [
26+
"raft"
27+
"crdt"
28+
];
29+
description = "Consensus protocol - 'raft' or 'crdt'. https://cluster.ipfs.io/documentation/guides/consensus/";
30+
};
31+
32+
dataDir = lib.mkOption {
33+
type = lib.types.str;
34+
default = "/var/lib/ipfs-cluster";
35+
description = "The data dir for ipfs-cluster.";
36+
};
37+
38+
initPeers = lib.mkOption {
39+
type = lib.types.listOf lib.types.str;
40+
default = [ ];
41+
description = "Peer addresses to initialize with on first run.";
42+
};
43+
44+
openSwarmPort = lib.mkOption {
45+
type = lib.types.bool;
46+
default = false;
47+
description = "Open swarm port, secured by the cluster secret. This does not expose the API or proxy. https://cluster.ipfs.io/documentation/guides/security/";
48+
};
49+
50+
secretFile = lib.mkOption {
51+
type = lib.types.nullOr lib.types.path;
52+
default = null;
53+
description = ''
54+
File containing the cluster secret in the format of EnvironmentFile as described by
55+
{manpage}`systemd.exec(5)`. For example:
56+
<programlisting>
57+
CLUSTER_SECRET=<replaceable>...</replaceable>
58+
</programlisting>
59+
60+
If null, a new secret will be generated on first run and stored in the data directory.
61+
A secret in the correct format can also be generated by: `openssl rand -hex 32`
62+
'';
63+
};
64+
};
65+
};
66+
67+
config = lib.mkIf cfg.enable {
68+
assertions = [
69+
{
70+
assertion = cfg.enable -> config.services.kubo.enable;
71+
message = "ipfs-cluster requires ipfs - configure and enable services.kubo";
72+
}
73+
];
74+
75+
environment.systemPackages = [ pkgs.ipfs-cluster ];
76+
77+
systemd.tmpfiles.rules = [
78+
"d '${cfg.dataDir}' - ${config.services.kubo.user} ${config.services.kubo.group} - -"
79+
];
80+
81+
systemd.services.ipfs-cluster-init = {
82+
path = [
83+
"/run/wrappers"
84+
pkgs.ipfs-cluster
85+
];
86+
environment.IPFS_CLUSTER_PATH = cfg.dataDir;
87+
wantedBy = [ "default.target" ];
88+
89+
serviceConfig = {
90+
ExecStart = [
91+
"${lib.getExe' pkgs.ipfs-cluster "ipfs-cluster-service"} init --consensus ${cfg.consensus} ${initFlags}"
92+
];
93+
Type = "oneshot";
94+
RemainAfterExit = true;
95+
User = config.services.kubo.user;
96+
Group = config.services.kubo.group;
97+
EnvironmentFile = lib.mkIf (cfg.secretFile != null) cfg.secretFile;
98+
};
99+
# only run once (= when the data directory is empty)
100+
unitConfig.ConditionDirectoryNotEmpty = "!${cfg.dataDir}";
101+
};
102+
103+
systemd.services.ipfs-cluster = {
104+
environment.IPFS_CLUSTER_PATH = cfg.dataDir;
105+
wantedBy = [ "multi-user.target" ];
106+
107+
wants = [ "ipfs-cluster-init.service" ];
108+
after = [ "ipfs-cluster-init.service" ];
109+
110+
serviceConfig = {
111+
Type = "notify";
112+
ExecStart = [ "${lib.getExe' pkgs.ipfs-cluster "ipfs-cluster-service"} daemon" ];
113+
User = config.services.kubo.user;
114+
Group = config.services.kubo.group;
115+
};
116+
};
117+
118+
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openSwarmPort [ 9096 ];
119+
};
120+
121+
meta = {
122+
maintainers = with lib.maintainers; [
123+
sorki
124+
];
125+
};
126+
}

0 commit comments

Comments
 (0)