Làm cách nào để tách /etc/nixos/configuration.nix thành các mô-đun riêng biệt?


14

Giả sử tôi có một tệp cấu hình NixOS rất đơn giản :

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

Tôi biết rằng NixOS thực hiện một hệ thống mô-đun và một mô-đun là một .nixtệp. Mỗi .nixtệp phải chứa bất kỳ biểu thức Nix hợp lệ nào (ví dụ: hàm hoặc tập hợp). Điều này có nghĩa là tệp cấu hình NixOS /etc/nixos/configuration.nixchính nó là một mô-đun, chứa biểu thức Nix.

Tôi cũng biết rằng để làm cho biểu thức Nix trong một mô-đun khác hiển thị với mô-đun tôi đang làm việc, tôi có thể sử dụng importhàm tích hợp .

Tôi muốn tách khai báo các gói hệ thống (danh sách chứa emacsgitFull) thành tập tin packages.nix. Làm cách nào để chia tệp cấu hình NixOS thành các mô-đun riêng biệt?

Câu trả lời:


22

Biểu thức Nix

Một biểu hiện Nix cũng giống như bất kỳ biểu hiện ngôn ngữ lập trình: bất cứ điều gì mà đánh giá lại một giá trị hoặc một hàm. Một giá trị trong trường hợp này cũng có thể là một danh sách hoặc một tập hợp. Vì mô-đun Nix (tệp có phần mở rộng .nix) có thể chứa bất kỳ biểu thức Nix nào, bạn sẽ mong muốn tệp cấu hình NixOS ( /etc/nixos/configuration.nix) chứa một biểu thức Nix duy nhất làm nội dung tệp của nó.

Tệp cấu hình NixOS chứa biểu thức Nix có dạng:

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

Nếu bạn nhìn kỹ, bạn có thể thấy đó là một chức năng , bởi vì các chức năng tuân theo biểu mẫu pattern: form. Bạn cũng có thể thấy đó là một chức năng chấp nhận một bộ và trả về một bộ. Ví dụ, nếu bạn có một hàm f = {x, y}: {a = x + y;}, thì bạn có thể gọi nó là f {x=1; y=2;}và lấy lại một bộ {a=3;}.

Vì vậy, điều đó có nghĩa là khi bạn gọi nixos-rebuild switch, một cái gì đó gọi hàm bên trong tệp cấu hình NixOS với tập hợp phải chứa các thuộc tính configpkgs.

nhập khẩu

Ví dụ sau đây ./hardware-configuration.nix, cách đơn giản để trích xuất danh sách các gói vào một mô-đun riêng biệt packages.nixchỉ là tách environment.systemPackagestùy chọn ra và đưa ./packages.nixvào importstùy chọn. Bạn /etc/nixos/configuration.nixsẽ trông như thế nào:

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

Bạn /etc/nixos/packages.nixsẽ trông như thế nào:

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

Làm thế nào mà làm việc? Khi bạn chạy nixos-rebuild switch, quá trình đánh giá các biểu thức Nix và quyết định cài đặt các gói và các cuộc gọi configuration.nixvới một tập các thuộc tính, một số trong đó là configpkgs.

Nó tìm thấy thuộc tính importsbên trong các thiết lập trở lại, vì vậy nó đánh giá từng biểu Nix trong module importschứa với các đối số tương tự ( config, pkgs, vv).

Bạn phải có pkgsmột đối số (hoặc, về mặt kỹ thuật, thuộc tính của một tập hợp, chính nó là một đối số) của một hàm trong packages.nix, bởi vì, từ góc độ ngôn ngữ Nix, quá trình có thể hoặc không thể gọi hàm với tập hợp đó chứa pkgs. Nếu không, thuộc tính nào bạn sẽ đề cập đến, khi chạy with pkgs?

Bạn cũng phải có dấu chấm lửng, bởi vì hàm có thể được gọi với các thuộc tính khác, không chỉ pkgs.

Tại sao không có pkgstrong đó configuration.nix? Bạn có thể có nó, nhưng nếu bạn không đề cập đến nó ở bất cứ đâu trong tệp, bạn có thể bỏ qua nó một cách an toàn, vì dấu chấm lửng sẽ bao gồm chúng.

Cập nhật một thuộc tính bằng cách gọi một chức năng bên ngoài

Một cách khác là tạo một hàm trả về một tập hợp với một số thuộc tính và giá trị của thuộc tính đó bạn sẽ đặt vào bên trong environment.systemPackages. Đây là của bạn 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
}

của bạn packages.nix:

pkgs: with pkgs; [ emacs gitFull ]

import ./packages.nix pkgscó nghĩa là: tải và trả về biểu thức Nix trong ./packages.nixvà vì nó là một hàm, gọi nó bằng một đối số pkgs. with pkgs; [ emacs gitFull ]là một biểu thức có biểu thức , nó mang phạm vi của biểu thức trước dấu chấm phẩy đến biểu thức sau dấu chấm phẩy. Không có nó, nó sẽ được [ pkgs.emacs pkgs.gitFull ].


1
Nhập khẩu được sáp nhập như thế nào? Họ có sử dụng recursiveUpdate hoặc một cái gì đó tương tự không?
aij

1
Có cách nào để nhập khẩu có điều kiện?
CMCDragonkai

1
@CMCDragonkai giá trị của importschỉ là một danh sách, vì vậy bạn có thể thêm các yếu tố để mà có điều kiện, ví dụ:imports = [ ./foo.nix ./bar.nix ] ++ (if baz then [ ./quux.nix ] else []);
Warbo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.