Skip to content

Instantly share code, notes, and snippets.

@tarnacious
Last active February 22, 2024 01:22
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tarnacious/f9674436fff0efeb4bb6585c79a3b9ff to your computer and use it in GitHub Desktop.
Save tarnacious/f9674436fff0efeb4bb6585c79a3b9ff to your computer and use it in GitHub Desktop.
Build a bare bones bootable nixos qcow2 image suitable for running with libvirt/qemu/kvm.

Build a bare bones bootable nixos qcow2 image suitable for running with libvirt/qemu/kvm.

nix-build '<nixpkgs/nixos>' -A config.system.build.qcow2 --arg configuration "{ imports = [ ./build-qcow2.nix ]; }"

Should create a results directory that symlinks to a qcow2 image in the store.

I basically copied this from the openstack image in nixpkgs because I don't know a better way.

Update:

Thanks to @d-goldin I've just learnt I can start a VM using just:

nix-build '<nixpkgs/nixos>' -A vm -I nixos-config=./machine-config.nix build-vm
./result/bin/run-nixos-vm

Which is pretty neat, and I guess pretty common.

{ config, lib, pkgs, ... }:
with lib;
{
imports =
[
<nixpkgs/nixos/modules/installer/cd-dvd/channel.nix>
./machine-config.nix
];
system.build.qcow2 = import <nixpkgs/nixos/lib/make-disk-image.nix> {
inherit lib config;
pkgs = import <nixpkgs> { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
diskSize = 8192;
format = "qcow2";
configFile = pkgs.writeText "configuration.nix"
''
{
imports = [ <./machine-config.nix> ];
}
'';
};
}
{ pkgs, lib, ... }:
with lib;
{
imports = [
<nixpkgs/nixos/modules/profiles/qemu-guest.nix>
];
config = {
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
autoResize = true;
};
boot.growPartition = true;
boot.kernelParams = [ "console=ttyS0" ];
boot.loader.grub.device = "/dev/vda";
boot.loader.timeout = 0;
users.extraUsers.root.password = "";
};
}
@munibrahman
Copy link

What is up with the weird formatting in machine-config.nix?

@AleXoundOS
Copy link

@munibrahman, the first line has some garbage in its end (starting from 124th character).

@tarnacious
Copy link
Author

Looks like I copied it from my terminal, the garbage at the end on the string was the tmux copy-mode pager.

@gcr
Copy link

gcr commented Sep 20, 2023

When I try this, I get Segmentation fault. Do you have any thoughts on what's going wrong?

nix log output here: https://gist.github.com/gcr/7857bf5906e20273e156e6b467ef51f7 The command was: nix-build '<nixpkgs/nixos>' -A config.system.build.qcow2 --arg configuration "{imports = [ ./build-qcow2.nix ]; }" I'm on Debian testing

$ nix --version
nix (Nix) 2.8.0

The log mentions not having access to KVM, but I thought qemu's CPU emulation is a good fallback, so I'm not sure if this is a red herring. Besides, if kvm really was required, wouldn't it be part of the nix store, or is this one of the instances where the host machine's configuration is leaking over?

(i'm trying to learn nix and nixos, but every time i try to run an untested blog post or example like this, it winds up not working on my system... i know it's just my frustration talking, but as a new user, i'm surprised and worried at how brittle these commands turn out to be in practice)

@tarnacious
Copy link
Author

hi @gcr

I just tried this on nixos 22.05, on a system with KVM virtualization capabilities.

I was a bit surprised it worked as I wrote this gist almost 4 years ago, I posted the output here in case it's helpful.

https://gist.github.com/tarnacious/e16b54426296decc7f79e6ed0bbef576

Here is my libvirt configuration:

https://github.com/tarnacious/server-configuration/blob/f6a3bbea3ee7a6689522b6c16a4f82c951b4c00b/roles/thinkpad/templates/configuration.nix#L107-L118

I don't think the ovmf or swtpm stuff is relevant, I think I added that to boot windows VMs.

What might be relevant is that my user is a member of three possibly important groups

https://github.com/tarnacious/server-configuration/blob/main/roles/thinkpad/templates/configuration.nix#L184-L186

I guess it might be worth checking if you can start a VM with qemu on your machine with your user, either directly or via libvirt / virt-manager.

Sorry to hear you had problems with it and hope you work them out.

If you do get the image built, I was able to start the VM with these commands (it didn't work with the build-vm parameter)

nix-build '<nixpkgs/nixos>' -A vm -I nixos-config=./machine-config.nix
./result/bin/run-nixos-vm

(i'm trying to learn nix and nixos, but every time i try to run an untested blog post or example like this, it winds up not working on my system... i know it's just my frustration talking, but as a new user, i'm surprised and worried at how brittle these commands turn out to be in practice)

I still consider myself a novice, I know what you mean.

@jtara1
Copy link

jtara1 commented Feb 21, 2024

I was getting file not found error trying to nixos-rebuild dry-build within the VM running the qcow2

because of

    configFile = pkgs.writeText "configuration.nix"
      ''
        {
          imports = [ <./machine-config.nix> ];
        }
      '';

I replaced it with

    configFile = pkgs.writeText "configuration.nix" (pkgs.lib.readFile ./machine-config.nix);

It's really useful to have a qcow2 file. Used gnome boxes to run the qcow2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment