Skip to content

Commit

Permalink
Add nixos service and scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
jbgi committed Nov 29, 2021
1 parent 9f59c44 commit 2279b1b
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -46,3 +46,6 @@ hie.yaml

### Docs build
/_build/

### databases of scripts
/db-cardano-wallet-*
20 changes: 16 additions & 4 deletions flake.nix
Expand Up @@ -26,14 +26,21 @@
config = import ./nix/config.nix lib customConfig;
cardanoWalletLib = import ./nix/util.nix { inherit lib; };
inherit (flake-utils.lib) eachSystem mkApp flattenTree;
inherit (iohkNix.lib) prefixNamesWith;
inherit (iohkNix.lib) evalService;
supportedSystems = import ./nix/supported-systems.nix;
defaultSystem = lib.head supportedSystems;
overlay = final: prev:
{
cardanoWalletHaskellProject = self.legacyPackages.${final.system};
inherit (final.cardanoWalletHaskellProject.hsPkgs.cardano-wallet.components.exes) cardano-wallet;
};
nixosModule = { pkgs, lib, ... }: {
imports = [ ./nix/nixos/cardano-wallet-service.nix ];
services.cardano-node.project = lib.mkDefault self.legacyPackages.${pkgs.system};
};
nixosModules = {
cardano-wallet = nixosModule;
};
# Which exes should be put in the release archives.
releaseContents = jobs: map (exe: jobs.${exe}) [
"cardano-wallet"
Expand Down Expand Up @@ -153,7 +160,12 @@
checks = collectChecks isProjectPackage project.hsPkgs;
# `benchmarks` are only built, not run.
benchmarks = collectComponents "benchmarks" isProjectPackage project.hsPkgs;
});
}) //
# nix run .#<network>/wallet
(flattenTree (import ./nix/scripts.nix {
inherit project evalService;
customConfigs = [ config ];
}));
in self;

# See the imported file for how to use the docker build.
Expand Down Expand Up @@ -282,7 +294,7 @@
dockerImage = mkDockerImage packages;
};

apps = lib.mapAttrs (n: p: { type = "app"; program = if (p ? exePath) then p.exePath else "${p}/bin/${n}"; }) packages;
apps = lib.mapAttrs (n: p: { type = "app"; program = p.exePath or "${p}/bin/${p.name or n}"; }) packages;

devShell = project.shell;

