From f7c2133250cef7d63857ab48bee63d62dacbb18e Mon Sep 17 00:00:00 2001 From: Erik Arvstedt Date: Mon, 16 Aug 2021 10:42:07 +0200 Subject: [PATCH] add flake support This change is fully backwards compatible. We continue to use the standard non-flake evaluation mode in our examples and internal tooling until the flakes design has stabilized. 'clightning-plugins = pkgs.recurseIntoAttrs' in pkgs/default.nix is needed by flake-utils.lib.flattenTree in flake.nix. It transforms the packages in `clightning-plugins` to top-level packages named like `clightning-plugins/summary`. (The flake attr `packages` must be a non-nested attrset of derivations.) --- examples/README.md | 10 +++- examples/flakes/flake.nix | 49 ++++++++++++++++++ flake.lock | 60 +++++++++++++++++++++ flake.nix | 106 ++++++++++++++++++++++++++++++++++++++ pkgs/default.nix | 2 +- pkgs/nixpkgs-pinned.nix | 23 +++++---- test/run-tests.sh | 9 ++++ 7 files changed, 246 insertions(+), 13 deletions(-) create mode 100644 examples/flakes/flake.nix create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/examples/README.md b/examples/README.md index 445f846..20e3d0f 100644 --- a/examples/README.md +++ b/examples/README.md @@ -69,9 +69,17 @@ c systemctl status bitcoind ``` See [`run-tests.sh`](../test/run-tests.sh) for a complete documentation. - ### Real-world example Check the [server repo](https://github.com/fort-nix/nixbitcoin.org) for https://nixbitcoin.org to see the configuration of a nix-bitcoin node that's used in production. The commands in `shell.nix` allow you to locally run the node in a VM or container. + +### Flakes + +Flakes make it easy to include `nix-bitcoin` in an existing NixOS config. +The [flakes example](./flakes/flake.nix) shows how to use `nix-bitcoin` as an input to a system flake. + +Run `nix run` or `nix run .#vm` from the nix-bitcoin root directory to start an example +nix-bitcoin node VM. +This command is defined by the nix-bitcoin flake (in [flake.nix](../flake.nix)). diff --git a/examples/flakes/flake.nix b/examples/flakes/flake.nix new file mode 100644 index 0000000..aaaff29 --- /dev/null +++ b/examples/flakes/flake.nix @@ -0,0 +1,49 @@ +{ + description = "A basic nix-bitcoin node"; + + inputs.nix-bitcoin.url = "github:fort-nix/nix-bitcoin"; + + outputs = { self, nix-bitcoin }: { + + nixosConfigurations.mynode = nix-bitcoin.inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + ## Note: + ## If you use a custom nixpkgs version for evaluating your system, + ## consider using `withLockedPkgs` instead of `withSystemPkgs` to use the exact + ## pkgs versions for nix-bitcoin services that are tested by nix-bitcoin. + ## The downsides are increased evaluation times and increased system + ## closure size. + # + # nix-bitcoin.nixosModules.withLockedPkgs + nix-bitcoin.nixosModules.withSystemPkgs + + ## Optional: + ## Import the secure-node preset, an opinionated config to enhance security + ## and privacy. + # + # "${nix-bitcoin}/modules/presets/secure-node.nix" + + { + nix-bitcoin.generateSecrets = true; + + services.bitcoind.enable = true; + + # When using nix-bitcoin as part of a larger NixOS configuration, set the following to enable + # interactive access to nix-bitcoin features (like bitcoin-cli) for your system's main user + nix-bitcoin.operator = { + enable = true; + name = "main"; # Set this to your system's main user + }; + + # The system's main unprivileged user. This setting is usually part of your + # existing NixOS configuration. + users.users.main = { + isNormalUser = true; + password = "a"; + }; + } + ]; + }; + }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..00d2d9f --- /dev/null +++ b/flake.lock @@ -0,0 +1,60 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1623875721, + "narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "f7e004a55b120c02ecb6219596820fcd32ca8772", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1628865210, + "narHash": "sha256-dB3IA8AYUQDXH+Xy/6nbv4QpIbVl88DphbcxJSUYiX4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a445f5829889959d65ad65e5c961d5c67e1cd677", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-21.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgsUnstable": { + "locked": { + "lastModified": 1628779307, + "narHash": "sha256-ErivbgE5SGvNdFpq+Q50lw1JGGmvxBR/d71aW41S+1A=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "4138cbd913fad85073e59007710e3f083d0eb7c6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "nixpkgsUnstable": "nixpkgsUnstable" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..12828a1 --- /dev/null +++ b/flake.nix @@ -0,0 +1,106 @@ +{ + description = '' + A collection of Nix packages and NixOS modules for easily + installing full-featured Bitcoin nodes with an emphasis on security. + ''; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.05"; + nixpkgsUnstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, nixpkgsUnstable, flake-utils }: + let + supportedSystems = [ "x86_64-linux" "i686-linux" "aarch64-linux" ]; + in + rec { + mkNbPkgs = { + system + , pkgs ? import nixpkgs { inherit system; } + , pkgsUnstable ? import nixpkgsUnstable { inherit system; } + }: + import ./pkgs { inherit pkgs pkgsUnstable; }; + + overlay = final: prev: let + nbPkgs = mkNbPkgs { inherit (final) system; pkgs = final; }; + in removeAttrs nbPkgs [ "pinned" "nixops19_09" "krops" ]; + + nixosModules = { + # Uses the default system pkgs for nix-bitcoin.pkgs + withSystemPkgs = { pkgs, ... }: { + imports = [ ./modules/modules.nix ]; + nix-bitcoin.pkgs = (mkNbPkgs { inherit (pkgs) system; inherit pkgs; }).modulesPkgs; + }; + + # Uses the nixpkgs version locked by this flake for nix-bitcoin.pkgs. + # More stable, but slightly slower to evaluate and needs more space if the + # locked and the system nixpkgs versions differ. + withLockedPkgs = { config, ... }: { + imports = [ ./modules/modules.nix ]; + nix-bitcoin.pkgs = (mkNbPkgs { inherit (config.nixpkgs) system; }).modulesPkgs; + }; + }; + + defaultTemplate = { + description = "Basic node template"; + path = ./examples/flakes; + }; + + } // (flake-utils.lib.eachSystem supportedSystems (system: + let + pkgs = import nixpkgs { inherit system; }; + + mkVMScript = vm: pkgs.writers.writeBash "run-vm" '' + set -euo pipefail + export TMPDIR=$(mktemp -d /tmp/nix-bitcoin-vm.XXX) + trap "rm -rf $TMPDIR" EXIT + export NIX_DISK_IMAGE=$TMPDIR/nixos.qcow2 + QEMU_OPTS="-smp $(nproc) -m 1500" ${vm}/bin/run-*-vm + ''; + in rec { + nbPkgs = self.mkNbPkgs { inherit system pkgs; }; + + packages = flake-utils.lib.flattenTree (removeAttrs nbPkgs [ + "pinned" "modulesPkgs" "nixops19_09" "krops" + ]) // { + runVM = mkVMScript packages.vm; + + # This is a simple demo VM. + # See ./examples/flakes/flake.nix on how to use nix-bitcoin with flakes. + vm = let + nix-bitcoin = self; + in + (import "${nixpkgs}/nixos" { + inherit system; + configuration = { + imports = [ + nix-bitcoin.nixosModules.withSystemPkgs + "${nix-bitcoin}/modules/presets/secure-node.nix" + ]; + + nix-bitcoin.generateSecrets = true; + services.clightning.enable = true; + # For faster startup in offline VMs + services.clightning.extraConfig = "disable-dns"; + + nixpkgs.pkgs = pkgs; + virtualisation.graphics = false; + services.getty.autologinUser = "root"; + nix.nixPath = [ "nixpkgs=${nixpkgs}" ]; + }; + }).vm; + }; + + defaultApp = apps.vm; + + apps = { + # Run a basic nix-bitcoin node in a VM + vm = { + type = "app"; + program = toString packages.runVM; + }; + }; + } + )); +} diff --git a/pkgs/default.nix b/pkgs/default.nix index 039cd08..1e41b01 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -14,7 +14,7 @@ let self = { krops = import ./krops { }; netns-exec = pkgs.callPackage ./netns-exec { }; extra-container = pkgs.callPackage ./extra-container { }; - clightning-plugins = import ./clightning-plugins pkgs self.nbPython3Packages; + clightning-plugins = pkgs.recurseIntoAttrs (import ./clightning-plugins pkgs self.nbPython3Packages); clboss = pkgs.callPackage ./clboss { }; secp256k1 = pkgs.callPackage ./secp256k1 { }; diff --git a/pkgs/nixpkgs-pinned.nix b/pkgs/nixpkgs-pinned.nix index 0b57e7e..d3f3acc 100644 --- a/pkgs/nixpkgs-pinned.nix +++ b/pkgs/nixpkgs-pinned.nix @@ -1,19 +1,20 @@ let - fetch = { rev, sha256 }: + fetchNixpkgs = { rev, sha256 }: builtins.fetchTarball { url = "https://github.com/nixos/nixpkgs/archive/${rev}.tar.gz"; inherit sha256; }; + + fetch = input: let + inherit (input) locked; + in fetchNixpkgs { + inherit (locked) rev; + sha256 = locked.narHash; + }; + + lockedInputs = (builtins.fromJSON (builtins.readFile ../flake.lock)).nodes; in { - # To update, run ../helper/fetch-channel REV - nixpkgs = fetch { - # nixos-21.05 (2021-08-14) - rev = "a445f5829889959d65ad65e5c961d5c67e1cd677"; - sha256 = "0zl930jjacdphplw1wv5nlhjk15zvflzzwp53zbh0l8qq01wh7bl"; - }; - nixpkgs-unstable = fetch { - rev = "4138cbd913fad85073e59007710e3f083d0eb7c6"; - sha256 = "0l7vaa6mnnmxfxzi9i5gd4c4j3cpfh7gjsjsfk6nnj1r05pazf0j"; - }; + nixpkgs = fetch lockedInputs.nixpkgs; + nixpkgs-unstable = fetch lockedInputs.nixpkgsUnstable; } diff --git a/test/run-tests.sh b/test/run-tests.sh index 7990308..241f142 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -281,9 +281,18 @@ examples() { (cd "$scriptDir/../examples" && nix-shell --run "$script") } +flake() { + if [[ $(nix flake 2>&1) != *"requires a sub-command"* ]]; then + echo "Skipping flake test. Nix flake support is not enabled." + else + nix flake check "$scriptDir/.." + fi +} + all() { buildable examples + flake } # An alias for buildTest