Nixos

如何將 /etc/nixos/configuration.nix 拆分為單獨的模組?

  • March 28, 2016

假設我有一個非常簡單的NixOS 配置文件

{ config, pkgs, ... }:    
{
 imports =
   [ # Include the results of the hardware scan.
     ./hardware-configuration.nix
   ];
 # SOME STUFF
 environment.systemPackages = with pkgs; [ emacs gitFull ];
 # SOME STUFF
}

我知道 NixOS 實現了一個模組系統,一個模組就是一個.nix文件。每個.nix文件都應該包含任何有效的Nix 表達式(例如函式或集合)。這意味著 NixOS 配置文件/etc/nixos/configuration.nix本身就是一個模組,包含一個 Nix 表達式。

我也知道要使另一個模組中的 Nix 表達式對我正在使用的模組可見,我可以使用內置import函式

我想將系統包的聲明(包含emacsand的列表gitFull)拆分為 file packages.nix。如何將 NixOS 配置文件拆分為單獨的模組?

尼克斯表達式

Nix 表達式就像任何程式語言表達式:任何計算結果為值或函式的東西。在這種情況下,值也可以是列表或集合。由於 Nix 模組(副檔名為 的文件.nix)可以包含任何 Nix 表達式,您會期望 NixOS 配置文件 ( /etc/nixos/configuration.nix) 包含單個 Nix 表達式作為其文件內容。

NixOS 配置文件包含以下形式的 Nix 表達式:

{config, pkgs, ...}: { /* various configuration options */ }

如果你仔細看,你會發現它是一個函式,因為函式遵循形式pattern: form。您還可以看到它是一個接受集合併返回集合的函式。例如,如果你有一個 function f = {x, y}: {a = x + y;},那麼你可以呼叫它 asf {x=1; y=2;}並取回一個 set {a=3;}

所以這意味著當你呼叫時nixos-rebuild switch,一些東西會呼叫 NixOS 配置文件中的函式,其中的集合必須包含屬性configpkgs.

進口

在 的範例中./hardware-configuration.nix,將包列表提取到單獨的模組中的簡單方法packages.nix是將environment.systemPackages選項取出並放入./packages.nix選項imports中。你/etc/nixos/configuration.nix會看起來像:

{ config, ... }:    
{
 imports =
   [ # Include the results of the hardware scan.
     ./hardware-configuration.nix
     # Include the package list.
     ./packages.nix
   ];
 # SOME STUFF
 # SOME STUFF
}

/etc/nixos/packages.nix會看起來像:

{ pkgs, ... }:
{
 environment.systemPackages = with pkgs; [ emacs gitFull ];
}

這是如何運作的?當您執行nixos-rebuild switch時,評估 Nix 表達式並決定安裝包等的過程會呼叫configuration.nix一組屬性,其中一些屬性是configpkgs

它在返回的集合中找到屬性imports,因此它評估模組中imports包含相同參數(config、、pkgs等)的每個 Nix 表達式。

你必須有pkgs一個函式的參數(或者,從技術上講,一個集合的屬性,它本身就是一個參數)packages.nix,因為從 Nix 語言的角度來看,該過程可能會或可能不會使用集合呼叫函式包含pkgs. 如果沒有,您在執行時會引用什麼屬性with pkgs

您還必須有省略號,因為該函式可能會使用其他屬性呼叫,而不僅僅是pkgs.

pkgs為什麼裡面沒有configuration.nix?你可以擁有它,但如果你不在文件中的任何地方引用它,你可以放心地省略它,因為省略號無論如何都會包含它們。

通過呼叫外部函式更新屬性

另一種方法是創建一個函式,該函式返回具有某個屬性的集合,以及您將放入的該屬性的值environment.systemPackages。這是你的configuration.nix

{ config, pkgs, ... }:    
{
 imports =
   [ # Include the results of the hardware scan.
     ./hardware-configuration.nix
   ];
 # SOME STUFF
 environment.systemPackages = import ./packages.nix pkgs;
 # SOME STUFF
}

你的packages.nix

pkgs: with pkgs; [ emacs gitFull ]

import ./packages.nix pkgs意思是:載入並返回 Nix 表達式./packages.nix,因為它是一個函式,所以用一個參數呼叫它pkgswith pkgs; [ emacs gitFull ]是一個with-expression,它將分號之前的表達式的範圍帶到分號之後的表達式。沒有它,它會是[ pkgs.emacs pkgs.gitFull ]

引用自:https://unix.stackexchange.com/questions/272660