-
Notifications
You must be signed in to change notification settings - Fork 8
/
flake.nix
221 lines (218 loc) · 8.81 KB
/
flake.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/24.05";
kadena-nix = {
url = "github:kadena-io/kadena-nix";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
};
};
flake-utils.url = "github:numtide/flake-utils";
flake-compat.url = "github:kadena-io/flake-compat";
devenv.url = "github:cachix/devenv";
# The pact-override input is not a true input to this flake, but it is used
# to override the pact input of chainweb-node optionally. chainweb-node's
# pact input is normally a trivial "empty" flake, which tells it to use
# the pact package from its cabal.project, but a non-"empty" flake overrides it.
pact-override.follows = "chainweb-node/empty";
chainweb-node = {
url = "github:kadena-io/chainweb-node";
inputs.pact.follows = "pact-override";
};
chainweb-data.url = "github:kadena-io/chainweb-data";
chainweb-mining-client.url = "github:kadena-io/chainweb-mining-client";
block-explorer.url = "github:kadena-io/block-explorer/devnet";
nix-exe-bundle = { url = "github:3noch/nix-bundle-exe"; flake = false; };
process-compose = {
url = "github:F1bonacc1/process-compose";
inputs = { nixpkgs.follows = "nixpkgs"; flake-utils.follows = "flake-utils"; };
};
};
outputs = { self
, nixpkgs
, devenv
, ... } @ inputs:
inputs.flake-utils.lib.eachDefaultSystem (system: let
bundle = drv:
let bundled = pkgs.callPackage inputs.nix-exe-bundle {} drv;
# We're exposing the bin contents in a new derivation because the bundling produces
# a /lib folder with duplicate files across different bundles, which causes problems
# while preparing the docker image root
bundledBin = pkgs.runCommand "${bundled.name}-bin" {} ''
mkdir -p $out/bin
ln -s ${bundled}/bin/* $out/bin
'';
in bundledBin // {
version = drv.version or drv.meta.version or null;
};
pact = let
cwnDefault = inputs.chainweb-node.packages.${system}.default;
pactMeta = cwnDefault.cached.meta.pact;
pactSrc = pkgs.fetchgit {
inherit (pactMeta.src) rev url;
sha256 = pactMeta.src.hash;
name = "source";
};
pactFlake = (import inputs.flake-compat { src = pactSrc; }).defaultNix;
meta = {
flakeInfo.rev = pactMeta.src.rev;
flakeInfo.shortRev = builtins.substring 0 7 pactMeta.src.rev;
version = pactMeta.version;
};
in bundle pactFlake.packages.${system}.default // meta;
get-flake-info = import nix/lib/get-flake-info.nix inputs;
bundleWithInfo = inputs: let
get-flake-info = import nix/lib/get-flake-info.nix inputs;
in flakeName: let
flakeInfo = get-flake-info flakeName;
default = inputs.${flakeName}.packages.${system}.default;
in bundle default // { inherit flakeInfo; };
bundleWithInfo' = bundleWithInfo inputs;
withNpmjsInfo = drv: let
inherit (drv) packageName version;
flakeInfo.revLink = "https://npmjs.com/package/${packageName}/v/${version}";
in drv // { inherit flakeInfo; }
;
overlay = (self: super: {
chainweb-data = bundleWithInfo' "chainweb-data";
chainweb-mining-client = bundleWithInfo' "chainweb-mining-client";
chainweb-node = bundleWithInfo' "chainweb-node";
pact = pact;
block-explorer = inputs.block-explorer.packages.x86_64-linux.static // {
flakeInfo = get-flake-info "block-explorer";
};
kadena-graph = withNpmjsInfo kadena-nix-pkgs.kadena-graph;
kadena-cli = withNpmjsInfo kadena-nix-pkgs.kadena-cli;
mining-trigger = pkgs.haskellPackages.callCabal2nix "mining-trigger" nix/pkgs/mining-trigger {};
});
pkgs = import nixpkgs { inherit system; overlays = [ overlay ]; };
kadena-nix-pkgs = inputs.kadena-nix.packages.${system};
devnetInfo = {
devnetVersion = "0.1.0";
devnetRepo = "https://github.com/kadena-io/devnet";
devnetRevision = self.rev or null;
};
modules = [
# https://devenv.sh/reference/options/
nix/modules/init.nix
nix/modules/postgres.nix
nix/modules/chainweb-data.nix
nix/modules/chainweb-node.nix
nix/modules/chainweb-mining-client.nix
nix/modules/http-server.nix
nix/modules/ttyd.nix
nix/modules/sqlpage.nix
nix/modules/landing-page/module.nix
nix/modules/pact-cli.nix
nix/modules/process-compose.nix
nix/modules/devnet-mode.nix
nix/modules/explorer.nix
nix/modules/utils.nix
nix/modules/graph.nix
{
sites.landing-page = devnetInfo;
process-managers.process-compose.package =
inputs.process-compose.packages.${system}.process-compose;
}
];
packageExtras = {
};
containerExtras = with pkgs.lib; {config, ...}: {
devenv.root = "/devnet";
services.chainweb-data.extra-migrations-folders = [ "/cwd-extra-migrations" ];
sites.landing-page.container-api.enable = mkDefault true;
services.postgres.forward-socket-port = mkDefault 5432;
services.postgres.remove-lock-files = true;
services.pact-cli.working-directory = mkDefault "/pact-cli";
sites.landing-page.container-api.folders = mkBefore "- `/data`: Persistent data folder";
init.container-init = ''
mkdir /cwd-extra-migrations
mkdir /pact-cli
'';
init.devnet-init = ''
# Assert that these folders are mounted as read-only
for dir in /cwd-extra-migrations /pact-cli; do
dir_mount="^[^\S]+ $dir"
(${pkgs.gnugrep}/bin/grep -E "$dir_mount" /proc/mounts || true) | while read -r mount; do
is_readonly="$dir_mount [^\S]+ ro"
if ! [[ $mount =~ $is_readonly ]]; then
echo "Error: $dir should be mounted as read-only."
exit 1
fi
done
done
'';
};
mkFlake = cfgName: cfgPos: extraModule:
import nix/mkDevnetFlake.nix {
inherit pkgs nixpkgs devenv containerExtras packageExtras;
containerTag = cfgName;
modules = modules ++ [
extraModule
{
sites.landing-page = {
devnetConfig = cfgName;
} // pkgs.lib.optionalAttrs (cfgPos != null) {devnetConfigPos = cfgPos;};
}
];
};
configurations = rec {
minimal = {
services.chainweb-node.enable = true;
services.chainweb-mining-client.enable = true;
services.http-server.enable = true;
};
default = {
imports = [minimal];
services.chainweb-data.enable = true;
services.graph.enable = true;
sites.explorer.enable = true;
utils.kadena-cli.enable = true;
};
crashnet = {
imports = [default];
services.postgres.forward-socket-port = null;
services.chainweb-node.throttle = true;
services.chainweb-data.throttle = true;
services.chainweb-mining-client.expose-make-blocks = false;
};
container-default = {
imports = [default];
services.ttyd.enable = true;
services.pact-cli.enable = true;
};
# Useful for iterating on nginx configurations
http-only = {
services.http-server.enable = true;
# Keep process-compose alive even if nginx dies
processes.sleep.exec = "sleep 100";
sites.explorer.enable = true;
};
};
mkCfgPos = cfgName:
let pos = builtins.unsafeGetAttrPos cfgName configurations;
in { file = pkgs.lib.strings.removePrefix "${self}/" pos.file; line = pos.line; };
combined-flake = import nix/lib/combine-flakes.nix pkgs.lib (
builtins.mapAttrs (cfgName: config: mkFlake cfgName (mkCfgPos cfgName) config) configurations
);
in pkgs.lib.recursiveUpdate combined-flake {
apps.develop-page = {
type = "app";
program = (import nix/lib/develop-page.nix {inherit pkgs;}).outPath;
};
apps.develop-sqlpage = {
type = "app";
program = (pkgs.writeShellScript "develop-sqlpage" ''
DEVNET_VARIANT="''${1:-container-default}"
export SQLPAGE_PORT_OVERRIDE=8091
${pkgs.watchexec}/bin/watchexec --on-busy-update restart -- \
nix run --impure ".#$DEVNET_VARIANT/runSqlpage"
'').outPath;
};
packages.mining-trigger = pkgs.mining-trigger;
inherit configurations;
overlays.default = overlay;
lib = { inherit mkFlake bundleWithInfo; };
});
}