Git Product home page Git Product logo

nix-fast-build's Introduction

nix-fast-build ๐Ÿš€ (previously known as nix-ci-build)

Combine the power of nix-eval-jobs with nix-output-monitor to speed-up your evaluation and building process. nix-fast-build an also integrates with remote machines by uploading the current flake, performing the evaluation/build remotely, and then transferring the resultant store paths back to you.

Why nix-fast-build?

Problem: Evaluating and building big flakes i.e. with numerous NixOS machines can be painfully slow. For instance, rebuilding the already-compiled disko integration test suite demands 1:50 minutes on an AMD Ryzen 9 7950X3D. But, it only takes a 10 seconds with nix-fast-build.

Solution: nix-fast-build makes builds faster by evaluating and building your nix packages concurrently, reducing the overall time.

How Does It Work?

Under the hood:

  1. It leverages the output from nix-eval-jobs to evaluate flake attributes in parallel.
  2. As soon as attributes complete evaluation, nix-fast-build initiates their build, even if the overall evaluation is ongoing.
  3. Lastly, nix-output-monitor to show the build progress nicely.
  4. (Optional) Once a build finishes, nix-fast-build can initiate its upload to a designated remote binary cache.

Usage

To get started, run:

$ nix-fast-build

or:

$ nix run github:Mic92/nix-fast-build

This command will concurrently evaluate all systems in .#checks and build the attributes in .#checks.$currentSystem.


Enjoy faster and more efficient NixOS builds with nix-fast-build!

Remote building

When leveraging the remote-builder protocol, uploading pre-built paths or sources from the local machine can often turn into a bottleneck. nix-fast-build does not use the remote-builder protocol. Instead it uploads only the flake and executes all evaluation/build operations on the remote end. At the end nix-fast-build will download the finished builds to the local machine while not having to download all build dependencies in between.

Here is how to use it:

nix run github:Mic92/nix-fast-build -- --remote youruser@yoursshhostname

Replace youruser@yoursshhostname with your SSH login credentials for the target machine. Please note that as of now, you must be recognized as a trusted user on the remote endpoint to access this feature.

CI-Friendly Output

By default, Nix-output-monitor (abbreviated as nom) updates its output every 0.5 seconds. In standard terminal environments, this frequent update is unnoticeable, as nom erases the previous output before displaying the new one. However, in Continuous Integration (CI) systems, each update appears as a separate line of output.

To make output more concise for CI environments, use the --no-nom flag. This replaces nom with a streamlined status reporter, which updates only when there's a change in the number of pending builds, uploads, or downloads.

Avoiding Redundant Package Downloads

By default, nix build will download pre-built packages, leading to needless downloads even when there are no changes to any package. This can be especially burdensome for CI environments without a persistent Nix store, such as GitHub Actions.

To optimize this, use the --skip-cached flag with nix-fast-build. This ensures that only those packages missing from the binary caches will be built.

Specifying Build Systems

By default, nix-fast-build evaluates all architectures but only initiates builds for the current system. You can modify this behavior with the --systems flag. For instance, using --systems "aarch64-linux x86_64-linux" will prompt builds for both aarch64-linux and x86_64-linux architectures. Ensure that your system is capable of building for the specified architectures, either locally or through the remote builder protocol.

Building different flake attributes

nix-fast-build by default builds .#checks.$currentSystem, which refers to all checks for the current flake. You can modify this default behavior by using the --flake flag to specify a different attribute path.

Example:

$ nix run github:Mic92/nix-fast-build -- --flake github:NixOS/nixpkgs#legacyPackages.x86_64-linux.hello

Note: Always provide the complete flake path. Unlike nix build, nix-fast-build does not iterate over different attributes; the full path must be explicitly stated.

Only evaluate the current system

By default nix-fast-build will evaluate all systems in .#checks, you can limit it to the current system by using this command:

