NixOS modules: Difference between revisions

imported>Gileri
m T'is a config, not an option
Qyriad (talk | contribs)
With Flakes: fix? typo and typesetting; idk what {{|c|nixos-rebuild}} was intended to be
 
(10 intermediate revisions by 8 users not shown)
Line 16: Line 16:
   options = {
   options = {
     # Option declarations.
     # Option declarations.
     # Declare what settings a user of this module module can set.
     # Declare what settings a user of this module can set.
     # Usually this includes an "enable" option to let a user of this module choose.
     # Usually this includes a global "enable" option which defaults to false.
   };
   };


Line 23: Line 23:
     # Option definitions.
     # Option definitions.
     # Define what other settings, services and resources should be active.
     # Define what other settings, services and resources should be active.
     # Usually these are depend on whether a user of this module chose to "enable" it
     # Usually these depend on whether a user of this module chose to "enable" it
     # using the "option" above.  
     # using the "option" above.  
     # You also set options here for modules that you imported in "imports".
     # Options for modules imported in "imports" can be set here.
   };
   };
}
}
</syntaxhighlight>
</syntaxhighlight>


There is a shorthand for modules without any declarations:
There is a shorthand for modules without any option declarations:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
Line 47: Line 47:
</syntaxhighlight>
</syntaxhighlight>


