Skip to content
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

Add spruned application and nixos module #50382

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Expand Up @@ -609,6 +609,7 @@
./services/networking/smokeping.nix
./services/networking/softether.nix
./services/networking/spiped.nix
./services/networking/spruned.nix
./services/networking/squid.nix
./services/networking/sslh.nix
./services/networking/ssh/lshd.nix
Expand Down
51 changes: 51 additions & 0 deletions nixos/modules/services/networking/spruned.nix
@@ -0,0 +1,51 @@
{ config, lib, pkgs, ... }:

with lib;

let
cfg = config.services.spruned;

cliArgs = "--datadir ${cfg.dataDir} --network bitcoin.${cfg.network} ${cfg.extraArguments}";
in
{
options = {
services.spruned = {
enable = mkEnableOption "The spruned lightweight Bitcoin pseudonode daemon service";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might be sad that you used a capital "T" here.

description = "Whether to enable ${name}."; https://github.com/NixOS/nixpkgs/blob/master/lib/options.nix#L68

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😅

dataDir = mkOption {
jb55 marked this conversation as resolved.
Show resolved Hide resolved
type = types.str;
default = "/var/lib/spruned";
description = ''
Directory to store cached block data and spruned logs.
'';
};
network = mkOption {
type = types.enum [ "mainnet" "testnet" ];
default = "mainnet";
description = ''
Whether to use Bitcoin mainnet or testnet.
'';
};
extraArguments = mkOption {
type = types.separatedString " ";
example = "--mempoolsize 20 --debug";
default = "";
description = ''
Additional arguments to be passed to spruned.
'';
};
};
};

config = mkIf cfg.enable {
systemd.user.services.spruned = {
description = "spruned service";
after = [ "local-fs.target" "network.target" ];
wantedBy = [ "multi-user.target" ];

serviceConfig = {
Restart = "on-abort";
ExecStart = "${pkgs.spruned}/bin/spruned ${cliArgs}";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like this, the service runs as root. Try using the DynamicUser and StateDirectory systemd settings (man systemd.exec) to prevent that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so I tried running it as non-root by first using user services and then assigned users, but spruned calls out to ping and doesn't work without it. I couldn't figure out how to make a systemd service that uses ping and isn't root. I looked into the CapabilityBoundingSet CAP_NET_RAW thing but it didn't seem to work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use /run/wrappers/bin/ping instead of the ping in iputils. And really try to use DynamicUser, I think it should work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I'll try to take another pass at this and patch spruned to use /run/wrappers/bin/ping and switch to DynamicUser. Why DynamicUser instead of a user service?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DynamicUser lets you can run an un-elevated service without assigning it a system user id.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting this when I try to run with DynamicUser:

Nov 17 12:42:17 monad systemd[1]: Started spruned service.
Nov 17 12:42:17 monad spruned[17804]: Failed to import the site module
Nov 17 12:42:17 monad spruned[17804]: Traceback (most recent call last):
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/site.py", line 544, in <module>
Nov 17 12:42:17 monad spruned[17804]:     main()
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/site.py", line 530, in main
Nov 17 12:42:17 monad spruned[17804]:     known_paths = addusersitepackages(known_paths)
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/site.py", line 282, in addusersitepackages
Nov 17 12:42:17 monad spruned[17804]:     user_site = getusersitepackages()
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/site.py", line 258, in getusersitepackages
Nov 17 12:42:17 monad spruned[17804]:     user_base = getuserbase() # this will also set USER_BASE
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/site.py", line 248, in getuserbase
Nov 17 12:42:17 monad spruned[17804]:     USER_BASE = get_config_var('userbase')
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/sysconfig.py", line 601, in get_config_var
Nov 17 12:42:17 monad spruned[17804]:     return get_config_vars().get(name)
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/sysconfig.py", line 558, in get_config_vars
Nov 17 12:42:17 monad spruned[17804]:     _CONFIG_VARS['userbase'] = _getuserbase()
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/sysconfig.py", line 205, in _getuserbase
Nov 17 12:42:17 monad spruned[17804]:     return joinuser("~", ".local")
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/sysconfig.py", line 184, in joinuser
Nov 17 12:42:17 monad spruned[17804]:     return os.path.expanduser(os.path.join(*args))
Nov 17 12:42:17 monad spruned[17804]:   File "/nix/store/nrl0l79a48924xb0897ap572xf29ciir-python3-3.6.6/lib/python3.6/posixpath.py", line 249, in expanduser
Nov 17 12:42:17 monad spruned[17804]:     userhome = pwd.getpwuid(os.getuid()).pw_dir
Nov 17 12:42:17 monad spruned[17804]: KeyError: 'getpwuid(): uid not found: 61833'
Nov 17 12:42:17 monad systemd[1]: spruned.service: Main process exited, code=exited, status=1/FAILURE
Nov 17 12:42:17 monad systemd[1]: spruned.service: Failed with result 'exit-code'.

};
};
};
}
3 changes: 2 additions & 1 deletion pkgs/applications/altcoins/default.nix
@@ -1,4 +1,4 @@
{ callPackage, boost155, boost165, openssl_1_1, haskellPackages, darwin, libsForQt5, miniupnpc_2, python3, buildGo110Package }:
{ callPackage, boost155, boost165, openssl_1_1, darwin, libsForQt5, miniupnpc_2, python3, buildGo110Package }:

