Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Nix flake #9023

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Add a Nix flake #9023

wants to merge 4 commits into from

Conversation

sellout
Copy link

@sellout sellout commented Nov 14, 2024

Motivation

I manage all of my systems with Nix, so this grew out of me doing various work around Zebra the past few months. I currently merge this branch into whatever I’m working on (which is easy, because this basically only adds new files1, so no conflicts).

I also saw @teor2345 had previously put up a Nix derivation in #1479, which roughly corresponds to nix/packages/zebra in this PR.

Solution

Here is a summary of what’s added. ${system} can be replaced with any of aarch64-darwin, aarch64-linux, x86_64-darwin, x86_64-linux.

├───apps
│   └───${system}
│       ├───default: app
│       ├───zebra-scanner: app
│       └───zebrad: app
├───checks
│   └───${system}
│       ├───audit: derivation 'crate-audit-0.0.0'
│       ├───clippy: derivation 'zebra-clippy-2.0.1'
│       ├───deny: derivation 'zebra-deny-2.0.1'
│       ├───doc: derivation 'zebra-doc-2.0.1'
│       └───fmt: derivation 'zebra-fmt-2.0.1'
├───darwinConfigurations
│   ├───aarch64-darwin-example: nix-darwin configuration
│   └───x86_64-darwin-example: nix-darwin configuration
├───darwinModules
│   ├───default: nix-darwin module
│   └───zebra: nix-darwin module
├───devShells
│   └───${system}
│       └───default: development environment 'nix-shell'
├───formatter
│   └───${system}: package 'alejandra-3.0.0'
├───homeConfigurations: unknown
│   └───${system}-example: Home Manager configuration
├───homeModules
│   ├───default: Home Manager module
│   └───zebra: Home Manager module
├───nixosConfigurations
│   ├───aarch64-linux-example: NixOS configuration
│   └───x86_64-linux-example: NixOS configuration
├───nixosModules
│   ├───default: NixOS module
│   └───zebra: NixOS module
├───overlays
│   └───default: Nixpkgs overlay
└───packages
    └───${system}
        ├───default: package 'zebra-2.0.1'
        ├───zebra: package 'zebra-2.0.1'
        └───zebra-deps: package 'zebra-deps-2.0.1'
  • packages are builds of the main content of this repo
  • checks are various tests (other than cargo test, which is covered by packages)
  • *Modules allow you to configure zebrad like this
  • *Configurations are examples of those configurations that are built as tests of much of the flake
  • devShells provide a sandboxed development environment with rustc, cargo, etc.

Tests

Everything is built on aarch64-darwin, aarch64-linux, and x86_64-linux at garnix, which also runs the various checks (clippy, fmt, etc.), and it builds the example configurations which implicitly tests the overlays, modules, etc.

For these CI builds to run on not-my-fork, the ZcashFoundation org would need to get a garnix account, or would need to add some Nix-based GitHub workflow (ideally with some caching solution, which garnix handles automatically).

Follow-up Work

The current solution has everything in there, but I think the Nix/Rust tooling could be improved wrt cache-friendliness. It currently uses crane, which condenses everything into only two packages (“zebra”, containing all the crates in this repo, and “zebra-deps”, containing all the dependency crates not in this repo), so if any part of Zebra changes, all of Zebra gets rebuilt, and if a dependency changes, all of Zebra and all deps get rebuilt. Having a separate package for each crate would minimize rebuilds, so a solution like cargo2nix or crate2nix is probably the way to go longer-term2.

The derivation is built with ZEBRA_SKIP_NETWORK_TESTS, because of Nix sandboxing3. But even so, there are a number of failing tests that I’ve explicitly skipped. That file conditionalizes them so you can see in which contexts they fail. One thing I didn’t conditionally enable is tests that pass outside of a sandbox, because I think that makes the dev / CI divide confusing. E.g., a number of disabled tests can pass if __darwinAllowLocalNetworking is enabled, but that can only be done outside of a sandbox. Also interesting is that there are a number of tests that only fail when the elasticsearch feature is enabled (and only on MacOS).

This PR doesn’t provide a default.nix or shell.nix (#1479 did, just under a different name), because I do everything with flakes, but it’s easy enough to expose them with flake-compat if that’s desired.

PR Author's Checklist

  • The PR name will make sense to users.
  • The PR provides a CHANGELOG summary.
  • The solution is tested.
  • The documentation is up to date.
  • The PR has a priority label.

PR Reviewer's Checklist

  • The PR Author's checklist is complete.
  • The PR resolves the issue.

Footnotes

  1. There are three minor changes to existing files:

    1. ignored the Nix build result in .gitignore,
    2. fixed a clippy complaint in disk_db.rs, and
    3. removed an invalid Alias from systemd/zebrad.service.
  2. They’re not being used yet because of a bug in Nix ([OS X] Derivation fails with sandbox NixOS/nix#4119) that prevents packages with a lot of dependencies from building in a sandbox on MacOS (which would cause failures on garnix CI, as it requires everything to be sandboxed).

  3. There are ways to enable network access in a sandbox, so that might allow all (or at least more) tests to be enabled.

This adds a fairly rich Nix environment. It provides a shell that includes rustfmt and
rust-analyzer, and a Home Manager module for configuring & running Zebra via Nix.
Simple CI for Nix
@sellout sellout requested a review from a team as a code owner November 14, 2024 19:06
@sellout sellout requested review from arya2 and removed request for a team November 14, 2024 19:06
@github-actions github-actions bot added the C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG label Nov 14, 2024
@gustavovalverde gustavovalverde added A-devops Area: Pipelines, CI/CD and Dockerfiles C-feature Category: New features A-compatibility Area: Compatibility with other nodes or wallets, or standard rules P-Optional ✨ extra-reviews This PR needs at least 2 reviews to merge and removed C-trivial Category: A trivial change that is not worth mentioning in the CHANGELOG labels Nov 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-compatibility Area: Compatibility with other nodes or wallets, or standard rules A-devops Area: Pipelines, CI/CD and Dockerfiles C-feature Category: New features extra-reviews This PR needs at least 2 reviews to merge P-Optional ✨
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants