Skip to content

Commit

Permalink
add dev helper and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
erikarvstedt committed Jan 15, 2023
1 parent b35d08d commit b4d7e1a
Show file tree
Hide file tree
Showing 12 changed files with 746 additions and 1 deletion.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ The nix-bitcoin security fund is a 2 of 3 bitcoin multisig address open for dona
security researchers who discover vulnerabilities in nix-bitcoin or its upstream dependencies.\
See [Security Fund](./SECURITY.md#nix-bitcoin-security-fund) for details.

Developing
---
See [dev/README](./dev/README.md).

Troubleshooting
---
If you are having problems with nix-bitcoin check the [FAQ](docs/faq.md) or submit an issue.\
Expand Down
104 changes: 104 additions & 0 deletions dev/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
This directory contains docs and helper scripts for developing and debugging:

- [`dev.sh`](./dev.sh): misc dev helpers
- [`dev-features.sh`](./dev-features.sh): helpers for developing specific
nix-bitcoin features, like services
- [`topics`](./topics) features specific topics
- [`dev-scenarios.nix`](./dev-scenarios.nix): extra test scenarios used in the above scripts

See also: [test/README.md](../test/README.md)

## Run a dev shell

There are two ways to run a dev shell:

### 1. Run command `nix develop`

This starts a shell with [`test/run-tests.sh`](../test/run-tests.sh) and
the scripts in dir [`helper`](../helper) added to `PATH`.

### 2. Setup and start the `direnv` dev env

This is an opinionated, [direnv](https://direnv.net/)-based dev env, optimized for developer experience.

[`dev-env/create.sh`](./dev-env/create.sh) creates a git repo with the following contents:
- Dir `src` which contains the nix-bitcoin repo
- Dir `bin` for helper scripts
- File `scenarios.nix` for custom test scenarios
- File `.envrc` that defines a [direnv](https://direnv.net/) environment,
mainly for adding nix-bitcoin and helper scripts to `PATH`

#### Installation

1. [Install direnv](https://direnv.net/docs/installation.html).\
If you use NixOS (and Bash as the default shell), just add the following to your system config:
```nix
environment.systemPackages = [ pkgs.direnv ];
programs.bash.interactiveShellInit = ''
eval "$(direnv hook bash)"
'';
```

2. Create the dev env:
```bash
# Set up a dev environment in dir ~/dev/nix-bitcoin.
# The dir is created automatically.
./dev-env/create.sh ~/dev/nix-bitcoin

cd ~/dev/nix-bitcoin

# Enable direnv
direnv allow
```

3. Optional: Editor integration
- Add envrc support to your editor
- Setup your editor so you can easily execute lines or paragraphs from a shell script
file in a shell.\
This simplifies using dev helper scripts like [`./dev.sh`](./dev.sh).

#### Explore the dev env
```bash
# The direnv is automatically activated when visiting any subdir of ~/dev/nix-bitcoin
cd ~/dev/nix-bitcoin

ls -al . bin lib

# The direnv config file
cat .envrc

# You can use this file to define extra scenarios
cat scenarios.nix

# Binary `dev-run-tests` runs nix-bitcoin's `run-tests.sh` with extra scenarios from ./scenarios.nix
# Example:
# Run command `nodeinfo` in `myscenario` (defined in ./scenarios.nix) via a container
dev-run-tests -s myscenario container --run c nodeinfo

# Equivalent (shorthand)
te -s myscenario container --run c nodeinfo

# Run the tests for `myscenario` in a VM
te -s myscenario

# Start an interactive shell inside a VM
te -s myscenario vm
```

See also: [test/README.md](../test/README.md)

## Adding a new service

It's easiest to use an existing service as a template:
- [electrs.nix](../modules/electrs.nix): a basic service
- [clightning.nix](../modules/clightning.nix): simple, but covers a few more features.\
(A `cli` binary and a runtime-composed config to include secrets.)
- [rtl.nix](../modules/rtl.nix): includes a custom package, defined in [pkgs/rtl](../pkgs/rtl).\
Most other services use packages that are already included in nixpkgs.

## Switching to a new NixOS release

- [flake.nix](../flake.nix): update `nixpkgs.url`
- [cirrus.yml](../.cirrus.yml): update toplevel container -> image attribute
- [examples/configuration.nix](../examples/configuration.nix): update `system.stateVersion`
- Treewide: check if any `TODO-EXTERNAL` comments can be resolved
65 changes: 65 additions & 0 deletions dev/dev-env/create.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# shellcheck disable=SC2016
set -euo pipefail

destDir=${1:-nix-bitcoin}

scriptDir=$(cd "${BASH_SOURCE[0]%/*}" && pwd)

mkdir -p "$destDir/"{bin,lib}
cd "$destDir"

if [[ ! -e src ]]; then
echo "Cloning fort-nix/nix-bitcoin"
git clone https://github.com/fort-nix/nix-bitcoin src
fi

echo 'export root=$PWD
export src=$root/src
PATH_add bin
PATH_add src/helper' > .envrc

if [[ ! -e scenarios.nix ]]; then
cp "$scriptDir/template-scenarios.nix" scenarios.nix
fi

install -m 755 <(
echo '#!/usr/bin/env bash'
echo 'exec run-tests.sh --extra-scenarios "$root/scenarios.nix" "$@"'
) bin/dev-run-tests

install -m 755 <(
echo '#!/usr/bin/env bash'
echo 'exec $root/src/test/run-tests.sh --out-link-prefix /tmp/nix-bitcoin/test "$@"'
) bin/run-tests.sh

ln -sfn dev-run-tests bin/te

## nix-bitcoin-firejail

echo '# Add your shell config files here that should be accessible in the sandbox
whitelist ${HOME}/.bashrc
read-only ${HOME}/.bashrc' > lib/nix-bitcoin-firejail.conf

install -m 755 <(
echo '#!/usr/bin/env bash'
echo '# A sandbox for running shells/binaries in an isolated environment:'
echo '# - The sandbox user is the calling user, with all capabilities dropped'
echo '# and with no way to gain new privileges (e.g. via `sudo`).'
echo '# - $HOME is bind-mounted to a dir that only contains shell config files and files required by direnv.'
echo '#'
echo '# You can modify the firejail env by editing `lib/nix-bitcoin-firejail.conf` in your dev env dir.'
echo 'exec firejail --profile="$root/lib/nix-bitcoin-firejail.conf" --profile="$root/src/dev/dev-env/nix-bitcoin-firejail.conf" "$@"'
) bin/nix-bitcoin-firejail

echo "1" > lib/dev-env-version

## git

echo '/src' > .gitignore

if [[ ! -e .git ]]; then
git init
git add .
git commit -a -m init
fi
16 changes: 16 additions & 0 deletions dev/dev-env/dev-shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pkgs:

pkgs.mkShell {
shellHook = ''
# A known rev from the master branch to test whether `nix develop`
# is called inside the nix-bitcoin repo
rev=5cafafd02777919c10e559b5686237fdefe920c2
if git cat-file -e $rev &>/dev/null; then
root=$(git rev-parse --show-toplevel)
export PATH=$root/test:$root/helper:$PATH
else
echo 'Error: `nix develop` must be called inside the nix-bitcoin repo.'
exit 1
fi
'';
}
25 changes: 25 additions & 0 deletions dev/dev-env/nix-bitcoin-firejail.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
include default.local
include globals.local

include disable-common.inc
include disable-programs.inc

caps.drop all
netfilter
noinput
nonewprivs
noroot
notv
novideo
protocol unix,inet,inet6
seccomp

## Enable features

allow-debuggers

# Enable direnv configs
whitelist ${HOME}/.config/direnv
read-only ${HOME}/.config/direnv
whitelist ${HOME}/.local/share/direnv
read-only ${HOME}/.local/share/direnv
20 changes: 20 additions & 0 deletions dev/dev-env/template-scenarios.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{ pkgs, lib, scenarios, nix-bitcoin }:
with lib;
rec {
# For more examples, see `scenarios` and `exampleScenarios` in ./src/test/tests.nix

template = { config, pkgs, lib, ... }: {
imports = [
(nix-bitcoin + "/modules/presets/secure-node.nix")
scenarios.netnsBase
scenarios.regtestBase
];
test.container.enableWAN = true;
test.container.exposeLocalhost = true;
};

myscenario = { config, pkgs, lib, ... }: {
services.clightning.enable = true;
nix-bitcoin.nodeinfo.enable = true;
};
}
Loading

0 comments on commit b4d7e1a

Please sign in to comment.