Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- [How to Guide](./HowTo.md)
- [Disko-Install](./disko-install.md)
- [Disko-Images](./disko-images.md)
- [Performing Unattended NixOS Installations](./unattended-install.md)
- [Support Matrix](./supportmatrix.md)
- [Reference](./reference.md)
- [Upgrade Guide](./upgrade-guide.md)
Expand Down
113 changes: 6 additions & 107 deletions docs/disko-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,110 +135,9 @@ from other devices if needed.

### Using disko-install in an offline installer

If you want to use **disko-install** from a custom installer without internet,
you need to make sure that in addition to the toplevel of your NixOS closure
that you plan to install, it also needs to contain **diskoScript** and all the
flake inputs for evaluation.

#### Example configuration to install

Add this to your flake.nix output:

```nix
{
nixosConfigurations.your-machine = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
# to pass this flake into your configuration (see the example below)
specialArgs = {inherit self;};
modules = [
{
# TODO: add your NixOS configuration here, don't forget your hardware-configuration.nix as well!
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";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
}
];
};
}
```

#### Example for a NixOS installer

```nix
# `self` here is referring to the flake `self`, you may need to pass it using `specialArgs` or define your NixOS installer configuration
# in the flake.nix itself to get direct access to the `self` flake variable.
{ lib, pkgs, self, ... }:
let
flakeOutPaths =
let
collector =
parent:
map (
child:
[ child.outPath ] ++ (if child ? inputs && child.inputs != { } then (collector child) else [ ])
) (lib.attrValues parent.inputs);
in
lib.unique (lib.flatten (collector self));

dependencies = [
self.nixosConfigurations.your-machine.config.system.build.toplevel
self.nixosConfigurations.your-machine.config.system.build.diskoScript
self.nixosConfigurations.your-machine.config.system.build.diskoScript.drvPath
self.nixosConfigurations.your-machine.pkgs.stdenv.drvPath

# https://github.com/NixOS/nixpkgs/blob/f2fd33a198a58c4f3d53213f01432e4d88474956/nixos/modules/system/activation/top-level.nix#L342
self.nixosConfigurations.your-machine.pkgs.perlPackages.ConfigIniFiles
self.nixosConfigurations.your-machine.pkgs.perlPackages.FileSlurp

(self.nixosConfigurations.your-machine.pkgs.closureInfo { rootPaths = [ ]; }).drvPath
] ++ flakeOutPaths;

closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
in
# Now add `closureInfo` to your NixOS installer
{
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"
'')
];
}
```

