nixos-generators/README.md

359 lines
12 KiB
Markdown
Raw Normal View History

# nixos-generators - one config, multiple formats
The nixos-generators project allows to take the same NixOS configuration, and
generate outputs for different target formats.
Just put your stuff into the configuration.nix and then call one of the image builders.
2018-04-28 13:01:45 +03:00
For example:
2018-04-28 13:01:45 +03:00
```
nixos-generate -f iso
2018-04-28 13:01:45 +03:00
```
2018-05-17 23:46:25 +03:00
or
2018-05-17 23:46:25 +03:00
```
nixos-generate -f iso -c /etc/nixos/configuration.nix
2018-05-17 23:46:25 +03:00
```
2018-04-28 13:01:45 +03:00
it echoes the path to a iso image, which you then can flash onto an usb-stick
or mount & boot in a virtual machine.
2018-04-28 13:01:45 +03:00
2019-01-22 01:47:08 +03:00
# Installation
2021-11-06 09:17:19 +03:00
nixos-generators is part of [nixpkgs](https://search.nixos.org/packages?channel=unstable&show=nixos-generators&from=0&size=50&sort=relevance&type=packages&query=nixos-generator) and can be installed from there.
nixos-generators can be also installed from source into the user profile like this:
2019-01-22 01:47:08 +03:00
```console
nix-env -f https://github.com/nix-community/nixos-generators/archive/master.tar.gz -i
2019-01-22 01:47:08 +03:00
```
2021-11-23 04:17:21 +03:00
or for flakes users like this:
```console
nix profile install github:nix-community/nixos-generators
```
2021-11-06 09:17:19 +03:00
or run from the nix flake without installing:
```
nix run github:nix-community/nixos-generators -- --help
```
## Supported formats
2018-04-28 13:01:45 +03:00
format | description
--- | ---
2020-08-18 12:02:48 +03:00
amazon | Amazon EC2 image
azure | Microsoft azure image (Generation 1 / VHD)
cloudstack | qcow2 image for cloudstack
2019-12-01 20:25:19 +03:00
do | Digital Ocean image
2022-04-19 20:09:35 +03:00
docker | Docker image (uses systemd to run, probably only works in podman)
gce | Google Compute image
hyperv | Hyper-V Image (Generation 2 / VHDX)
2019-01-19 00:17:38 +03:00
install-iso | Installer ISO
2019-12-01 22:10:37 +03:00
install-iso-hyperv | Installer ISO with enabled hyper-v support
2019-01-19 00:17:38 +03:00
iso | ISO
2019-01-20 23:32:05 +03:00
kexec | kexec tarball (extract to / and run /kexec_nixos)
kexec-bundle | same as before, but it's just an executable
kubevirt | KubeVirt image
2022-08-16 15:52:07 +03:00
linode | Linode image
2019-02-07 19:59:08 +03:00
lxc | create a tarball which is importable as an lxc container, use together with lxc-metadata
lxc-metadata | the necessary metadata for the lxc image to start, usage: `lxc image import $(nixos-generate -f lxc-metadata) $(nixos-generate -f lxc)`
2019-01-20 23:32:05 +03:00
openstack | qcow2 image for openstack
2021-11-02 17:46:13 +03:00
proxmox | [VMA](https://pve.proxmox.com/wiki/VMA) file for proxmox
2022-02-15 21:35:01 +03:00
proxmox-lxc | LXC template for proxmox
qcow | qcow2 image
qcow-efi | qcow2 image with efi support
raw | raw image with bios/mbr. for physical hardware, see the 'raw and raw-efi' section
raw-efi | raw image with efi support. for physical hardware, see the 'raw and raw-efi' section
sd-aarch64 | Like sd-aarch64-installer, but does not use default installer image config.
sd-aarch64-installer | create an installer sd card for aarch64. For cross compiling use `--system aarch64-linux` and read the cross-compile section.
vagrant-virtualbox | VirtualBox image for [Vagrant](https://www.vagrantup.com/)
2019-01-20 23:32:05 +03:00
virtualbox | virtualbox VM
vm | only used as a qemu-kvm runner
2020-07-30 13:56:09 +03:00
vm-bootloader | same as vm, but uses a real bootloader instead of netbooting
vm-nogui | same as vm, but without a GUI
2020-05-21 04:07:15 +03:00
vmware | VMWare image (VMDK)
2018-05-11 13:01:00 +03:00
## Usage
2018-05-11 13:01:00 +03:00
Run `nixos-generate --help` for detailed usage information.
2019-01-17 19:38:32 +03:00
2019-12-02 13:27:25 +03:00
## select a specific nixpkgs channel
Adds ability to select a specific channel version.
2019-12-02 13:27:25 +03:00
Example:
2019-12-02 13:27:25 +03:00
```
nix-shell --command './nixos-generate -f iso -I nixpkgs=channel:nixos-19.09'
```
2019-12-01 20:25:19 +03:00
## Using a particular nixpkgs
To use features found in a different nixpkgs (for instance the Digital Ocean
image was recently merged in nixpkgs):
```
NIX_PATH=nixpkgs=../nixpkgs nixos-generate -f do
```
## Setting the disk image size
To specify the size of the generated disk image, use the `--disk-size` argument,
specifying the size in megabytes. This is currently supported by the following
formats. If this argument is unspecified it defaults to automatic sizing based
on the generated NixOS build.
- hyperv
- proxmox
- qcow
- raw-efi
- raw
- vm
- vm-nogui
- vmware
Example (20GB disk):
2024-03-27 15:07:55 +03:00
```bash
nixos-generate -c <your_config.nix> -f <format> --disk-size 20480
```
2024-03-27 15:07:55 +03:00
To set the disk size in `flake.nix`, set `diskSize` in the `specialArgs` argument of the `nixosGenerate` function.
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
xc = {
url = "github:joerdav/xc";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { nixpkgs, nixos-generators, xc, ... }:
let
pkgsForSystem = system: import nixpkgs {
inherit system;
overlays = [
(final: prev: { xc = xc.packages.${system}.xc; })
];
};
allVMs = [ "x86_64-linux" "aarch64-linux" ];
forAllVMs = f: nixpkgs.lib.genAttrs allVMs (system: f {
inherit system;
pkgs = pkgsForSystem system;
});
in
{
packages = forAllVMs ({ system, pkgs }: {
vm = nixos-generators.nixosGenerate {
system = system;
specialArgs = {
pkgs = pkgs;
diskSize = 20 * 1024;
};
modules = [
# Pin nixpkgs to the flake input, so that the packages installed
# come from the flake inputs.nixpkgs.url.
({ ... }: { nix.registry.nixpkgs.flake = nixpkgs; })
# Apply the rest of the config.
./configuration.nix
];
format = "raw";
};
});
};
}
```
2019-03-22 17:35:50 +03:00
## Cross Compiling
To cross compile nixos images for other architectures you have to configure
`boot.binfmt.emulatedSystems` or `boot.binfmt.registrations` on your host system.
In your system `configuration.nix`:
```nix
{
# Enable binfmt emulation of aarch64-linux.
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
}
```
Alternatively, if you want to target other architectures:
```nix
# Define qemu-arm-static source.
let qemu-arm-static = pkgs.stdenv.mkDerivation {
name = "qemu-arm-static";
src = builtins.fetchurl {
url = "https://github.com/multiarch/qemu-user-static/releases/download/v6.1.0-8/qemu-arm-static";
sha256 = "06344d77d4f08b3e1b26ff440cb115179c63ca8047afb978602d7922a51231e3";
};
dontUnpack = true;
installPhase = "install -D -m 0755 $src $out/bin/qemu-arm-static";
};
in {
# Enable binfmt emulation of extra binary formats (armv7l-linux, for exmaple).
boot.binfmt.registrations.arm = {
interpreter = "${qemu-arm-static}/bin/qemu-arm-static";
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'';
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff'';
};
# Define additional settings for nix.
nix.extraOptions = ''
extra-platforms = armv7l-linux
'';
nix.sandboxPaths = [ "/run/binfmt/arm=${qemu-arm-static}/bin/qemu-arm-static" ];
}
```
2019-03-22 17:35:50 +03:00
For more details on configuring `binfmt`, have a look at:
[binfmt options](https://search.nixos.org/options?channel=unstable&query=boot.binfmt),
[binfmt.nix](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/system/boot/binfmt.nix),
[this comment](https://github.com/NixOS/nixpkgs/issues/109661#issuecomment-762629438) and
2019-03-22 17:35:50 +03:00
[clevers qemu-user](https://github.com/cleverca22/nixos-configs/blob/master/qemu.nix).
Once you've run `nixos-rebuild` with these options,
2019-03-22 17:35:50 +03:00
you can use the `--system` option to create images for other architectures.
## Using as a nixos-module
`nixos-generators` can be included as a `NixOS module` into your existing `configuration.nix` making all available formats available through `config.formats` and configurable through `config.formatConfigs`. New formats can be defined by adding a new entry like `config.formatConfigs.my-new-format = {config, ...}: {}`.
An example `flake.nix` demonstrating this approach is below.
Images can be built from that flake by running:
- `nix build .#nixosConfigurations.my-machine.config.formats.vmware` or
- `nix build .#nixosConfigurations.my-machine.config.formats.my-custom-format` or
- `nix build .#nixosConfigurations.my-machine.config.formats.<any-other-format>`
```nix
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, nixos-generators, ... }: {
# A single nixos config outputting multiple formats.
# Alternatively put this in a configuration.nix.
nixosModules.myFormats = { config, ... }: {
imports = [
nixos-generators.nixosModules.all-formats
];
nixpkgs.hostPlatform = "x86_64-linux";
# customize an existing format
2023-08-26 11:12:51 +03:00
formatConfigs.vmware = { config, ... }: {
services.openssh.enable = true;
};
# define a new format
2023-08-26 11:12:51 +03:00
formatConfigs.my-custom-format = { config, modulesPath, ... }: {
imports = [ "${toString modulesPath}/installer/cd-dvd/installation-cd-base.nix" ];
formatAttr = "isoImage";
2023-07-22 17:20:50 +03:00
fileExtension = ".iso";
networking.wireless.networks = {
# ...
};
};
};
# a machine consuming the module
nixosConfigurations.my-machine = nixpkgs.lib.nixosSystem {
modules = [ self.nixosModules.myFormats ];
};
};
}
```
## Using in a Flake
`nixos-generators` can be included as a `Flake` input and provides
a `nixosGenerate` function for building images as `Flake` outputs. This
approach pins all dependencies and allows for conveniently defining multiple
output types based on one config.
An example `flake.nix` demonstrating this approach is below. `vmware` or
`virtualbox` images can be built from the same `configuration.nix` by running
`nix build .#vmware` or `nix build .#virtualbox`
2023-01-30 00:05:19 +03:00
Custom formats can be defined by building a format module (see the
[formats](./formats) directory for examples) and passing it to `nixosGenerate`
via an the `customFormats` argument. `customFormats` should be in the form of
an attribute sets of the form `<format name> = <format module>` and can define
multiple custom formats. `nixosGenerate` will then match against these custom formats as well as the built in ones.
2023-01-30 00:05:19 +03:00
```nix
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, nixos-generators, ... }: {
packages.x86_64-linux = {
vmware = nixos-generators.nixosGenerate {
system = "x86_64-linux";
modules = [
# you can include your own nixos configuration here, i.e.
# ./configuration.nix
];
format = "vmware";
2023-01-30 00:05:19 +03:00
# optional arguments:
# explicit nixpkgs and lib:
# pkgs = nixpkgs.legacyPackages.x86_64-linux;
# lib = nixpkgs.legacyPackages.x86_64-linux.lib;
# additional arguments to pass to modules:
# specialArgs = { myExtraArg = "foobar"; };
2023-01-30 00:05:19 +03:00
# you can also define your own custom formats
# customFormats = { "myFormat" = <myFormatModule>; ... };
# format = "myFormat";
};
vbox = nixos-generators.nixosGenerate {
system = "x86_64-linux";
format = "virtualbox";
};
};
};
}
```
## Format-specific notes
### `raw` and `raw-efi`
`raw` and `raw-efi` images can be used on physical hardware, but benefit from some tweaks.
* These images are configured to log to the serial console, and not to your display. One workaround for this is to add `boot.kernelParams = [ "console=tty0" ];` to your configuration, which will override the image's default `console=ttyS0`.
* By default, grub will timeout after 1 second. To extend this, set `boot.loader.timeout = 5;` (or longer)
* If boot fails for some reason, you will not get a recovery shell unless the root user is enabled, which you can do by setting a password for them (`users.users.root.password = "something";`, possibly `users.mutableUsers = true;` so you can interactively change the passwords after boot)
* After booting, if you intend to use `nixos-switch`, consider using `nixos-generate-config`.
2019-01-17 19:38:32 +03:00
### License
This project is licensed under the [MIT License](LICENSE).
2022-04-13 14:03:10 +03:00
# FAQ
#### No space left on device
This means either /tmp, /run/user/$UID or your TMPFS runs full. Sometimes setting TMPDIR to some other location can help, sometimes /tmp needs to be on a bigger partition (not a tmpfs).