2023-07-04 06:18:46 +02:00
|
|
|
# Enabling NixOS with Flakes
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
## Enabling Flakes Support for NixOS {#enable-nix-flakes}
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Compared to the default configuration method currently used in NixOS, Flakes offers better
|
|
|
|
reproducibility. Its clear package structure definition inherently supports dependencies
|
|
|
|
on other Git repositories, facilitating code sharing. Therefore, this book suggests using
|
|
|
|
Flakes to manage system configurations. Currently, Flakes is still an experimental feature
|
|
|
|
and not enabled by default. We need to manually modify the `/etc/nixos/configuration.nix`
|
|
|
|
file to enable the Flakes feature and the accompanying new nix command-line tool:
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
```nix{12,16}
|
2023-06-23 14:29:12 +02:00
|
|
|
{ config, pkgs, ... }:
|
|
|
|
|
|
|
|
{
|
2024-02-14 09:00:16 +01:00
|
|
|
imports = [
|
|
|
|
# Include the results of the hardware scan.
|
|
|
|
./hardware-configuration.nix
|
|
|
|
];
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
# ......
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
# Enable the Flakes feature and the accompanying new nix command-line tool
|
2023-07-08 06:42:00 +02:00
|
|
|
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
2023-06-23 14:29:12 +02:00
|
|
|
environment.systemPackages = with pkgs; [
|
2024-02-14 09:00:16 +01:00
|
|
|
# Flakes clones its dependencies through the git command,
|
|
|
|
# so git must be installed first
|
2023-06-23 14:29:12 +02:00
|
|
|
git
|
|
|
|
vim
|
|
|
|
wget
|
|
|
|
curl
|
|
|
|
];
|
2024-02-14 09:00:16 +01:00
|
|
|
# Set the default editor to vim
|
2023-08-13 06:37:28 +02:00
|
|
|
environment.variables.EDITOR = "vim";
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
# ......
|
2023-06-23 14:29:12 +02:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
After making these changes, run `sudo nixos-rebuild switch` to apply the modifications.
|
|
|
|
Then, you can use the Flakes feature to manage your system configuration.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The new nix command-line tool also offers some convenient features. For example, you can
|
|
|
|
now use the `nix repl` command to open a nix interactive environment. If you're
|
|
|
|
interested, you can use it to review and test all the Nix syntax you've learned before.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
## Switching System Configuration to `flake.nix` {#switch-to-flake-nix}
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
After enabling the Flakes feature, the `sudo nixos-rebuild switch` command will prioritize
|
|
|
|
reading the `/etc/nixos/flake.nix` file, and if it's not found, it will attempt to use
|
|
|
|
`/etc/nixos/configuration.nix`.
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
You can start by using the official templates to learn how to write a flake. First, check
|
|
|
|
what templates are available:
|
2023-06-23 14:29:12 +02:00
|
|
|
|
|
|
|
```bash
|
|
|
|
nix flake show templates
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Among them, the `templates#full` template demonstrates all possible usage. Take a look at
|
|
|
|
its content:
|
2023-06-23 14:29:12 +02:00
|
|
|
|
|
|
|
```bash
|
|
|
|
nix flake init -t templates#full
|
|
|
|
cat flake.nix
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Referencing this template, create the file `/etc/nixos/flake.nix` and write the
|
|
|
|
configuration content. All subsequent system modifications will be taken over by Nix
|
|
|
|
Flakes. Here's an example of the content:
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-15 09:20:04 +01:00
|
|
|
```nix{16}
|
2023-06-23 14:29:12 +02:00
|
|
|
{
|
2024-02-14 09:00:16 +01:00
|
|
|
description = "A simple NixOS flake";
|
2024-02-15 09:20:04 +01:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
inputs = {
|
|
|
|
# NixOS official package source, using the nixos-23.11 branch here
|
|
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
|
|
|
};
|
2024-02-15 09:20:04 +01:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
outputs = { self, nixpkgs, ... }@inputs: {
|
|
|
|
# Please replace my-nixos with your hostname
|
|
|
|
nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem {
|
|
|
|
system = "x86_64-linux";
|
|
|
|
modules = [
|
2024-02-15 09:20:04 +01:00
|
|
|
# Import the previous configuration.nix we used,
|
|
|
|
# so the old configuration file still takes effect
|
2024-02-14 09:00:16 +01:00
|
|
|
./configuration.nix
|
|
|
|
];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Here we defined a system named `my-nixos`, with its configuration file located at
|
|
|
|
`/etc/nixos/` as `./configuration.nix`. This means we are still using the old
|
|
|
|
configuration.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Now, when you execute `sudo nixos-rebuild switch` to apply the configuration, the system
|
|
|
|
should not change at all because we have simply switched to using Nix Flakes, and the
|
|
|
|
configuration content remains consistent with before.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 11:07:01 +01:00
|
|
|
After the switch, we can manage the system through the Flakes feature.
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
Currently, our flake includes these files:
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
- `/etc/nixos/flake.nix`: The entrypoint for the flake, which is recognized and deployed
|
|
|
|
when `sudo nixos-rebuild switch` is executed.
|
|
|
|
- `/etc/nixos/flake.lock`: The automatically generated version lock file, which records
|
|
|
|
the data sources, hash values, and version numbers of all inputs in the entire flake,
|
|
|
|
ensuring system reproducibility.
|
|
|
|
- `/etc/nixos/configuration.nix`: This is our previous configuration file, which is
|
|
|
|
imported as a module in `flake.nix`. Currently, all system configurations are written in
|
|
|
|
this file.
|
|
|
|
- `/etc/nixos/hardware-configuration.nix`: This is the system hardware configuration file,
|
|
|
|
generated by NixOS, which describes the system's hardware information.
|
|
|
|
|
|
|
|
Up to this point, `/etc/nixos/flake.nix` has merely been a thin wrapper around
|
|
|
|
`/etc/nixos/configuration.nix`, offering no new functionality and introducing no
|
|
|
|
disruptive changes. In the content of the book that follows, we will gradually see the
|
|
|
|
benefits that such a wrapper brings.
|
|
|
|
|
|
|
|
> Note: The configuration management method described in this book is NOT "Everything in a
|
|
|
|
> single file". It is recommended to categorize configuration content into different nix
|
|
|
|
> files, then introduce these configuration files in the `modules` list of `flake.nix`,
|
|
|
|
> and manage them with Git.
|
2024-02-14 09:00:16 +01:00
|
|
|
>
|
2024-03-16 12:29:05 +01:00
|
|
|
> The benefits of this approach are better organization of configuration files and
|
|
|
|
> improved maintainability of the configuration. The section
|
|
|
|
> [Modularizing NixOS Configuration](./modularize-the-configuration.md) will explain in
|
|
|
|
> detail how to modularize your NixOS configuration, and
|
|
|
|
> [Other Useful Tips - Managing NixOS Configuration with Git](./other-useful-tips.md) will
|
|
|
|
> introduce several best practices for managing NixOS configuration with Git.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
## `flake.nix` Configuration Explained {#flake-nix-configuration-explained}
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Above, we created a `flake.nix` file to manage system configurations, but you might still
|
|
|
|
be unclear about its structure. Let's explain the content of this file in detail.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
### 1. Flake Inputs
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
First, let's look at the `inputs` attribute. It is an attribute set that defines all the
|
|
|
|
dependencies of this flake. These dependencies will be passed as arguments to the
|
|
|
|
`outputs` function after they are fetched:
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
```nix{2-5,7}
|
|
|
|
{
|
2023-06-23 14:29:12 +02:00
|
|
|
inputs = {
|
2024-02-14 09:00:16 +01:00
|
|
|
# NixOS official package source, using the nixos-23.11 branch here
|
|
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
|
|
|
};
|
|
|
|
|
|
|
|
outputs = { self, nixpkgs, ... }@inputs: {
|
|
|
|
# Omitting previous configurations......
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Dependencies in `inputs` has many types and definitions. It can be another flake, a
|
|
|
|
regular Git repository, or a local path. The section
|
|
|
|
[Other Usage of Flakes - Flake Inputs](../other-usage-of-flakes/inputs.md) describes
|
|
|
|
common types of dependencies and their definitions in detail.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Here we only define a dependency named `nixpkgs`, which is the most common way to
|
|
|
|
reference in a flake, i.e., `github:owner/name/reference`. The `reference` here can be a
|
|
|
|
branch name, commit-id, or tag.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
After `nixpkgs` is defined in `inputs`, you can use it in the parameters of the subsequent
|
|
|
|
`outputs` function, which is exactly what our example does.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
### 2. Flake Outputs
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Now let's look at `outputs`. It is a function that takes the dependencies from `inputs` as
|
|
|
|
its parameters, and its return value is an attribute set, which represents the build
|
|
|
|
results of the flake:
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
```nix{11-19}
|
|
|
|
{
|
|
|
|
description = "A simple NixOS flake";
|
|
|
|
|
|
|
|
inputs = {
|
|
|
|
# NixOS official package source, here using the nixos-23.11 branch
|
|
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
|
|
|
};
|
|
|
|
|
|
|
|
# The `self` parameter is special, it refers to
|
|
|
|
# the attribute set returned by the `outputs` function itself.
|
|
|
|
outputs = { self, nixpkgs, ... }@inputs: {
|
|
|
|
# The host with the hostname `my-nixos` will use this configuration
|
|
|
|
nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem {
|
|
|
|
system = "x86_64-linux";
|
|
|
|
modules = [
|
|
|
|
./configuration.nix
|
|
|
|
];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Flakes can have various purposes and can have different types of outputs. The section
|
|
|
|
[Flake Outputs](../other-usage-of-flakes/outputs.md) provides a more detailed
|
|
|
|
introduction. Here, we are only using the `nixosConfigurations` type of outputs, which is
|
|
|
|
used to configure NixOS systems.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
When we run the `sudo nixos-rebuild switch` command, it looks for the
|
|
|
|
`nixosConfigurations.my-nixos` attribute (where `my-nixos` will be the hostname of your
|
|
|
|
current system) in the attribute set returned by the `outputs` function of
|
|
|
|
`/etc/nixos/flake.nix` and uses the definition there to configure your NixOS system.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Actually, we can also customize the location of the flake and the name of the NixOS
|
|
|
|
configuration instead of using the defaults. This can be done by adding the `--flake`
|
|
|
|
parameter to the `nixos-rebuild` command. Here's an example:
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
```nix
|
|
|
|
sudo nixos-rebuild switch --flake /path/to/your/flake#your-hostname
|
|
|
|
```
|
|
|
|
|
|
|
|
A brief explanation of the `--flake /path/to/your/flake#your-hostname` parameter:
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
1. `/path/to/your/flake` is the location of the target flake. The default path is
|
|
|
|
`/etc/nixos/`.
|
|
|
|
2. `#` is a separator, and `your-hostname` is the name of the NixOS configuration.
|
|
|
|
`nixos-rebuild` will default to using the hostname of your current system as the
|
|
|
|
configuration name to look for.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
You can even directly reference a remote GitHub repository as your flake source, for
|
|
|
|
example:
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
```nix
|
|
|
|
sudo nixos-rebuild switch --flake github:owner/repo#your-hostname
|
|
|
|
```
|
|
|
|
|
|
|
|
### 3. Simple Introduction to `nixpkgs.lib.nixosSystem` Function {#simple-introduction-to-nixpkgs-lib-nixos-system}
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 05:19:54 +01:00
|
|
|
**A Flake can depend on other Flakes to utilize the features they provide.**
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
By default, a flake searches for a `flake.nix` file in the root directory of each of its
|
|
|
|
dependencies (i.e., each item in `inputs`) and lazily evaluates their `outputs` functions.
|
|
|
|
It then passes the attribute set returned by these functions as arguments to its own
|
|
|
|
`outputs` function, enabling us to use the features provided by the other flakes within
|
|
|
|
our current flake.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
More precisely, the evaluation of the `outputs` function for each dependency is lazy. This
|
|
|
|
means that a flake's `outputs` function is only evaluated when it is actually used,
|
|
|
|
thereby avoiding unnecessary calculations and improving efficiency.
|
2024-03-16 05:19:54 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The description above may be a bit confusing, so let's take a look at the process with the
|
|
|
|
`flake.nix` example used in this section. Our `flake.nix` declares the `inputs.nixpkgs`
|
|
|
|
dependency, so that [nixpkgs/flake.nix] will be evaluated when we run the
|
|
|
|
`sudo nixos-rebuild switch` command.
|
2024-03-16 05:19:54 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
From the source code of the Nixpkgs repository, we can see that its flake outputs
|
|
|
|
definition includes the `lib` attribute, and in our example, we use the `lib` attribute's
|
|
|
|
`nixosSystem` function to configure our NixOS system:
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
```nix{8-13}
|
|
|
|
{
|
|
|
|
inputs = {
|
|
|
|
# NixOS official package source, here using the nixos-23.11 branch
|
2023-12-05 03:51:12 +01:00
|
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
2023-06-23 14:29:12 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
outputs = { self, nixpkgs, ... }@inputs: {
|
2024-02-14 09:00:16 +01:00
|
|
|
nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem {
|
|
|
|
system = "x86_64-linux";
|
|
|
|
modules = [
|
|
|
|
./configuration.nix
|
|
|
|
];
|
2023-06-23 14:29:12 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The attribute set following `nixpkgs.lib.nixosSystem` is the function's parameter. We have
|
|
|
|
only set two parameters here:
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
1. `system`: This is straightforward, it's the system architecture parameter.
|
2024-03-16 12:29:05 +01:00
|
|
|
2. `modules`: This is a list of modules, where the actual NixOS system configuration is
|
|
|
|
defined. The `/etc/nixos/configuration.nix` configuration file itself is a Nixpkgs
|
|
|
|
Module, so it can be directly added to the `modules` list for use.
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Understanding these basics is sufficient for beginners. Exploring the
|
|
|
|
`nixpkgs.lib.nixosSystem` function in detail requires a grasp of the Nixpkgs module
|
|
|
|
system. Readers who have completed the
|
|
|
|
[Modularizing NixOS Configuration](./modularize-the-configuration.md) section can return
|
|
|
|
to [nixpkgs/flake.nix] to find the definition of `nixpkgs.lib.nixosSystem`, trace its
|
|
|
|
source code, and study its implementation.
|
2023-10-04 09:00:55 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
## Nixpkgs Module Structure Explained {#simple-introduction-to-nixpkgs-module-structure}
|
2023-10-04 09:00:55 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
> The detailed workings of this module system will be introduced in the following
|
|
|
|
> [Modularizing NixOS Configuration](./modularize-the-configuration.md) section. Here,
|
|
|
|
> we'll just cover some basic knowledge.
|
2023-10-04 09:00:55 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
You might be wondering why the `/etc/nixos/configuration.nix` configuration file adheres
|
|
|
|
to the Nixpkgs Module definition and can be referenced directly within the `flake.nix`.
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
This is because the Nixpkgs repository contains a significant amount of NixOS
|
|
|
|
implementation source code, primarily written in Nix. To manage and maintain such a large
|
|
|
|
volume of Nix code and to allow users to customize various functions of their NixOS
|
|
|
|
systems, a modular system for Nix code is essential.
|
2024-01-11 03:13:31 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
This modular system for Nix code is also implemented within the Nixpkgs repository and is
|
|
|
|
primarily used for modularizing NixOS system configurations. However, it is also widely
|
|
|
|
used in other contexts, such as nix-darwin and home-manager. Since NixOS is built on this
|
|
|
|
modular system, it is only natural that its configuration files, including
|
|
|
|
`/etc/nixos/configuration.nix`, are Nixpkgs Modules.
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Before delving into the subsequent content, it's essential to have a basic understanding
|
|
|
|
of how this module system operates.
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
Here's a simplified structure of a Nixpkgs Module:
|
|
|
|
|
|
|
|
```nix
|
|
|
|
{lib, config, options, pkgs, ...}:
|
2023-06-23 14:29:12 +02:00
|
|
|
{
|
2024-02-14 09:00:16 +01:00
|
|
|
# Importing other Modules
|
|
|
|
imports = [
|
|
|
|
# ...
|
|
|
|
./xxx.nix
|
|
|
|
];
|
|
|
|
for.bar.enable = true;
|
|
|
|
# Other option declarations
|
|
|
|
# ...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The definition is actually a Nix function, and it has five **automatically generated,
|
|
|
|
automatically injected, and declaration-free parameters** provided by the module system:
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
1. `lib`: A built-in function library included with nixpkgs, offering many practical
|
|
|
|
functions for operating Nix expressions.
|
2024-02-14 09:00:16 +01:00
|
|
|
- For more information, see <https://nixos.org/manual/nixpkgs/stable/#id-1.4>.
|
2024-03-16 12:29:05 +01:00
|
|
|
2. `config`: A set of all options' values in the current environment, which will be used
|
|
|
|
extensively in the subsequent section on the module system.
|
2024-02-14 09:00:16 +01:00
|
|
|
3. `options`: A set of all options defined in all Modules in the current environment.
|
2024-03-16 12:29:05 +01:00
|
|
|
4. `pkgs`: A collection containing all nixpkgs packages, along with several related
|
|
|
|
utility functions.
|
|
|
|
- At the beginner stage, you can consider its default value to be
|
|
|
|
`nixpkgs.legacyPackages."${system}"`, and the value of `pkgs` can be customized
|
|
|
|
through the `nixpkgs.pkgs` option.
|
|
|
|
5. `modulesPath`: A parameter available only in NixOS, which is a path pointing to
|
|
|
|
[nixpkgs/nixos/modules](https://github.com/NixOS/nixpkgs/tree/nixos-23.11/nixos/modules).
|
|
|
|
- It is defined in
|
|
|
|
[nixpkgs/nixos/lib/eval-config-minimal.nix#L43](https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/lib/eval-config-minimal.nix#L43).
|
|
|
|
- It is typically used to import additional NixOS modules and can be found in most
|
|
|
|
NixOS auto-generated `hardware-configuration.nix` files.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
## Passing Non-default Parameters to Submodules {#pass-non-default-parameters-to-submodules}
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
If you need to pass other non-default parameters to submodules, you will need to use some
|
|
|
|
special methods to manually specify these non-default parameters.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
The Nixpkgs module system provides two ways to pass non-default parameters:
|
|
|
|
|
|
|
|
1. The `specialArgs` parameter of the `nixpkgs.lib.nixosSystem` function
|
|
|
|
2. Using the `_module.args` option in any module to pass parameters
|
2024-02-15 09:10:05 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The official documentation for these two parameters is buried deep and is vague and hard
|
|
|
|
to understand. If readers are interested, I will include the links here:
|
2024-02-15 09:10:05 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
1. `specialArgs`: There are scattered mentions related to it in the NixOS Manual and the
|
|
|
|
Nixpkgs Manual.
|
2024-02-15 09:13:53 +01:00
|
|
|
- Nixpkgs Manual: [Module System - Nixpkgs]
|
2024-03-16 12:29:05 +01:00
|
|
|
- NixOS Manual:
|
|
|
|
[nixpkgs/nixos-23.11/nixos/doc/manual/development/option-types.section.md#L237-L244]
|
2024-03-16 05:39:05 +01:00
|
|
|
1. `_module.args`:
|
2024-03-16 12:29:05 +01:00
|
|
|
- NixOS Manual:
|
|
|
|
[Appendix A. Configuration Options](https://nixos.org/manual/nixos/stable/options#opt-_module.args)
|
2024-03-16 05:39:05 +01:00
|
|
|
- Source Code: [nixpkgs/nixos-23.11/lib/modules.nix - _module.args]
|
2024-02-15 09:10:05 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
In short, `specialArgs` and `_module.args` both require an attribute set as their value,
|
|
|
|
and they serve the same purpose, passing all parameters in the attribute set to all
|
|
|
|
submodules. The difference between them is:
|
2024-02-15 09:10:05 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
1. The `_module.args` option can be used in any module to pass parameters to each other,
|
|
|
|
which is more flexible than `specialArgs`, which can only be used in the
|
|
|
|
`nixpkgs.lib.nixosSystem` function.
|
|
|
|
1. `_module.args` is declared within a module, so it must be evaluated after all modules
|
|
|
|
have been evaluated before it can be used. This means that **if you use the parameters
|
|
|
|
passed through `_module.args` in `imports = [ ... ];`, it will result in an
|
|
|
|
`infinite recursion` error**. In this case, you must use `specialArgs` instead.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The NixOS community generally recommends prioritizing the use of the `_module.args` option
|
|
|
|
and resorting to `specialArgs` only when `_module.args` cannot be used.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Suppose you want to pass a certain dependency to a submodule for use. You can use the
|
|
|
|
`specialArgs` parameter to pass the `inputs` to all submodules:
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
```nix{13}
|
|
|
|
{
|
|
|
|
inputs = {
|
|
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
|
|
|
another-input.url = "github:username/repo-name/branch-name";
|
|
|
|
};
|
|
|
|
|
|
|
|
outputs = inputs@{ self, nixpkgs, another-input, ... }: {
|
|
|
|
nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem {
|
|
|
|
system = "x86_64-linux";
|
|
|
|
|
|
|
|
# Set all inputs parameters as special arguments for all submodules,
|
|
|
|
# so you can directly use all dependencies in inputs in submodules
|
|
|
|
specialArgs = { inherit inputs; };
|
|
|
|
modules = [
|
|
|
|
./configuration.nix
|
|
|
|
];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
Or you can achieve the same effect using the `_module.args` option:
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
```nix{14}
|
|
|
|
{
|
|
|
|
inputs = {
|
|
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
|
|
|
another-input.url = "github:username/repo-name/branch-name";
|
|
|
|
};
|
|
|
|
outputs = inputs@{ self, nixpkgs, another-input, ... }: {
|
|
|
|
nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem {
|
|
|
|
system = "x86_64-linux";
|
|
|
|
modules = [
|
|
|
|
./configuration.nix
|
|
|
|
{
|
|
|
|
# Set all inputs parameters as special arguments for all submodules,
|
|
|
|
# so you can directly use all dependencies in inputs in submodules
|
|
|
|
_module.args = { inherit inputs; };
|
|
|
|
}
|
|
|
|
];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Choose one of the two methods above to modify your configuration, and then you can use the
|
|
|
|
`inputs` parameter in `/etc/nixos/configuration.nix`. The module system will automatically
|
|
|
|
match the `inputs` defined in `specialArgs` and inject it into all submodules that require
|
|
|
|
this parameter:
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-02-15 09:16:19 +01:00
|
|
|
```nix{3}
|
2024-02-14 09:00:16 +01:00
|
|
|
# Nix will match by name and automatically inject the inputs
|
|
|
|
# from specialArgs/_module.args into the third parameter of this function
|
|
|
|
{ config, pkgs, inputs, ... }:
|
|
|
|
{
|
2023-07-04 06:18:46 +02:00
|
|
|
# ...
|
2024-02-14 09:00:16 +01:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The next section will demonstrate how to use `specialArgs`/`_module.args` to install
|
|
|
|
system software from other flake sources.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
## Installing System Software from Other Flake Sources {#install-system-packages-from-other-flakes}
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The most common requirement for managing a system is to install software, and we have
|
|
|
|
already seen in the previous section how to install packages from the official nixpkgs
|
|
|
|
repository using `environment.systemPackages`. These packages all come from the official
|
|
|
|
nixpkgs repository.
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Now, we will learn how to install software packages from other flake sources, which is
|
|
|
|
much more flexible than installing directly from nixpkgs. The main use case is to install
|
|
|
|
the latest version of a software that is not yet added or updated in Nixpkgs.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Taking the Helix editor as an example, here's how to compile and install the master branch
|
|
|
|
of Helix directly.
|
2024-02-14 09:00:16 +01:00
|
|
|
|
|
|
|
First, add the helix input data source to `flake.nix`:
|
|
|
|
|
|
|
|
```nix{6,12,18}
|
|
|
|
{
|
2023-06-23 14:29:12 +02:00
|
|
|
inputs = {
|
2024-02-14 09:00:16 +01:00
|
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
# helix editor, use the master branch
|
2024-01-11 03:13:31 +01:00
|
|
|
helix.url = "github:helix-editor/helix/master";
|
2023-06-23 14:29:12 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
outputs = inputs@{ self, nixpkgs, ... }: {
|
2024-02-14 09:00:16 +01:00
|
|
|
nixosConfigurations.my-nixos = nixpkgs.lib.nixosSystem {
|
|
|
|
system = "x86_64-linux";
|
|
|
|
specialArgs = { inherit inputs; };
|
|
|
|
modules = [
|
|
|
|
./configuration.nix
|
|
|
|
|
|
|
|
# This module works the same as the `specialArgs` parameter we used above
|
|
|
|
# chose one of the two methods to use
|
|
|
|
# { _module.args = { inherit inputs; };}
|
|
|
|
];
|
2023-06-23 14:29:12 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
Next, you can reference this flake input data source in `configuration.nix`:
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-02-15 09:13:53 +01:00
|
|
|
```nix{1,10}
|
2024-02-14 09:00:16 +01:00
|
|
|
{ config, pkgs, inputs, ... }:
|
2023-06-23 14:29:12 +02:00
|
|
|
{
|
2024-02-14 09:00:16 +01:00
|
|
|
# ...
|
2023-06-23 14:29:12 +02:00
|
|
|
environment.systemPackages = with pkgs; [
|
|
|
|
git
|
|
|
|
vim
|
|
|
|
wget
|
|
|
|
curl
|
2024-02-14 09:00:16 +01:00
|
|
|
# Here, the helix package is installed from the helix input data source
|
|
|
|
inputs.helix.packages."${pkgs.system}".helix
|
2023-06-23 14:29:12 +02:00
|
|
|
];
|
2024-02-14 09:00:16 +01:00
|
|
|
# ...
|
2023-06-23 14:29:12 +02:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Make the necessary changes and deploy with `sudo nixos-rebuild switch`. The deployment
|
|
|
|
will take much longer this time because Nix will compile the entire Helix program from
|
|
|
|
source.
|
2024-01-11 03:13:31 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
After deployment, you can directly test and verify the installation using the `hx` command
|
|
|
|
in the terminal.
|
2023-06-23 14:29:12 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Additionally, if you just want to try out the latest version of Helix and decide whether
|
|
|
|
to install it on your system later, there is a simpler way to do it in one command (but as
|
|
|
|
mentioned earlier, compiling from source will take a long time):
|
2024-01-11 04:27:42 +01:00
|
|
|
|
|
|
|
```bash
|
|
|
|
nix run github:helix-editor/helix/master
|
|
|
|
```
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
We will go into more detail on the usage of `nix run` in the following section
|
|
|
|
[Usage of the New CLI](../other-usage-of-flakes/the-new-cli.md).
|
2024-02-14 09:00:16 +01:00
|
|
|
|
2024-01-11 03:58:58 +01:00
|
|
|
## Leveraging Features from Other Flakes Packages
|
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
In fact, this is the primary functionality of Flakes — a flake can depend on other flakes,
|
|
|
|
allowing it to utilize the features they provide. It's akin to how we incorporate
|
|
|
|
functionalities from other libraries when writing programs in TypeScript, Go, Rust, and
|
|
|
|
other programming languages.
|
2024-01-11 03:58:58 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
The example above, using the latest version from the official Helix Flake, illustrates
|
|
|
|
this functionality. More use cases will be discussed later, and here are a few examples
|
|
|
|
referenced for future mention:
|
2024-01-11 03:58:58 +01:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
- [Getting Started with Home Manager](./start-using-home-manager.md): This introduces the
|
|
|
|
community's Home-Manager as a dependency, enabling direct utilization of the features
|
|
|
|
provided by this Flake.
|
|
|
|
- [Downgrading or Upgrading Packages](./downgrade-or-upgrade-packages.md): Here, different
|
|
|
|
versions of Nixpkgs are introduced as dependencies, allowing for flexible selection of
|
|
|
|
packages from various versions of Nixpkgs.
|
2024-01-11 03:58:58 +01:00
|
|
|
|
2024-02-14 09:00:16 +01:00
|
|
|
[nixpkgs/flake.nix]: https://github.com/NixOS/nixpkgs/tree/nixos-23.11/flake.nix
|
2024-03-16 12:29:05 +01:00
|
|
|
[nixpkgs/nixos/lib/eval-config.nix]:
|
|
|
|
https://github.com/NixOS/nixpkgs/tree/nixos-23.11/nixos/lib/eval-config.nix
|
|
|
|
[Module System - Nixpkgs]:
|
|
|
|
https://github.com/NixOS/nixpkgs/blob/23.11/doc/module-system/module-system.chapter.md
|
|
|
|
[nixpkgs/nixos-23.11/lib/modules.nix - _module.args]:
|
|
|
|
https://github.com/NixOS/nixpkgs/blob/nixos-23.11/lib/modules.nix#L122-L184
|
|
|
|
[nixpkgs/nixos-23.11/nixos/doc/manual/development/option-types.section.md#L237-L244]:
|
|
|
|
https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/doc/manual/development/option-types.section.md?plain=1#L237-L244
|