diff options
author | Marek Mahut <marek.mahut@gmail.com> | 2020-06-26 21:17:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-26 21:17:36 +0200 |
commit | bb7c60708ac768e8011fe0563711cb56b1693b2d (patch) | |
tree | d79ebf2c0f0df5e102658d6d92ef4745d7c66f5b /nixos | |
parent | edddbd3d1b9ce17f9818a60f18eb9c41a41b3e81 (diff) | |
parent | c6d346b323043cdf84517a4723e358c2fc55011b (diff) | |
download | nixpkgs-bb7c60708ac768e8011fe0563711cb56b1693b2d.tar nixpkgs-bb7c60708ac768e8011fe0563711cb56b1693b2d.tar.gz nixpkgs-bb7c60708ac768e8011fe0563711cb56b1693b2d.tar.bz2 nixpkgs-bb7c60708ac768e8011fe0563711cb56b1693b2d.tar.lz nixpkgs-bb7c60708ac768e8011fe0563711cb56b1693b2d.tar.xz nixpkgs-bb7c60708ac768e8011fe0563711cb56b1693b2d.tar.zst nixpkgs-bb7c60708ac768e8011fe0563711cb56b1693b2d.zip |
Merge pull request #91497 from 1000101/blockbook
nixos/blockbook-frontend: init
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/networking/blockbook-frontend.nix | 272 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/blockbook-frontend.nix | 28 |
4 files changed, 302 insertions, 0 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index fd6294f2d7c..cf25ae3157e 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -589,6 +589,7 @@ ./services/networking/autossh.nix ./services/networking/bird.nix ./services/networking/bitlbee.nix + ./services/networking/blockbook-frontend.nix ./services/networking/charybdis.nix ./services/networking/cjdns.nix ./services/networking/cntlm.nix diff --git a/nixos/modules/services/networking/blockbook-frontend.nix b/nixos/modules/services/networking/blockbook-frontend.nix new file mode 100644 index 00000000000..61938e51e06 --- /dev/null +++ b/nixos/modules/services/networking/blockbook-frontend.nix @@ -0,0 +1,272 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + eachBlockbook = config.services.blockbook-frontend; + + blockbookOpts = { config, lib, name, ...}: { + + options = { + + enable = mkEnableOption "blockbook-frontend application."; + + package = mkOption { + type = types.package; + default = pkgs.blockbook; + description = "Which blockbook package to use."; + }; + + user = mkOption { + type = types.str; + default = "blockbook-frontend-${name}"; + description = "The user as which to run blockbook-frontend-${name}."; + }; + + group = mkOption { + type = types.str; + default = "${config.user}"; + description = "The group as which to run blockbook-frontend-${name}."; + }; + + certFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/etc/secrets/blockbook-frontend-${name}/certFile"; + description = '' + To enable SSL, specify path to the name of certificate files without extension. + Expecting <filename>certFile.crt</filename> and <filename>certFile.key</filename>. + ''; + }; + + configFile = mkOption { + type = with types; nullOr path; + default = null; + example = "${config.dataDir}/config.json"; + description = "Location of the blockbook configuration file."; + }; + + coinName = mkOption { + type = types.str; + default = "Bitcoin"; + example = "Bitcoin"; + description = '' + See <link xlink:href="https://github.com/trezor/blockbook/blob/master/bchain/coins/blockchain.go#L61"/> + for current of coins supported in master (Note: may differ from release). + ''; + }; + + cssDir = mkOption { + type = types.path; + default = "${config.package}/share/css/"; + example = "${config.dataDir}/static/css/"; + description = '' + Location of the dir with <filename>main.css</filename> CSS file. + By default, the one shipped with the package is used. + ''; + }; + + dataDir = mkOption { + type = types.path; + default = "/var/lib/blockbook-frontend-${name}"; + description = "Location of blockbook-frontend-${name} data directory."; + }; + + debug = mkOption { + type = types.bool; + default = false; + description = "Debug mode, return more verbose errors, reload templates on each request."; + }; + + internal = mkOption { + type = types.nullOr types.str; + default = ":9030"; + example = ":9030"; + description = "Internal http server binding <literal>[address]:port</literal>."; + }; + + messageQueueBinding = mkOption { + type = types.str; + default = "tcp://127.0.0.1:38330"; + example = "tcp://127.0.0.1:38330"; + description = "Message Queue Binding <literal>address:port</literal>."; + }; + + public = mkOption { + type = types.nullOr types.str; + default = ":9130"; + example = ":9130"; + description = "Public http server binding <literal>[address]:port</literal>."; + }; + + rpc = { + url = mkOption { + type = types.str; + default = "http://127.0.0.1"; + description = "URL for JSON-RPC connections."; + }; + + port = mkOption { + type = types.port; + default = 8030; + description = "Port for JSON-RPC connections."; + }; + + user = mkOption { + type = types.str; + default = "rpc"; + example = "rpc"; + description = "Username for JSON-RPC connections."; + }; + + password = mkOption { + type = types.str; + default = "rpc"; + example = "rpc"; + description = '' + RPC password for JSON-RPC connections. + Warning: this is stored in cleartext in the Nix store!!! + Use <literal>configFile</literal> or <literal>passwordFile</literal> if needed. + ''; + }; + + passwordFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing password of the RPC user. + Note: This options is ignored when <literal>configFile</literal> is used. + ''; + }; + }; + + sync = mkOption { + type = types.bool; + default = true; + description = "Synchronizes until tip, if together with zeromq, keeps index synchronized."; + }; + + templateDir = mkOption { + type = types.path; + default = "${config.package}/share/templates/"; + example = "${config.dataDir}/templates/static/"; + description = "Location of the HTML templates. By default, ones shipped with the package are used."; + }; + + extraConfig = mkOption { + type = types.attrs; + default = {}; + example = literalExample '' { + alternative_estimate_fee = "whatthefee-disabled"; + alternative_estimate_fee_params = "{\"url\": \"https://whatthefee.io/data.json\", \"periodSeconds\": 60}"; + fiat_rates = "coingecko"; + fiat_rates_params = "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"bitcoin\", \"periodSeconds\": 60}"; + coin_shortcut = "BTC"; + coin_label = "Bitcoin"; + xpub_magic = 76067358; + xpub_magic_segwit_p2sh = 77429938; + xpub_magic_segwit_native = 78792518; + }''; + description = '' + Additional configurations to be appended to <filename>coin.conf</filename>. + Overrides any already defined configuration options. + See <link xlink:href="https://github.com/trezor/blockbook/tree/master/configs/coins"/> + for current configuration options supported in master (Note: may differ from release). + ''; + }; + + extraCmdLineOptions = mkOption { + type = types.listOf types.str; + default = []; + example = [ "-workers=1" "-dbcache=0" "-logtosderr" ]; + description = '' + Extra command line options to pass to Blockbook. + Run blockbook --help to list all available options. + ''; + }; + }; + }; +in +{ + # interface + + options = { + services.blockbook-frontend = mkOption { + type = types.attrsOf (types.submodule blockbookOpts); + default = {}; + description = "Specification of one or more blockbook-frontend instances."; + }; + }; + + # implementation + + config = mkIf (eachBlockbook != {}) { + + systemd.services = mapAttrs' (blockbookName: cfg: ( + nameValuePair "blockbook-frontend-${blockbookName}" ( + let + configFile = if cfg.configFile != null then cfg.configFile else + pkgs.writeText "config.conf" (builtins.toJSON ( { + coin_name = "${cfg.coinName}"; + rpc_user = "${cfg.rpc.user}"; + rpc_pass = "${cfg.rpc.password}"; + rpc_url = "${cfg.rpc.url}:${toString cfg.rpc.port}"; + message_queue_binding = "${cfg.messageQueueBinding}"; + } // cfg.extraConfig) + ); + in { + description = "blockbook-frontend-${blockbookName} daemon"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + preStart = '' + ln -sf ${cfg.templateDir} ${cfg.dataDir}/static/ + ln -sf ${cfg.cssDir} ${cfg.dataDir}/static/ + ${optionalString (cfg.rpc.passwordFile != null && cfg.configFile == null) '' + CONFIGTMP=$(mktemp) + ${pkgs.jq}/bin/jq ".rpc_pass = \"$(cat ${cfg.rpc.passwordFile})\"" ${configFile} > $CONFIGTMP + mv $CONFIGTMP ${cfg.dataDir}/${blockbookName}-config.json + ''} + ''; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + ExecStart = '' + ${cfg.package}/bin/blockbook \ + ${if (cfg.rpc.passwordFile != null && cfg.configFile == null) then + "-blockchaincfg=${cfg.dataDir}/${blockbookName}-config.json" + else + "-blockchaincfg=${configFile}" + } \ + -datadir=${cfg.dataDir} \ + ${optionalString (cfg.sync != false) "-sync"} \ + ${optionalString (cfg.certFile != null) "-certfile=${toString cfg.certFile}"} \ + ${optionalString (cfg.debug != false) "-debug"} \ + ${optionalString (cfg.internal != null) "-internal=${toString cfg.internal}"} \ + ${optionalString (cfg.public != null) "-public=${toString cfg.public}"} \ + ${toString cfg.extraCmdLineOptions} + ''; + Restart = "on-failure"; + WorkingDirectory = cfg.dataDir; + LimitNOFILE = 65536; + }; + } + ) )) eachBlockbook; + + systemd.tmpfiles.rules = flatten (mapAttrsToList (blockbookName: cfg: [ + "d ${cfg.dataDir} 0750 ${cfg.user} ${cfg.group} - -" + "d ${cfg.dataDir}/static 0750 ${cfg.user} ${cfg.group} - -" + ]) eachBlockbook); + + users.users = mapAttrs' (blockbookName: cfg: ( + nameValuePair "blockbook-frontend-${blockbookName}" { + name = cfg.user; + group = cfg.group; + home = cfg.dataDir; + isSystemUser = true; + })) eachBlockbook; + + users.groups = mapAttrs' (instanceName: cfg: ( + nameValuePair "${cfg.group}" { })) eachBlockbook; + }; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 1e065c804c7..debc60a21d0 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -33,6 +33,7 @@ in bees = handleTest ./bees.nix {}; bind = handleTest ./bind.nix {}; bittorrent = handleTest ./bittorrent.nix {}; + blockbook-frontend = handleTest ./blockbook-frontend.nix {}; buildkite-agents = handleTest ./buildkite-agents.nix {}; boot = handleTestOn ["x86_64-linux"] ./boot.nix {}; # syslinux is unsupported on aarch64 boot-stage1 = handleTest ./boot-stage1.nix {}; diff --git a/nixos/tests/blockbook-frontend.nix b/nixos/tests/blockbook-frontend.nix new file mode 100644 index 00000000000..67d0fcab947 --- /dev/null +++ b/nixos/tests/blockbook-frontend.nix @@ -0,0 +1,28 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "blockbook-frontend"; + meta = with pkgs.stdenv.lib; { + maintainers = with maintainers; [ maintainers."1000101" ]; + }; + + machine = { ... }: { + services.blockbook-frontend."test" = { + enable = true; + }; + services.bitcoind = { + enable = true; + rpc = { + port = 8030; + users.rpc.passwordHMAC = "acc2374e5f9ba9e62a5204d3686616cf$53abdba5e67a9005be6a27ca03a93ce09e58854bc2b871523a0d239a72968033"; + }; + }; + }; + + testScript = '' + start_all() + machine.wait_for_unit("blockbook-frontend-test.service") + + machine.wait_for_open_port(9030) + + machine.succeed("curl -sSfL http://localhost:9030 | grep 'Blockbook'") + ''; +}) |