Open bam80 opened 7 months ago
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/disko-install-how-to-to-pass-flake-self-using-specialargs/43920/6
Does it work if you replace self
with ${./.}
?
@Mic92
The problem seem to be not with ${self}
, but with the dependencies
block:
self
there, it works:
dependencies = [
pkgs.stdenv.drvPath
];
self
once, it doesn't:
dependencies = [
pkgs.stdenv.drvPath
self.nixosConfigurations.i7.config.system.build.toplevel
];
Thoughts?
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/infinite-recursion-encountered-by-making-module-configurable/23508/11
Does it work if you replace
self
with${./.}
?
Where should I do that?
So I tried to insert the Example module for a NixOS installer to the flake itself, so it got direct access to the self
flake variable and no specialArgs = {inherit self;};
trick is needed.
Still, the same infinite recursion error.
@Mic92 how it worked on your side, did you test the code?
So I debugged it even more and apparently I was wrong about the reason is related to "self".
The problem seems to be in this line instead:
self.nixosConfigurations.your-machine.config.system.build.toplevel
, if I remove it the error goes away.
At the same time, the next line is all OK:
self.nixosConfigurations.your-machine.config.system.build.diskoScript
Any ideas what can be wrong with the toplevel
?
Do you have a complete example that leads to the said infinite recursion?
Please see the full reproducible sample:
# command to run:
# $ nix build .\#nixosConfigurations.i7.config.system.build.diskoImagesScript --show-trace
# flake.nix
{
inputs.disko.url = "github:nix-community/disko";
inputs.disko.inputs.nixpkgs.follows = "nixpkgs";
outputs = { self, disko, nixpkgs }: {
nixosConfigurations.i7 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ pkgs, ... }:
let
dependencies = [
pkgs.stdenv.drvPath
# "error: infinite recursion encountered" with this line!
self.nixosConfigurations.i7.config.system.build.toplevel
self.nixosConfigurations.i7.config.system.build.diskoScript
] ++ builtins.map (i: i.outPath) (builtins.attrValues self.inputs);
closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
in
{
environment.etc."install-closure".source = "${closureInfo}/store-paths";
environment.systemPackages = [
(pkgs.writeShellScriptBin "install-nixos-unattended" ''
set -eux
# Replace "/dev/disk/by-id/some-disk-id" with your actual disk ID
exec ${pkgs.disko}/bin/disko-install --flake "${self}#your-machine" --disk vdb "/dev/disk/by-id/some-disk-id"
'')
];
})
{
boot.loader.systemd-boot.enable = true;
imports = [ self.inputs.disko.nixosModules.disko ];
disko.devices = {
disk = {
vdb = {
device = "/dev/disk/by-id/some-disk-id";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
type = "EF00";
size = "500M";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}
];
};
};
}
you can't reference the systems own top-level in it's own dependencies (that's also unnecessary, because the system usually has itself available :)) what you need to do instead is create a new system which represents the installer you boot into and reference the system you want to install in there.
@Lassulus thank you for your answer.
Could you be more specific? I really new to Nix and didn't quite understand what you just said. I just followed the docs here, could you provide concrete code I should try?
Thanks.
Also, please note I'm chasing the fully unattended installer here. Can I do that?
If I need to do something manually on the system running the generated installer, this is not quite what I need.
Please reply so I wouldn't spent even more time on that, if my goal is unachievable currently.
This is the flake I come up with.
$ nixos-generate --flake . -f install-iso
$ qemu-system-x86_64 -cdrom /nix/store/...linux.iso/iso/nixos-24.05.20240422.1e1dc66-x86_64-linux.iso -enable-kvm -m 3000 -device e1000,netdev=net0 -netdev user,id=net0,hostfwd=tcp::5555-:22 -nographic target.img
In the VM, I then do the actual installation by manually running the command:
$ sudo install-nixos-unattended
# flake.nix
{
inputs.disko.url = "github:nix-community/disko";
inputs.disko.inputs.nixpkgs.follows = "nixpkgs";
outputs = { self, disko, nixpkgs }: {
nixosConfigurations.i7 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
({ pkgs, ... }:
let
dependencies = [
pkgs.stdenv.drvPath
self.nixosConfigurations.nixos.config.system.build.toplevel
self.nixosConfigurations.nixos.config.system.build.diskoScript
] ++ builtins.map (i: i.outPath) (builtins.attrValues self.inputs);
closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
in
{
environment.etc."install-closure".source = "${closureInfo}/store-paths";
environment.systemPackages = [
(pkgs.writeShellScriptBin "install-nixos-unattended" ''
set -eux
# Replace "/dev/disk/by-id/some-disk-id" with your actual disk ID
exec ${pkgs.disko}/bin/disko-install --flake "${self}#nixos" --disk vdb /dev/sda "$@"
'')
];
})
];
};
nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
{
boot.loader.systemd-boot.enable = true;
imports = [ self.inputs.disko.nixosModules.disko ];
disko.devices = {
disk = {
vdb = {
device = "/dev/disk/by-id/some-disk-id";
type = "disk";
content = {
type = "gpt";
partitions = {
ESP = {
type = "EF00";
size = "500M";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}
];
};
};
}
If I went in the right direction, let's reflect that in the documentation, I could help with that.
So it seems to me like you've found the perfect solution. I agree the documentation could be slightly better here, but I'd say the basic example is very close already. The only missing piece is how to incorporate it into a flake.
When I add this snippet as a file (
installer.nix
) to the flake, I get the infinite recursion error while generating the image withnixos-generate
: https://github.com/nix-community/disko/blob/dea314155a9b8a4de242bdd4c005ba8a5dce8385/docs/disko-install.md?plain=1#L186-L213I added
installer.nix
to the flake like this: