Is specifying nixpkgs necessary to build sd-image?

currently I am using such a script to build an sd image using a nixpkgs version pinned in sources.json is there something i can simplify about this?

sources="$(pwd)/sources.json"
nixpkgs=$(nix-instantiate --eval --expr "(builtins.fetchTarball (builtins.fromJSON (builtins.readFile $sources)).nixpkgs)"| tr -d \")
nix-build '<nixpkgs/nixos>' -A config.system.build.sdImage --argstr system aarch64-linux -I nixos-config=./sd-image.nix -I nixpkgs=$nixpkgs

You can inline the variable. But I am not sure whether that counts as “simplification” though.

What would definitely help reading the snippet are line breaks in the final invocation.

Of course you can remove the -I nixpkgs=..., but that would resolve through system state and not use the pin anymore.

If you’re comfortable using flakes and changing your sources file, you can simplify it to one command

nix-build '<nixpkgs/nixos>' -A config.system.build.sdImage --argstr system aarch64-linux -I nixos-config=./sd-image.nix -I nixpkgs=flake:$(<./nixpkgs-ref)

You could also use a default.nix file and call nixos from that file, e.g.

{
  nixpkgs ? builtins.fetchTarball (builtins.fromJSON (builtins.readFile ./sources.json)).nixpkgs,
  system ? builtins.currentSystem
}:

import "${nixpkgs}/nixos" {
  configuration = ./sd-image.nix;
  inherit system;
}

This would mean that you would only have to run

nix-build --argstr system aarch64-linux -A config.system.build.sdImage

Once you have a nix file that yields a nixos configuration, like in this example, you can also use nixos-rebuild build-image. e.g.

nixos-rebuild build-image --image-variant sd-card -f nixos.nix in this case. The sd-image module import is implied here. So a minimal nixos.nix here could be just

{ pkgs, ...}:
  pkgs.nixosSystem {
    # whatever nixos options you need
  }

Everything else is handled by defaults, including the target system and nixpkgs commit. The latter defaults to your nix path - so you can just prepend NIX_PATH="nixpkgs=$path-to-nixpkgs" to pin it, if desired (there’s also various other ways, build-image supports the --flake, --file and --attr flags of nixos-rebuild)

2 Likes

At that point, why not make it into a package output, that you can nix build?

1 Like

how would one do that?

...
(import "${nixpkgs}/nixos"
  {
    inherit configuration system;
  }).config.system.build.sdImage
1 Like