diff --git a/20-package-overrides/README.md b/20-package-overrides/README.md new file mode 100644 index 0000000..0428737 --- /dev/null +++ b/20-package-overrides/README.md @@ -0,0 +1,19 @@ +# 20-package-overrides + +This example shows how to customize an existing package with `overrideAttrs`. + +It includes: + +- a package built from `pkgs.hello`, +- one override that changes the installed program's behavior, and +- a check that proves the override took effect. + +Useful commands: + +```bash +nix build +./result/bin/hello + +nix run +nix flake check +``` diff --git a/20-package-overrides/flake.lock b/20-package-overrides/flake.lock new file mode 100644 index 0000000..dfdfdf9 --- /dev/null +++ b/20-package-overrides/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1776548001, + "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/20-package-overrides/flake.nix b/20-package-overrides/flake.nix new file mode 100644 index 0000000..939074e --- /dev/null +++ b/20-package-overrides/flake.nix @@ -0,0 +1,45 @@ +{ + # Customizes an existing package with `overrideAttrs` and verifies that + # the override changes the package's runtime behavior. + description = "Customize an existing package with overrideAttrs"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = + { self, nixpkgs, ... }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + + customizedHello = pkgs.hello.overrideAttrs (old: { + pname = "hello-override"; + nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ]; + postInstall = (old.postInstall or "") + '' + wrapProgram $out/bin/hello \ + --add-flags "--greeting=hello-from-overrideAttrs" + ''; + }); + in + { + packages.${system}.default = customizedHello; + + apps.${system}.default = { + type = "app"; + program = "${self.packages.${system}.default}/bin/hello"; + meta.description = "Run GNU hello with a greeting injected by overrideAttrs."; + }; + + checks.${system}.greeting = pkgs.runCommand "hello-override-check" { } '' + output="$(${self.packages.${system}.default}/bin/hello)" + + if [ "$output" = "hello-from-overrideAttrs" ]; then + echo ok > "$out" + else + echo "unexpected output: $output" >&2 + exit 1 + fi + ''; + }; +} diff --git a/21-nixos-configurations/README.md b/21-nixos-configurations/README.md new file mode 100644 index 0000000..93dfe7c --- /dev/null +++ b/21-nixos-configurations/README.md @@ -0,0 +1,17 @@ +# 21-nixos-configurations + +This example shows a small `nixosConfigurations` output. + +It includes: + +- a local module in `module.nix`, +- one full system configuration exposed as `nixosConfigurations.demo`, and +- a check that reads values from the evaluated system configuration. + +Useful commands: + +```bash +nix flake show +nix eval .#nixosConfigurations.demo.config.networking.hostName --raw +nix flake check +``` diff --git a/21-nixos-configurations/flake.lock b/21-nixos-configurations/flake.lock new file mode 100644 index 0000000..dfdfdf9 --- /dev/null +++ b/21-nixos-configurations/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1776548001, + "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/21-nixos-configurations/flake.nix b/21-nixos-configurations/flake.nix new file mode 100644 index 0000000..d128145 --- /dev/null +++ b/21-nixos-configurations/flake.nix @@ -0,0 +1,64 @@ +{ + # Defines a minimal `nixosConfigurations` output and verifies a known + # value from the evaluated system configuration. + description = "A minimal nixosConfigurations example"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = + { nixpkgs, ... }: + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + + demoSystem = nixpkgs.lib.nixosSystem { + inherit system; + modules = [ + ./module.nix + { + boot.loader.grub = { + enable = true; + device = "/dev/null"; + }; + + fileSystems."/" = { + device = "tmpfs"; + fsType = "tmpfs"; + }; + + system.stateVersion = "24.11"; + + playground = { + hostName = "demo-machine"; + motd = "hello from nixosConfigurations"; + }; + } + ]; + }; + in + { + nixosConfigurations.demo = demoSystem; + + checks.${system}.configuration = + pkgs.runCommand "nixos-configuration-check" + { + inherit (demoSystem.config.networking) hostName; + motd = demoSystem.config.environment.etc."playground-motd".text; + } + '' + if [ "$hostName" != "demo-machine" ]; then + echo "unexpected host name: $hostName" >&2 + exit 1 + fi + + if [ "$motd" != "hello from nixosConfigurations" ]; then + echo "unexpected motd: $motd" >&2 + exit 1 + fi + + echo ok > "$out" + ''; + }; +} diff --git a/21-nixos-configurations/module.nix b/21-nixos-configurations/module.nix new file mode 100644 index 0000000..ef75a36 --- /dev/null +++ b/21-nixos-configurations/module.nix @@ -0,0 +1,24 @@ +{ config, lib, ... }: +let + cfg = config.playground; +in +{ + options.playground = { + hostName = lib.mkOption { + type = lib.types.str; + default = "playground"; + description = "The host name used by the example system configuration."; + }; + + motd = lib.mkOption { + type = lib.types.str; + default = "hello"; + description = "Text written to /etc/playground-motd."; + }; + }; + + config = { + networking.hostName = cfg.hostName; + environment.etc."playground-motd".text = cfg.motd; + }; +} diff --git a/22-fetchers-and-fixed-output/README.md b/22-fetchers-and-fixed-output/README.md new file mode 100644 index 0000000..d494eb8 --- /dev/null +++ b/22-fetchers-and-fixed-output/README.md @@ -0,0 +1,20 @@ +# 22-fetchers-and-fixed-output + +This example shows a pinned fetcher with `fetchurl`. + +It includes: + +- one upstream tarball fetched with `fetchurl`, +- a declared content hash, +- a small package that consumes the fetched file, and +- a check that verifies the tarball hash and contents. + +Useful commands: + +```bash +nix build +./result/bin/show-fetched-hello-source + +nix run +nix flake check +``` diff --git a/22-fetchers-and-fixed-output/flake.lock b/22-fetchers-and-fixed-output/flake.lock new file mode 100644 index 0000000..dfdfdf9 --- /dev/null +++ b/22-fetchers-and-fixed-output/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1776548001, + "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/22-fetchers-and-fixed-output/flake.nix b/22-fetchers-and-fixed-output/flake.nix new file mode 100644 index 0000000..7236fce --- /dev/null +++ b/22-fetchers-and-fixed-output/flake.nix @@ -0,0 +1,56 @@ +{ + # Fetches a pinned upstream archive with `fetchurl`, then consumes that + # fixed-output file from a small package and check. + description = "Fetch a pinned upstream file with fetchurl"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = + { self, nixpkgs, ... }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + + url = "mirror://gnu/hello/hello-2.12.3.tar.gz"; + archiveName = builtins.baseNameOf url; + archiveHash = "sha256-DV9gFUOC/uELEUocNOeF2LH0kgc64tOm97FHaHs2aqA="; + archiveSha256 = "0d5f60154382fee10b114a1c34e785d8b1f492073ae2d3a6f7b147687b366aa0"; + + helloSource = pkgs.fetchurl { + inherit url; + hash = archiveHash; + }; + in + { + packages.${system}.default = pkgs.writeShellApplication { + name = "show-fetched-hello-source"; + runtimeInputs = [ pkgs.gnutar ]; + text = '' + echo "archive: ${archiveName}" + echo "top-level entry: $(tar -tzf ${helloSource} | head -n 1)" + ''; + }; + + apps.${system}.default = { + type = "app"; + program = "${self.packages.${system}.default}/bin/show-fetched-hello-source"; + meta.description = "Inspect the archive fetched by a fixed-output fetchurl."; + }; + + checks.${system}.archive = pkgs.runCommand "hello-source-check" { } '' + actualHash="$(sha256sum ${helloSource} | cut -d' ' -f1)" + + if [ "$actualHash" != "${archiveSha256}" ]; then + echo "unexpected sha256: $actualHash" >&2 + exit 1 + fi + + tar -tzf ${helloSource} > entries.txt + grep -q '^hello-2.12.3/README$' entries.txt + + echo ok > "$out" + ''; + }; +} diff --git a/notes/023-package-overrides.md b/notes/023-package-overrides.md new file mode 100644 index 0000000..c7a09eb --- /dev/null +++ b/notes/023-package-overrides.md @@ -0,0 +1,46 @@ +# Package Overrides + +This note covers `20-package-overrides/`, which customizes an existing package with `overrideAttrs`. + +--- + +## 1. Why Override Instead of Rewriting + +Sometimes you want to change one part of an existing package, not replace the whole derivation. That is what package overrides are for. + +This example starts from `pkgs.hello` and changes its installed program with `overrideAttrs`. + +--- + +## 2. What `overrideAttrs` Changes + +`overrideAttrs` receives the old derivation attributes and returns an updated attrset. + +In this example, the override: + +- appends `makeWrapper` to `nativeBuildInputs`, and +- wraps `bin/hello` so the program always receives a custom `--greeting` flag. + +The package still comes from `pkgs.hello`; only one part of its install result changes. + +--- + +## 3. Why the Check Runs the Program + +The check does not inspect the derivation text. It runs the overridden program and asserts that the greeting changed. + +That keeps the example focused on visible package behavior. + +--- + +## 4. Commands to Try + +```bash +cd 20-package-overrides + +nix build +./result/bin/hello + +nix run +nix flake check +``` diff --git a/notes/024-nixos-configurations.md b/notes/024-nixos-configurations.md new file mode 100644 index 0000000..ab9369f --- /dev/null +++ b/notes/024-nixos-configurations.md @@ -0,0 +1,56 @@ +# NixOS Configurations + +This note covers `21-nixos-configurations/`, which defines a full `nixosConfigurations` output. + +--- + +## 1. Module Versus Configuration + +`04-nixos-module/` shows a reusable module. This example shows the next layer up: a full system definition built with `nixpkgs.lib.nixosSystem`. + +The local `module.nix` still matters, but now it is only one input into a named machine configuration. + +--- + +## 2. What the Flake Exposes + +The key output is: + +- `nixosConfigurations.demo` + +That is the shape other commands expect when you build, inspect, or deploy a NixOS system from a flake. + +--- + +## 3. Why the Example Sets Boot and File System Options + +Even a small NixOS configuration needs a few system-level settings to evaluate cleanly as a full configuration. + +This example sets: + +- a host name, +- a root file system, +- a boot loader device, and +- `system.stateVersion`. + +Those settings are minimal, and they keep the example focused on flake structure rather than real machine setup. + +--- + +## 4. What the Check Verifies + +The check reads values from the evaluated configuration and compares them with the expected host name and `/etc` file contents. + +That proves the configuration merges correctly without turning the example into a deployment workflow. + +--- + +## 5. Commands to Try + +```bash +cd 21-nixos-configurations + +nix flake show +nix eval .#nixosConfigurations.demo.config.networking.hostName --raw +nix flake check +``` diff --git a/notes/025-fetchers-and-fixed-output.md b/notes/025-fetchers-and-fixed-output.md new file mode 100644 index 0000000..a435066 --- /dev/null +++ b/notes/025-fetchers-and-fixed-output.md @@ -0,0 +1,56 @@ +# Fetchers and Fixed-Output Derivations + +This note covers `22-fetchers-and-fixed-output/`, which uses `fetchurl` to pin an upstream tarball by content hash. + +--- + +## 1. Why Fetchers Need a Hash + +When Nix fetches content from outside the store, it needs a declared hash so the result stays reproducible. + +That turns the fetch into a fixed-output derivation: the output is defined by the content hash, not just by the build steps. + +--- + +## 2. What This Example Pins + +The example fetches: + +- the GNU hello source archive, +- from a concrete upstream URL, and +- with a declared SHA-256 hash. + +If the upstream content changes, the hash check fails instead of silently accepting different bytes. + +--- + +## 3. Why the Example Builds a Second Package + +The fetched file by itself is not very interesting. The point is that later derivations can consume it as a normal store path. + +This example adds a small package that reads the tarball and prints its top-level entry. That keeps the fetcher visible while still showing how fetched inputs flow into downstream builds. + +--- + +## 4. What the Check Verifies + +The check: + +- computes the tarball SHA-256 with `sha256sum`, and +- asserts that the archive contains `hello-2.12.3/README`. + +That proves both the pinned bytes and the expected archive layout. + +--- + +## 5. Commands to Try + +```bash +cd 22-fetchers-and-fixed-output + +nix build +./result/bin/show-fetched-hello-source + +nix run +nix flake check +```