Beginners often confuse the modules attribute <code>imports = [./module.nix]</code> here with the Nix [https://nixos.org/manual/nix/stable/language/builtins.html#builtins-import builtins] function <code>import module.nix</code>. The first expects a path to a file containing a NixOS module (having the same specific structure we're describing here), while the second loads whatever Nix expression is in that file (no expected structure). See [https://discourse.nixos.org/t/import-list-in-configuration-nix-vs-import-function/11372/8 this post].
Note that despite the name, <code>imports = [./module.nix]</code> should not be confused with the Nix [https://nixos.org/manual/nix/stable/language/builtins.html#builtins-import builtins] function <code>import module.nix</code>.
 
<code>imports</code> expects a path to a file containing a NixOS module structured as described here. <code>import</code> can load arbitrary Nix expression from provided file with no expectation of structure. (no expected structure). See [https://discourse.nixos.org/t/import-list-in-configuration-nix-vs-import-function/11372/8 this post] for more details.


Note: <code>imports</code> provides the same behavior as the obsolete <code>require</code>. There is no reason to use <code>require</code> anymore, however it may still linger in some legacy code.
Note: <code>imports</code> provides the same behavior as the obsolete <code>require</code>. There is no reason to use <code>require</code> anymore, however it may still linger in some legacy code.
Line 53: Line 55:
=== Function ===
=== Function ===


A module can be turned into a function accepting an attribute set.
A module may be a function accepting an attribute set.


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
Line 63: Line 65:
</syntaxhighlight>
</syntaxhighlight>


It may require the attribute set to contain:
Following arguments are available in NixOS modules by default:


<dl>
<dl>
Line 72: Line 74:
<dt><code>options</code></dt>
<dt><code>options</code></dt>
<dd>All option declarations refined with all definition and declaration references.</dd>
<dd>All option declarations refined with all definition and declaration references.</dd>
<dt><code>lib</code></dt>
<dd>An instance of the nixpkgs "standard library", providing what usually is in <code>pkgs.lib</code>.</dd>


<dt><code>pkgs</code></dt>
<dt><code>pkgs</code></dt>
Line 79: Line 84:
<dd>The location of the <code>module</code> directory of NixOS.</dd>
<dd>The location of the <code>module</code> directory of NixOS.</dd>


</dl>
</dl>The "<code>...</code>"  part of the argument attribute set indicates that this module does not depend on the rest of the arguments. When the module is defined as a function, this pattern is typically required, otherwise the evaluation will fail citing unexpected arguments.
 
==== Passing custom values to modules ====
The [[NixOS:config_argument|<code>config</code>]], <code>options</code>, <code>lib</code>, <code>pkgs</code>, and <code>modulesPath</code> arguments are passed automatically to modules, when the module is imported.
 
For example, in the following Nix flake, the `./configuration.nix` file will be provided with the default set of arguments listed above, plus `extraArg`, which was set in the `specialArgs` argument to the `nixosGenerate` function.<syntaxhighlight lang="nix">
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
    nixos-generators = {
      url = "github:nix-community/nixos-generators";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    xc = {
      url = "github:joerdav/xc";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
 
  outputs = { nixpkgs, nixos-generators, xc, ... }:
    let
      pkgsForSystem = system: import nixpkgs {
        inherit system;
        overlays = [
          (final: prev: { xc = xc.packages.${system}.xc; })
        ];
      };
      allVMs = [ "x86_64-linux" "aarch64-linux" ];
      forAllVMs = f: nixpkgs.lib.genAttrs allVMs (system: f {
        inherit system;
        pkgs = pkgsForSystem system;
      });
    in
    {
      packages = forAllVMs ({ system, pkgs }: {
        vm = nixos-generators.nixosGenerate {
          system = system;
          specialArgs = {
            extraArg = "foobar";
          };
          modules = [
            ./configuration.nix
          ];
          format = "raw";
        };
      });
    };
}
</syntaxhighlight>


==== modulesPath ====
==== modulesPath ====
Line 127: Line 180:
</syntaxhighlight>
</syntaxhighlight>


They are created with {{ic|mkOption}}, a function accepting a set with following attributes:<ref>{{Nixpkgs Link|lib/options.nix#L51-L84}}</ref><ref>{{manual:nixos|sec=#sec-option-declarations|chapter=42.1. Option Declarations}}</ref>
They are created with {{ic|mkOption}}, a function accepting a set with following attributes:<ref>{{Nixpkgs Link|lib/options.nix#L66-L88}}</ref><ref>{{manual:nixos|sec=#sec-option-declarations|chapter=42.1. Option Declarations}}</ref>


<dl>
<dl>
Line 307: Line 360:
The module system itself is rather complex, but here's a short overview. A module evaluation consists of a set of "modules", which can do three things:
The module system itself is rather complex, but here's a short overview. A module evaluation consists of a set of "modules", which can do three things:


* Import other modules (through imports = [ ./other-module.nix ])
* Import other modules (through <code>imports = [ ./other-module.nix ]</code>)
* Declare options (through options = { ... })
* Declare options (through <code>options = { ... }</code>)
* Define option values (through |config = { ... }, or without the config key as a shorthand if you don't have imports or options)
* Define option values (through <code>config = { ... }</code>, or without the config key as a shorthand if you don't have imports or options)


To do the actual evaluation, there's these rough steps:
To do the actual evaluation, there's these rough steps:
Line 345: Line 398:
</syntaxhighlight>
</syntaxhighlight>


If you're developing on top of master, this will potentially cause the compilation of lots of packages, since changes on master might not cached on cache.nixos.org yet. To avoid that, you can develop your module on top of the <code>nixos-unstable</code> [[Channels|channel]], tracked by the eponymous branch in https://github.com/NixOS/nixpkgs:
If you're developing on top of master, this will potentially cause the compilation of lots of packages, since changes on master might not cached on cache.nixos.org yet. To avoid that, you can develop your module on top of the <code>nixos-unstable</code> [[Channel branches|channel branch]], tracked by the eponymous branch in https://github.com/NixOS/nixpkgs:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 356: Line 409:
If you want to develop a module from a git repo, you can use `--override-input`. For example, if you have an input in your flake called {{ic|jovian}},, you can use
If you want to develop a module from a git repo, you can use `--override-input`. For example, if you have an input in your flake called {{ic|jovian}},, you can use
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
nixos-rebuild switch --override-input jovian <path-to-url>` --flake <uri>
nixos-rebuild switch --override-input jovian <path-to-url> --flake <uri>
</syntaxhighlight>
</syntaxhighlight>
Of course, it doesn't have to be {{|c|nixos-rebuild}} in particular.
Of course, it doesn't have to [[nixos-rebuild|<code>nixos-rebuild</code>]] in particular.
 
== References ==
== References ==