rec {

Expand All @@ -7,6 +7,7 @@ rec {
bitcoin = libsForQt5.callPackage ./bitcoin.nix { miniupnpc = miniupnpc_2; withGui = true; };
bitcoind = callPackage ./bitcoin.nix { miniupnpc = miniupnpc_2; withGui = false; };
clightning = callPackage ./clightning.nix { };
spruned = callPackage ./spruned { };

bitcoin-abc = libsForQt5.callPackage ./bitcoin-abc.nix { boost = boost165; withGui = true; };
bitcoind-abc = callPackage ./bitcoin-abc.nix { boost = boost165; withGui = false; };
Expand Down
53 changes: 53 additions & 0 deletions pkgs/applications/altcoins/spruned/default.nix
@@ -0,0 +1,53 @@
{ stdenv, python3 }:

let
pythonPackages = python3.pkgs;
in
with stdenv.lib;
pythonPackages.buildPythonApplication rec {
pname = "spruned";
version = "0.0.4b4";

src = pythonPackages.fetchPypi {
inherit pname version;
sha256 = "b156ad410ae71651aafb4ffc639ad491614622a53b3cb8211fd49e2579642f18";
};

disabled = ! pythonPackages.pythonAtLeast "3.5";

propagatedBuildInputs =
with pythonPackages; [
async-timeout
jsonrpcserver
sqlalchemy
plyvel
daemonize
aiohttp
pycoin
];

patchPhase = ''
sed -i 's,import spruned,,;s,spruned.__version__,"${version}",' setup.py

substituteInPlace spruned/application/tools.py \
--replace "subprocess.call(['ping" "subprocess.call(['/run/wrappers/bin/ping"

substituteInPlace requirements.txt \
--replace 'sqlalchemy==1.2.6' 'sqlalchemy==1.2.*' \
--replace 'aiohttp==3.0.0b0' aiohttp \
--replace 'daemonize==2.4.7' daemonize \
--replace 'async-timeout==2.0.1' async-timeout \
--replace 'jsonrpcserver==3.5.3' jsonrpcserver \
--replace 'plyvel==0.9.0' plyvel
'';

doCheck = false;

meta = {
description = "A Bitcoin lightweight pseudonode with RPC that can fetch any block or transaction";
homepage = https://github.com/gdassori/spruned;
maintainers = with maintainers; [ jb55 ];
license = licenses.mit;
platforms = platforms.linux;
};
}
19 changes: 19 additions & 0 deletions pkgs/development/python-modules/apply-defaults/default.nix
@@ -0,0 +1,19 @@
{ stdenv, buildPythonPackage, fetchPypi, pytest
}:

buildPythonPackage rec {
pname = "apply_defaults";
version = "0.1.1";

src = fetchPypi {
inherit pname version;
sha256 = "b8c1bc511a0368dabe1af4d80b97186296e25182d7e371d920a9633cf6a2a385";
};

meta = with stdenv.lib; {
homepage = https://github.com/bcb/apply_defaults;
description = "Apply default values to functions";
license = licenses.free;
maintainers = with maintainers; [ jb55 ];
};
}
23 changes: 23 additions & 0 deletions pkgs/development/python-modules/jsonrpcserver/default.nix
@@ -0,0 +1,23 @@
{ stdenv, buildPythonPackage, fetchPypi, pytest, jsonschema, funcsigs, apply-defaults, mypy, six
}:

buildPythonPackage rec {
pname = "jsonrpcserver";
version = "3.5.6";

src = fetchPypi {
inherit pname version;
sha256 = "8442af3632ebf012c773aea78639e1ad3f605cda2ffcc58d6e4e34ecf8b4a167";
};

propagatedBuildInputs = [ apply-defaults jsonschema funcsigs six ];

doCheck = false;

meta = with stdenv.lib; {
homepage = https://github.com/bcb/jsonrpcserver;
description = "Process JSON-RPC requests in Python";
license = licenses.mit;
maintainers = with maintainers; [ jb55 ];
};
}
22 changes: 22 additions & 0 deletions pkgs/development/python-modules/pycoin/default.nix
@@ -0,0 +1,22 @@
{ stdenv, fetchPypi, buildPythonPackage, tox, pytest }:

buildPythonPackage rec {
pname = "pycoin";
version = "0.80";

src = fetchPypi{
inherit pname version;
sha256 = "a79a7771c3f6ca2e35667e80983987f0c799c5db01e58016c22a12e8484b2034";
};

checkInputs = [ tox pytest ];

checkPhase = "tox";

meta = with stdenv.lib; {
description = "Utilities for Bitcoin and altcoin addresses and transaction manipulation";
homepage = https://github.com/richardkiss/pycoin;
license = licenses.mit;
maintainers = with maintainers; [ jb55 ];
};
}
1 change: 1 addition & 0 deletions pkgs/top-level/all-packages.nix
Expand Up @@ -15819,6 +15819,7 @@ with pkgs;

bitcoin = altcoins.bitcoin;
clightning = altcoins.clightning;
spruned = altcoins.spruned;

bitcoin-xt = altcoins.bitcoin-xt;
cryptop = altcoins.cryptop;
Expand Down
6 changes: 6 additions & 0 deletions pkgs/top-level/python-packages.nix
Expand Up @@ -182,6 +182,8 @@ in {

ansicolor = callPackage ../development/python-modules/ansicolor { };

apply-defaults = callPackage ../development/python-modules/apply-defaults { };

argon2_cffi = callPackage ../development/python-modules/argon2_cffi { };

asana = callPackage ../development/python-modules/asana { };
Expand Down Expand Up @@ -1263,6 +1265,8 @@ in {

jsonrpc-websocket = callPackage ../development/python-modules/jsonrpc-websocket { };

jsonrpcserver = callPackage ../development/python-modules/jsonrpcserver {};

onkyo-eiscp = callPackage ../development/python-modules/onkyo-eiscp { };

pyunifi = callPackage ../development/python-modules/pyunifi { };
Expand Down Expand Up @@ -1317,6 +1321,8 @@ in {

cffi = callPackage ../development/python-modules/cffi { };

pycoin = callPackage ../development/python-modules/pycoin { };

pycollada = callPackage ../development/python-modules/pycollada { };

pycontracts = callPackage ../development/python-modules/pycontracts { };
Expand Down