$ nix run github:Mic92/nix-fast-build -- --skip-cached --no-nom --flake ".#checks.$(nix eval --raw --impure --expr builtins.currentSystem)"

Reference

usage: nix-fast-build [-h] [-f FLAKE] [-j MAX_JOBS] [--option name value] [--remote-ssh-option name value] [--no-nom]
                      [--systems SYSTEMS] [--retries RETRIES] [--no-link] [--out-link OUT_LINK] [--remote REMOTE]
                      [--always-upload-source] [--no-download] [--skip-cached] [--copy-to COPY_TO] [--debug]
                      [--eval-max-memory-size EVAL_MAX_MEMORY_SIZE] [--eval-workers EVAL_WORKERS]

options:
  -h, --help            show this help message and exit
  -f FLAKE, --flake FLAKE
                        Flake url to evaluate/build (default: .#checks
  -j MAX_JOBS, --max-jobs MAX_JOBS
                        Maximum number of build jobs to run in parallel (0 for unlimited)
  --option name value   Nix option to set
  --remote-ssh-option name value
                        ssh option when accessing remote
  --no-nom              Don't use nix-output-monitor to print build output (default: false)
  --systems SYSTEMS     Space-separated list of systems to build for (default: current system)
  --retries RETRIES     Number of times to retry failed builds
  --no-link             Do not create an out-link for builds (default: false)
  --out-link OUT_LINK   Name of the out-link for builds (default: result)
  --remote REMOTE       Remote machine to build on
  --always-upload-source
                        Always upload sources to remote machine. This is needed if the remote machine cannot access all sources
                        (default: false)
  --no-download         Do not download build results from remote machine
  --skip-cached         Skip builds that are already present in the binary cache (default: false)
  --copy-to COPY_TO     Copy build results to the given path (passed to nix copy, i.e. file:///tmp/cache?compression=none)
  --debug               debug logging output
  --eval-max-memory-size EVAL_MAX_MEMORY_SIZE
                        Maximum memory size for nix-eval-jobs (in MiB) per worker. After the limit is reached, the worker is restarted.
  --eval-workers EVAL_WORKERS
                        Number of evaluation threads spawned

nix-fast-build's People

Contributors

andir avatar flokli avatar mergify[bot] avatar mic92 avatar mic92-renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

nix-fast-build's Issues

nix-fast-build depends on "nixpkgs" in the flake registry

I tried to build my nixfiles repo using nix-fast-build and got the following:

$ nix run github:Mic92/nix-fast-build
INFO:nix_fast_build:run nix-eval-jobs --gc-roots-dir /tmp/tmp213llfvo --force-recurse --max-memory-size 4096 --workers 8 --flake '.#checks'
warning: unknown setting 'allowed-users'
warning: unknown setting 'trusted-users'
error: cannot find flake 'flake:nixpkgs' in the flake registries
  building x86_64-linux.lint/nixpkgs-fmt
  building x86_64-linux.lint/deadnix
  building x86_64-linux.lint/statix
  building x86_64-linux.lint/gitleaks
  building x86_64-linux.lint/editorconfig-checker
  building x86_64-linux.lint/tofu-fmt
/nix/store/x8cz3lv4nn3yqnipw1fbsbql0mcp4pij-lint.gitleaks
/nix/store/5yjz8ilhs0azg6axv4w725k6m8jhc61p-lint.editorconfig-checker
/nix/store/0ak8ssa3ddzq4xs5fmziwwkddq7p7ll2-lint.tofu-fmt
/nix/store/xjs2xajl9m4hlkw4hqp0xn4a4dnrnp79-lint.statix
/nix/store/10wfqg315wjqzwywnbs7ispnbmj9mv9s-lint.nixpkgs-fmt
/nix/store/f7gzlqvv6bw47kmk9qj54y9yiylagzp5-lint.deadnix
ERROR:nix_fast_build:nix-output-monitor exited with 1

The error seems weird. I do indeed not have nixpkgs in my flake registry (I instead have a pinned version of nixpkgs under a different name). I think this error is coming from here:

cmd = maybe_remote([*nix_shell(["nixpkgs#nix-output-monitor"]), "nom"], opts)

Since nixpkgs in the flake registry is, by default, not pinned to any version I think nix-fast-build should not try to use anything from there and instead use the nix-output-monitor that is already in its closure.

Is this a bug or am I missing some reason for this?

call nix-build with --out-link to preserve result links

Hi,

I'm using cachix, and I've been blindly doing ls result* | cachix push {cache} and just now realizing that the way nix-fast-build works seems to be clobbering result as it goes.

So, I've been getting lucky that my slowest host to build often includes most things.

It would be nice if I can easily access the things built by nix-fast-build after the fact. Maybe if it took the attr name from the eval and then passed it as --out-link to nix-build ?

Why not use the system Nix?

I'm just curious why the derivation picks up Nix from nixpkgs here:

path = lib.makeBinPath [ nix nix-eval-jobs nix-output-monitor ];

As opposed to just relying on the nix from $PATH.

It means that every time you want to run nix-fast-build, even if you already have Nix installed, you always need to fetch the entire nix closure from cache, or build it if it was overlayed/uncached.

Is there a strong dependency on the specific version of Nix the tool uses? I was thinking of overriding the build on my end to remove that bit.

Package propagates Python interpreter to shell

If you construct a simple flake like this:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nix-fast-build.url = "github:Mic92/nix-fast-build";
    nix-fast-build.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { self, nixpkgs, nix-fast-build }: 
    let
      forAllSystems = nixpkgs.lib.genAttrs [
        "aarch64-darwin"
        "aarch64-linux"
        "x86_64-darwin"
        "x86_64-linux"
      ];
    in
  {
    devShells = forAllSystems (localSystem:
      let
        pkgs = import nixpkgs { inherit localSystem; };
      in
      {
        default = pkgs.mkShell {
          nativeBuildInputs = [
            nix-fast-build.packages.${localSystem}.nix-fast-build
          ];
        };
      }
    );
  };
}

You end up with python3 in your shell, which is unexpected:

$ which -a python3
/usr/bin/python3

$ nix develop --command which -a python3
/nix/store/rycxjkclx801wrhwrgllak0302xzjdvx-python3-3.11.4/bin/python3
/usr/bin/python3

This doesn't happen with other Python packages, for example:

$ nix-shell -p pre-commit --run "which -a python3"
/usr/bin/python3

`post-build-hook: warning: unknown experimental feature 'fetch-tree'` and random CI failures

After switching to nix-fast-build I've noticed much more unexplainable CI failures. Oftentimes they look like random network issues, but recently I've spotted some really odd ones.

From our CI:

post-build-hook: warning: unknown experimental feature 'fetch-tree'
running post-build-hook '/home/runner/work/_temp/cachix-daemon-KNU4uw/post-build-hook.sh'...
post-build-hook: warning: unknown experimental feature 'fetch-tree'
copying path '/nix/store/vbh4481bzdv7pnqq8m3d0jwz27c0qx0x-clang-wrapper-16.0.6' from 'https://cache.nixos.org/'...
building '/nix/store/pg3ilwm16il5b1cbr4dx4cv0a2fmvjr9-llvm-config.drv'...
running post-build-hook '/home/runner/work/_temp/cachix-daemon-KNU4uw/post-build-hook.sh'...
post-build-hook: warning: unknown experimental feature 'fetch-tree'

It's unclear to me what could be causing it. cachix-action? nix-fast-build?

Result symlinks override each other

When building an attributeset of derivations the result links are not stored individually. One randomly wins over the others. it would be good to either number them (result-1, result-2, ..) or have them follow the attribute names that are being built (result-a, result-foo, ..).

currently hides eval failures

I have a CI job setup to auto-update-rebase my nixpkgs/home-manager forks, update my other flake inputs, and build. I haven't received any job failures recently.

Turns out, I had nixos-hardware set to an old fork and got bit by the rocm packages change. However, my CI jobs are all still green.

It seems that nix-fast-build did spit out an error, but must have exitted 0 at the end, since the script kept going and GHA didn't complain.

Is it possible to change this behavior, either by default or with a flag?

doc feat: document how --remote works

Hi,

It's looking like this could drastically reduce my current "wrapper" script of sorts, but one of the things my wrapper does is do local evaluations, push the derivations to a remote, and then SSHs and does the build+cachix call on the remote machine.

This avoids the issue (that I think is still an issue?) of Nix's behavior of building/pulling derivations one at a time to/from a remote.

Does nix-fast-build do this too? Or is it using the built-in remote builder functionality of nix?

remote building and propagation of substituters/trusted-public-keys?

I'm looking at removing almost all of my "nix wrapper" script in favor of nix-fast-build.

One other thing that my wrapper script does is re-specify substituters and trusted-public-keys and ensure that the remote build is performed with them.

  1. Does nix-fast-build do this? (If so, I can send a PR noting it in the README in the remote builder section)
  2. If not, does it make sense to add such a feature?
  3. (I wonder if nix has or should have a feature to print the net of global and user nix conf and use that?)

opening lock file permission denied error

This tool works great for me in ci, but when running locally, I get the following error:

 error: opening lock file '/nix/store/ca0cw8qskng78k96g99ihmh3mmir4gzl-source.lock': Permission denied
error:

Not sure where to start debug this. I can give more details on my env if needed.

Don't evaluate other systems (option?)

After I "fixed" my flake to make sure there are no evaluations that wouldn't be possible to build on supported system I still get:

> nix run github:Mic92/nix-fast-build -- --skip-cached --no-nom --systems "x86_64-linux"

              (stack trace truncated; use '--show-trace' to show the full trace)

              error: a 'x86_64-darwin' with features {} is required to build '/nix/store/09par5vs5qdw9ylw0ckf6wg3xi94gdg1-android-googletv-license.drv', but I am a 'x86_64-linux' with features {be
nchmark, big-parallel, kvm, nixos-test}

which suggest, that even on x86_64-linux, there are some reachable things somewhere that actually don't compile on it? Possibly they are coming from nixpkgs-android which is an intput I don't control.

I don't really hit these issues with nix flake check or nix build, and it's unclear to me is some problem of my flake,nixpkgs-android or how nix-fast-build does things.

One way or another, I'd rather disable evaluation of other systems and move on.

Skipping non-native derivations even when supported by extra-platforms

      run: >
          nix run github:Mic92/nix-fast-build
          -- --skip-cached --no-nom
          --flake
          ".#checks.aarch64-linux"

https://github.com/SomeoneSerge/llama.cpp/blob/998c9b2cf6c77f365b50b6645b41ff81eaedd450/.github/workflows/nix-ci.yml#L102-L106

...run on an x86_64-linux (ubuntu-latest) host, configured with extra-platforms = aarch64-linux

...results in the successful exit but 0 actual builds happening. The same command works fine if nix.conf instead contains system = aarch64-linux and extra-platforms: x86_64-linux

Encountered in ggerganov/llama.cpp#4709

CI features: layered integration with nix-eval-jobs, support for gcrooting the outputs

Hi,

In addition to the hack I did for #35, I want to be able to make gcroots for the drvPaths, as nix-eval-jobs support. This is for CI on a self-hosted GHA runner box that is quickly filling up with disk space. I'd like to turn on auto garbage collection, but also want to be able to stash some gcroots for drvPaths and outPaths.

This leads to a thought of adding more fast to nix-fast-build to passthrough to nix-eval-jobs. But it seems it might be more elegant to have a mode where the user can pipe nix-eval-jobs themselves into nix-fast-build, so they can find tune eval/build parameters separately, as they see fit.

Any thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.