1{ lib, ...} : {
2 name = "kubo";
3 meta = with lib.maintainers; {
4 maintainers = [ mguentner Luflosi ];
5 };
6
7 nodes.machine = { config, ... }: {
8 services.kubo = {
9 enable = true;
10 # Also will add a unix domain socket socket API address, see module.
11 startWhenNeeded = true;
12 settings.Addresses.API = "/ip4/127.0.0.1/tcp/2324";
13 dataDir = "/mnt/ipfs";
14 };
15 users.users.alice = {
16 isNormalUser = true;
17 extraGroups = [ config.services.kubo.group ];
18 };
19 };
20
21 nodes.fuse = { config, ... }: {
22 services.kubo = {
23 enable = true;
24 autoMount = true;
25 };
26 users.users.alice = {
27 isNormalUser = true;
28 extraGroups = [ config.services.kubo.group ];
29 };
30 users.users.bob = {
31 isNormalUser = true;
32 };
33 };
34
35 testScript = ''
36 start_all()
37
38 with subtest("Automatic socket activation"):
39 ipfs_hash = machine.succeed(
40 "echo fnord0 | su alice -l -c 'ipfs add --quieter'"
41 )
42 machine.succeed(f"ipfs cat /ipfs/{ipfs_hash.strip()} | grep fnord0")
43
44 machine.stop_job("ipfs")
45
46 with subtest("IPv4 socket activation"):
47 machine.succeed("ipfs --api /ip4/127.0.0.1/tcp/2324 id")
48 ipfs_hash = machine.succeed(
49 "echo fnord | ipfs --api /ip4/127.0.0.1/tcp/2324 add --quieter"
50 )
51 machine.succeed(f"ipfs cat /ipfs/{ipfs_hash.strip()} | grep fnord")
52
53 machine.stop_job("ipfs")
54
55 with subtest("Unix domain socket activation"):
56 ipfs_hash = machine.succeed(
57 "echo fnord2 | ipfs --api /unix/run/ipfs.sock add --quieter"
58 )
59 machine.succeed(
60 f"ipfs --api /unix/run/ipfs.sock cat /ipfs/{ipfs_hash.strip()} | grep fnord2"
61 )
62
63 with subtest("Setting dataDir works properly with the hardened systemd unit"):
64 machine.succeed("test -e /mnt/ipfs/config")
65 machine.succeed("test ! -e /var/lib/ipfs/")
66
67 with subtest("FUSE mountpoint"):
68 fuse.fail("echo a | su bob -l -c 'ipfs add --quieter'")
69 # The FUSE mount functionality is broken as of v0.13.0 and v0.17.0.
70 # See https://github.com/ipfs/kubo/issues/9044.
71 # Workaround: using CID Version 1 avoids that.
72 ipfs_hash = fuse.succeed(
73 "echo fnord3 | su alice -l -c 'ipfs add --quieter --cid-version=1'"
74 ).strip()
75
76 fuse.succeed(f"cat /ipfs/{ipfs_hash} | grep fnord3")
77
78 with subtest("Unmounting of /ipns and /ipfs"):
79 # Force Kubo to crash and wait for it to restart
80 fuse.systemctl("kill --signal=SIGKILL ipfs.service")
81 fuse.wait_for_unit("ipfs.service", timeout = 30)
82
83 fuse.succeed(f"cat /ipfs/{ipfs_hash} | grep fnord3")
84 '';
85}