Also see the
[NixOS test of disko-install](https://github.com/nix-community/disko/blob/master/tests/disko-install/default.nix)
that also runs without internet.
Previous versions of this documentation contained some example code for how to
use **disko-install** to generate a custom installer that can be used to
perform offline installations of NixOS. Performing offline installations by
creating a custom installer that runs **disko-install** is no longer
recommended. If you would like to use **disko** to do an offline installation
of NixOS, then please take a look at [this guide](unattended-install.md).
135 changes: 135 additions & 0 deletions docs/unattended-install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Performing Unattended NixOS Installations

You can use **disko**’s NixOS module in order to perform unattended
installations of NixOS. When performing unattended NixOS installations, you
generally end up having two different NixOS configurations:

1. The deployee configuration. This is the configuration that you are trying to
install onto a system. You must create this NixOS configuration yourself.

2. The unattended installer configuration. This is the configuration that will
be used for the installation medium that your will boot into in order to
start the unattended installation. You can create the unattended installer
configuration yourself, or you can let **disko**’s NixOS module
automatically create it for you.

Regardless of which method you choose, unattended installs can be done offline.
The unattended installer should finish successfully regardless of whether or
not the computer that your are installing NixOS on is able to connect to the
Internet.

## Method 1: `nixos-rebuild build-image --image-variant disko-unattended-install-iso`

This first method is designed to make doing unattended installations as easy as
possible. This first method is recommended in most scenarios. In order to
perform an unattended NixOS installation using this method, follow these
instructions:

1. If you have not already, create a deployee configuration. Make sure that the
deployee configuration imports **disko**’s NixOS module and uses **disko**
for all of its disks, partitions and filesystems.

If you aren’t sure how to create such a NixOS configuration, then please
take some time to use **disko** in order to perform a manual installation
of NixOS. After you perform a manual installation of NixOS using **disko**,
you can reuse the NixOS configuration for that installation as the deployee
configuration for future unattended NixOS installations. For more
information about how to perform a manual installation of NixOS using
**disko**, please take a look at [the Quickstart Guide](./quickstart.md).

2. _(Optional)_ In the deployee configuration, customize the value of the
`image.modules.disko-unattended-install-iso` option. Customizing that option
will allow you to tweak the unattended installer configuration that will be
automatically generated for you in a later step. Take a look at [`<disko
repository>/lib/unattended-install.nix`][unattended-install.nix] for
documentation about some of the options that you may want to tweak here.

3. Build an unattended install ISO image by doing one of the following:

- If you did not use flakes when creating your deployee configuration, then
run this command:

```bash
nixos-rebuild build-image --include nixos-config=<path to deployee configuration.nix> --image-variant disko-unattended-install-iso
```

- If your deployee configuration is available as a flake output, then run
this command:

```bash
nixos-rebuild build-image --flake <flake URL>#<deployee configuration name> --image-variant disko-unattended-install-iso
```

Once either of those previous commands finishes, there will be a newly
generate ISO image located inside the `./result/iso` directory.

4. Write the ISO image that’s located in `./result/iso` onto a medium (for
example: a USB drive). This will turn the medium into an unattended
installation medium.

If you aren’t sure how to do this, then please take a look at [the NixOS
Manual’s “Booting from a USB flash drive”
section](https://nixos.org/manual/nixos/stable/#sec-booting-from-usb).

5. On the machine that you want to install NixOS on, start booting into the
unattended installation medium.

6. Once the unattended installation medium starts booting, you will see a menu
that contains multiple different options. Choose the option that contains
the text “Disko Unattended NixOS Installer”.

(That option may not be present in the boot menu if you made certain
customizations during step 2 of this procedure).

7. Wait for the installation to finish successfully. If the installation
finishes successfully, then the computer that you are installing NixOS on
will shut itself down automatically.

(The computer may not automatically shut down after the installation
finishes successfully if you made certain customizations during step 2 of
this procedure).

8. Remove the unattended installation medium from the computer.

9. Turn the computer on. At this point, your new installation of NixOS should
start booting!

## Method 2: Manually Creating the Unattended Installer Configuration

This second method is designed for advanced users. It’s not as straightforward
as the first method, but it allows for greater customization of the unattended
installation medium (for example, you could create an unattended installation
medium that doesn’t use any ISO 9660 filesystems at all).

The instructions for this method aren’t as specific as the instructions for the
previous method. You’ll need to put in some extra work in order to figure out
exactly how you want to do everything. This method is only recommended for
advanced users.

In order to perform an unattended NixOS installation using this method, follow
these instructions:

1. If you have not already, create a deployee configuration. In your deployee
configuration, make sure that the `disko.unattendedInstall.enable` option is
set to `false`.

2. Create an unattended installer configuration. In your unattended installer
configuration, make sure that the `disko.unattendedInstall.enable` option is
set to `true`. Also, make sure that you set the
`disko.unattendedInstall.deployeeConfiguration` option. For more information
about how to set `disko.unattendedInstall.deployeeConfiguration`, see
[`<disko repository>/lib/unattended-install.nix`][unattended-install.nix].

3. Somehow, install the unattended installer configuration onto a medium in
order to turn that medium into an unattended installation medium. You could
do this using [**disko-install**](./disko-install.md). You could also do
this by first running `nixos-rebuild build-image` and then writing the
resulting image to the medium.

4. Boot into the newly created unattended installation medium.

5. Make sure that the `unattendedInstallAtBoot.service` systemd service was
started during the boot process, or manually start the
`unattendedInstall.service` systemd service.

[unattended-install.nix]: ../lib/unattended-install.nix
18 changes: 18 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
diskoVersion = version;
};

unattended-install-module = pkgs.callPackage ./tests/unattended-install-module { };
unattended-install-iso = pkgs.callPackage ./tests/unattended-install-iso { };

checkJqSyntax = pkgs.runCommand "check-jq-syntax" { nativeBuildInputs = [ pkgs.jq ]; } ''
echo '{ "blockdevices" : [] }' | jq -r -f ${./disk-deactivate/disk-deactivate.jq} --arg disk_to_clear foo
echo '{ "blockdevices" : [] }' | jq -r -f ${./disk-deactivate/zfs-swap-deactivate.jq}
Expand All @@ -94,6 +97,21 @@
in
# FIXME: aarch64-linux seems to hang on boot
lib.optionalAttrs pkgs.stdenv.hostPlatform.isx86_64 (nixosTests // { inherit disko-install; })
# x86_32 is skipped because we need to create virtual machines that
# have more than 2 GiB of RAM.
// lib.optionalAttrs (!pkgs.stdenv.hostPlatform.isx86_32) {
inherit unattended-install-module;
}
# FIXME: aarch64-linux fails to find /dev/disk/by-label/nixos-26.11-aarch64
//
lib.optionalAttrs
(
!pkgs.stdenv.hostPlatform.isx86_32
&& !(pkgs.stdenv.hostPlatform.isAarch64 && pkgs.stdenv.hostPlatform.isLinux)
)
{
inherit unattended-install-iso;
}
//
pkgs.lib.optionalAttrs (!pkgs.stdenv.buildPlatform.isRiscV64 && !pkgs.stdenv.hostPlatform.isx86_32)
{
Expand Down
Loading
Loading