2

I'm trying to install external binary inside NixOS, using declarative ways. Inside nix-pkg manual, I found such way of getting external binary inside NixOS

{ pkgs ? import <nixpkgs> {} }:
pkgs.stdenv.mkDerivation {
  name = "goss";
  src = pkgs.fetchurl {
    url = "https://github.com/aelsabbahy/goss/releases/download/v0.3.13/goss-linux-amd64";
    sha256 = "1q0kfdbifffszikcl0warzmqvsbx4bg19l9a3vv6yww2jvzj4dgb";
  };
  phases = ["installPhase"];             
  installPhase = ''
  
  '';

But I'm wondering, what should I add inside InstallPhase, to make this binary being installed inside the system?

dragonhaze
  • 189
  • 1
  • 8

2 Answers2

2

This seems to be an open source Go application, so it's preferable to use Nixpkgs' Go support instead, which may be more straightforward than patching a binary.

That said, installPhase is responsible creating the $out path; typically mkdir -p $out/bin followed by cp, make install or similar commands.

So that's not actually installing it into the system; after all Nix derivations are not supposed to have side effects. "Installing" it into the system is the responsibility of NixOS's derivations, as configured by you.

You could say that 'installation' is the combination of modifying the NixOS configuration + switching to the new NixOS. I tend to think about the modification to the configuration only; the build and switch feel like implementation details, even though nixos-rebuild is usually a manual operation.

Example:

installPhase = ''
  install -D $src $out/bin/goss
  chmod a+x $out/bin/goss
'';

Normally chmod would be done to a local file by the build phase, but we don't really need that phase here.

Robert Hensing
  • 6,708
  • 18
  • 23
  • This hasn't actually answered the question of how to expose a single downloaded file within a Nix derivation. It's just mentioning an alternative approach and then talking about how Nix works in general. — Why is the simplest possible way of acquiring a resource, literally just downloading a single flipping file with no unpacking or compilation, so difficult on Nix? – Will Chen Jan 15 '23 at 05:36
  • If you're really looking for an answer and not just complaining, it's because downloading a file could add entropy to your build, which is not what you want. Nix effectively blocks this source of entropy by checking a hash. Any operations performed on the file are best done in a separate derivation because that way you can change those operations. Instead of moving it into `$out/bin`, you could flip it, as you suggest, without having to update the hash. Another reason is that the hash is a cached content address, and if you don't update it after changing the recipe, the result will be stale. – Robert Hensing Jan 19 '23 at 18:14
  • How is downloading a single file from a specific Git commit (or tagged release) any different from downloading a tarball of a Git repository at that commit (or tagged release)? AFAICT The only difference is how the repository owner has chosen to package it; It should be no less reproducible. That said, `$src` does make it easy enough; I just had a hard time finding it because in a couple hours of looking through pages on the fetchers I only encountered one blog post that showed its use and then only tangentially. I agree about making it a separate derivation; That is indeed what I wanted. – Will Chen Jan 19 '23 at 21:25
1

I have no idea why this was so hard to figure out. Having robust configuration systems is fine, but at the end of the day sometimes you just need to be able to download and expose a single flipping file on the $PATH.

The result of fetchurl is "the unaltered contents of the URL within the Nix store", which is being used for the src. So in installPhase, $src points to the downloaded data, and you just have to copy/install/link that into $out/…..

pkgs.stdenv.mkDerivation {
    name = "hello_static";

    src = pkgs.fetchurl {
        name = "hello_static";
        url = "https://raw.githubusercontent.com/ruanyf/simple-bash-scripts/6e837f949010e0f5e9305e629da946de12cc63e8/scripts/hello-world.sh";
        sha256 = "sha256:somE27ajbm0TtWv9tyeqTWDW3gbIs6xvlcFS9QS1ZJ0=";
    };

    phases = [ "installPhase" ];

    installPhase = ''
        install -D $src $out/bin/hello_static
    '';
};
Will Chen
  • 482
  • 4
  • 12