New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] ipfs-cluster: systemd service #100871
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for writing this service. ipfs
seems to be a hot topic lately, so I'm sure this service will be appreciated 👍
I hope you find my suggestion helpful. Please don't hesitate to ask if anything I have written isn't clear. I'm addition to my comments I have a few questions:
- Do you know if upstream provides a
systemd
unit at all? - Have you considered any
systemd
hardening on this service? - Are any firewall holes required for proper operation?
- Does this program take a configuration file at all?
|
||
systemd.packages = [ pkgs.ipfs-cluster pkgs.coreutils ]; | ||
|
||
systemd.services.ipfs-cluster-init = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this entire service could be replaced with an ExecStartPre
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so? I am using unitConfig.ConditionDirectoryNotEmpty = "!${cfg.dataDir}"; on -init to prevent it being run every time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like you could have a preStart
script that just checks if the directory exists then calls the init command if not. Save the hassle of a second unit. That's sorta what ExecStartPre
is for.
opt = options.services.ipfs-cluster; | ||
|
||
# secret is by envvar, not flag | ||
initFlags = toString [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe initFlags = optionalString (cfg.initPeers != []) "--peers ${lib.concatStringsSep "," cfg.initPeers}";
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured there would be more flags soon enough
Thank you for your feedback!
Thanks for pointing out the problem with readFile; git grepping nixpkgs, I see that duplicity uses EnvironmentFile = cfg.secretFile to have systemd read the secret at runtime. |
This will need a way to change arbitrary settings (in particular, all the addresses in the config). I wrote a module a while ago that uses the environment variable overrides to enable that while avoiding edits to |
e4fdac8
to
5747989
Compare
Rebased to current master. |
Very cool, +1 interest |
5747989
to
aa7dc2e
Compare
Any updates on this PR, please? |
Yeah, sorry. I'm going to rebase and try to test that minimal functionality is working. |
aa7dc2e
to
70f514b
Compare
Would there be a way to write a test for this service? |
You'd need to spawn 2 containers, connect them, pass data back and forth. I think this PR should go ahead without automated tests. It's been taking long enough. I'm trying to figure out |
Ok, tested the following so far:
|
Should we manage the user for the service?
|
Group = cfg.group; | ||
}; | ||
}; | ||
networking.firewall.allowedTCPPorts = [ 9096 ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think just opening a firewall port here is a good idea.
If you want this it should be hidden behind a openFirewall
option that is off by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a peer-to-peer service; it's expected that peers can connect. If enough other peers are available in the configured cluster, it should work without an open port, but not as well. In many configurations it just won't do anything without an open port.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lordcirth I think it's still best practice in nixpkgs to make it explicit via an openFirewall
option
It uses the ipfs user by default, which is created by the ipfs service. ipfs-cluster is largely useless without an ipfs daemon anyway. |
@lordcirth I present "exhibit A": security.acme.acceptTerms... which does absolutely nothing at all. Sometimes we just need the user to acknowledge that a module is implicitly doing something, by explicitly stating such 🤷♂️ |
What is the different between |
70f514b
to
adc9727
Compare
services.ipfs-cluster = { | ||
|
||
enable = mkEnableOption | ||
"Pinset orchestration for IPFS - requires ipfs daemon to be useful"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reads like I'd have to do something with ipfs daemon
to make this work, but the daemon is started by this service, right?
While the first paragraph from their repo is not all that much more informative, it at least contains more information to understand what this is even about:
IPFS Cluster provides data orchestration across a swarm of IPFS daemons by allocating, replicating and tracking a global pinset distributed among multiple peers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this starts the ipfs-cluster daemon. You would usually want to enable the ipfs daemon as well, but it's not a hard dependency as you could be running ipfs via a different module, in a separate container, etc.
No default so the user can't miss it.
@@ -82,6 +82,7 @@ in { | |||
wantedBy = [ "default.target" ]; | |||
|
|||
serviceConfig = { | |||
# "" clears exec list (man systemd.service -> execStart) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is such an obscure thing to do, seriously systemd
... I had to read carefully to find that, and it seems it does not even apply to all list-type options.
https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
LGTM |
Is there anything preventing us from getting this merged? (I'm looking forward to using it, or even testing it!) |
You should test this before this get's merged so we know it works :D (at least that would be great) |
I marked this as stale due to inactivity. → More info |
1.0.0 has recently been out with breaking changes, need anything be done aside from the version bump here? |
"There are no breaking configuration changes". Sounds like the breaking is in the API. |
👀 |
Anything that's blocking the merge? I've been running servers based on this PR for more than a year now. |
@lordcirth, could you please rebase this on top of master or unstable? |
@lordcirth Are you still working on this MR? |
Not really, sorry. |
Making this WIP PR to avoid someone duplicating effort while I work on it. It will need to be squashed.
Motivation for this change
ipfs-cluster is meant to be run as a daemon
Things done
Created systemd service for ipfs-cluster, and an -init service, with some basic settings
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)