Expand All @@ -294,7 +306,7 @@
in
lib.recursiveUpdate (removeAttrs systems [ "systemHydraJobs" ])
{
inherit overlay;
inherit overlay nixosModule nixosModules;
hydraJobs = lib.foldl' lib.mergeAttrs { } (lib.attrValues systems.systemHydraJobs) // {
inherit required;
};
Expand Down
2 changes: 1 addition & 1 deletion lib/cli/src/Cardano/CLI.hs
Expand Up @@ -1186,7 +1186,7 @@ hostPreferenceOption = option str $ mempty
<> long "listen-address"
<> metavar "HOST"
<> help
("Specification of which host to the bind API server to. " <>
("Specification of which host to bind the API server to. " <>
"Can be an IPv[46] address, hostname, or '*'.")
<> value "127.0.0.1"
<> showDefaultWith (const "127.0.0.1")
Expand Down
193 changes: 193 additions & 0 deletions nix/nixos/cardano-wallet-service.nix
@@ -0,0 +1,193 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.cardano-wallet;
inherit (lib) optionalString mkIf mkEnableOption mkOption types;
logLevels = types.enum [ "debug" "info" "notice" "warning" "error" "critical" "alert" "emergency" "off" ];
cardanoEnvAttrs = cfg.environments.${cfg.environment};
in
{
options.services.cardano-wallet = {

enable = mkEnableOption "Cardano Wallet service";

script = mkOption {
type = types.str;
internal = true;
default =
let
genesisFile = cardanoEnvAttrs.genesisFile
or cardanoEnvAttrs.nodeConfig.ByronGenesisFile;
in
toString ([
"exec ${cfg.package}/bin/cardano-wallet serve"
"--listen-address \"${cfg.listenAddress}\""
"--port ${toString cfg.port}"
"--node-socket \"$CARDANO_NODE_SOCKET_PATH\""
"--sync-tolerance ${toString cfg.syncTolerance}s"
"--pool-metadata-fetching ${if (cfg.poolMetadataFetching == "smash")
then cardanoEnvAttrs.smashUrl
else cfg.poolMetadataFetching}"
"--log-level ${cfg.logLevel}"
"--${cfg.walletMode}"
] ++ lib.optional (cfg.walletMode != "mainnet")
"\"${genesisFile}\""
++ lib.optional (cfg.tokenMetadataServer != null)
"--token-metadata-server ${cfg.tokenMetadataServer}"
++ lib.optional (cfg.database != null)
"--database \"${cfg.database}\""
++ lib.mapAttrsToList
(name: level: ''
--trace-${name}=${level} '')
cfg.trace
++ cfg.rtsArgs)
;
};

project = mkOption {
type = types.attrs;
default = (import ../.. { }).legacyPackages.${pkgs.system};
description = "The cardano-wallet haskell.nix project attribute set.";
};

package = mkOption {
type = types.package;
default = cfg.project.hsPkgs.cardano-wallet.components.exes.cardano-wallet;
description = "Package for the cardano wallet executable.";
};

listenAddress = mkOption {
type = types.str;
default = "*";
description = "Which host to bind the API server to.";
};

port = mkOption {
type = types.port;
default = 8090;
description = "The default port cardano wallet will listen on.";
};

nodeSocket = mkOption {
type = types.str;
default = "/run/cardano-node/node.socket";
description = ''Cardano-Node local communication socket path.'';
};

environment = mkOption {
type = types.enum (builtins.attrNames cfg.environments);
default = "testnet";
description = ''
The environment name to configure the wallet for.
This name can be an environment name from those found at
iohk-nix/cardano-lib/default.nix, or, it can be a custom
name, for example, if launching a test cluster that does
not have an environment yet defined in iohk-nix. If custom,
the environments option must contain an entry for this environment,
of the same form as in cardano-lib environments found
in iohk-nix.
'';
};

environments = mkOption {
type = types.attrsOf types.attrs;
default = cfg.project.pkgs.cardanoLib.environments;
description = ''
The set of possible environment attribute set to configure the wallet for.
Default to the set of environments found at
iohk-nix/cardano-lib/default.nix, or, it must be an attribute set
of the same form.
'';
};

walletMode = mkOption {
type = types.enum [ "mainnet" "staging" "testnet" ];
default =
if cfg.environment == "mainnet"
then "mainnet"
else if cfg.environment == "staging"
then "staging"
else "testnet";
description = "Which mode to start wallet in: --mainnet, --staging or --testnet";
};

database = mkOption {
type = types.nullOr types.str;
default = "$STATE_DIRECTORY";
description = ''Directory for storing wallets. Run in-memory if null.'';
};

syncTolerance = mkOption {
type = types.ints.positive;
default = 300;
description = "Time duration within which we consider being synced with the network. Expressed in seconds.";
};

poolMetadataFetching = mkOption {
type = types.enum [ "none" "direct" "smash" ];
default = if cardanoEnvAttrs ? smashUrl then "smash" else "none";
description = ''
Sets the stake pool metadata fetching strategy.
"smash" will use the 'smashUrl' attribute of the 'environnement'
as metadata proxy server (default if exists).
Use "direct" to fetch directly from the
registered pool URLs, or "none" to completely disable
stake pool metadata (default if no 'smashUrl' defined).'';
};

tokenMetadataServer = mkOption {
type = types.nullOr types.str;
default = cardanoEnvAttrs.metadataUrl or null;
description = ''
Sets the URL of the token metadata server,
default to 'metadataUrl' of the 'environnement' attribute, if exists.
If unset, metadata will not be fetched. By using this
option, you are fully trusting the operator of the
metadata server to provide authentic token metadata.
'';
};

logLevel = mkOption {
type = logLevels;
default = "info";
description = "Global minimum severity for a message to be logged.";
};

trace = mkOption {
type = types.attrsOf logLevels;
default = { };
description = ''
For each tracer, minimum severity for a message to be logged, or
"off" to disable the tracer".
'';
};

rtsArgs = mkOption {
type = types.listOf types.str;
default = [ "-N2" ];
apply = args:
if args != [ ] then
[ "+RTS" ] ++ args ++ [ "-RTS" ]
else [ ];
description = ''Extra CLI args for 'cardano-wallet', to be surrounded by "+RTS"/"-RTS"'';
};

};

config = mkIf cfg.enable {

systemd.services.cardano-wallet = {
description = "cardano-wallet daemon";
wantedBy = [ "multi-user.target" ];
inherit (cfg) script;

serviceConfig = {
DynamicUser = true;
StateDirectory = "cardano-wallet/${cfg.environment}";
};

environment = {
CARDANO_NODE_SOCKET_PATH = cfg.nodeSocket;
};
};
};
}
10 changes: 6 additions & 4 deletions nix/release-build.nix
Expand Up @@ -10,7 +10,7 @@

with pkgs.lib;

pkgs.stdenv.mkDerivation rec {
let drv = pkgs.stdenv.mkDerivation rec {
name = "${exe.identifier.name}-${version}";
version = exe.identifier.version;
phases = [ "installPhase" ];
Expand All @@ -20,7 +20,9 @@ pkgs.stdenv.mkDerivation rec {
# fixme: remove this
cp -Rv ${backend.deployments} $out/deployments
'');

meta.platforms = platforms.all;
passthru = optionalAttrs (backend != null) { inherit backend; };
}
passthru = {
exePath = drv + "/bin/cardano-wallet";
} // (optionalAttrs (backend != null) { inherit backend; });
};
in drv
56 changes: 56 additions & 0 deletions nix/scripts.nix
@@ -0,0 +1,56 @@
{ evalService
, project
, customConfigs
}:
with project.pkgs;
let
mkScript = envConfig:
let
service = evalService {
inherit pkgs customConfigs;
serviceName = "cardano-wallet";
modules = [
./nixos/cardano-wallet-service.nix
({ config, ... }: {
services.cardano-wallet = let cfg = config.services.cardano-wallet; in
{
project = lib.mkDefault project;
environment = lib.mkDefault envConfig.name;
database = lib.mkDefault "./db-cardano-wallet-${cfg.environment}";
};
})
];
};

in
writeScriptBin "cardano-wallet-${service.environment}" ''
#!${pkgs.runtimeShell}
set -euo pipefail
${service.script} $@
'';

debugDeps = with pkgs; [
coreutils
findutils
gnugrep
gnused
postgresql
strace
lsof
dnsutils
bashInteractive
iproute
curl
netcat
bat
tree
];

in
cardanoLib.forEnvironments (environment: lib.recurseIntoAttrs rec {
wallet = mkScript environment;
wallet-debug = pkgs.symlinkJoin {
inherit (wallet) name;
paths = [ wallet ] ++ debugDeps;
};
})

0 comments on commit 2279b1b

Please sign in to comment.