Here is a simple way to deploy a NixOS configuration to a QEMU VM.
For demo purposes, we will be deploying a system that has OpenSSH, forwarding port 22 to the host so as to be able to ssh into the machine.
# demo.nix
{ pkgs, lib, config, ... }:
with lib;
{
imports = [
<nixpkgs/nixos/modules/profiles/qemu-guest.nix>
<nixpkgs/nixos/modules/virtualisation/qemu-vm.nix>
# import your own NixOS modules here if needed
];
config = {
nixpkgs.overlays = [
# define or import overlays here
#
(self: super: { })
# (import ./my-overlay.nix)
];
services.qemuGuest.enable = true;
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
fsType = "ext4";
autoResize = true;
};
boot = {
growPartition = true;
kernelParams = [ "console=ttyS0 boot.shell_on_fail" ];
loader.timeout = 5;
};
virtualisation = {
diskSize = 8000; # MB
memorySize = 2048; # MB
writableStoreUseTmpfs = false;
};
services.openssh.enable = true;
services.openssh.permitRootLogin = "yes";
environment.systemPackages = with pkgs;
some relevant packages here
[ # pkgs.ghc
];
# we could alternatively hook root or a custom user
# to some ssh key pair
users.extraUsers.root.password = ""; # oops
users.mutableUsers = false;
}; }
We want to pass this configuration when instantiating the entire NixOS system, and say that we want to derive a VM from it. This can all be accomplished with this reasonably simple command:
nix-build '<nixpkgs/nixos>' -A vm --arg configuration ./tde-host.nix
$ these derivations will be built:
/nix/store/vlbc7mpmbmcalanbwmj1mwprfrya4izz-system-path.drv
/nix/store/7srbcqni6sxpncnvn68015m9vmmp74ni-dbus-1.drv
/nix/store/brax9nap3sbvqhvj6z8x6jx3r5gjwr5x-unit-dbus.service.drv
/nix/store/ma234k9859hn4krv3f1h95m4mxb2aq8l-unit-polkit.service.drv
/nix/store/ylrnqqm8vkrfcrgxb4g3fshslfnk8p3f-unit-systemd-fsck-.service.drv
/nix/store/3prjamgmjhkw6slqgpnsgk3qpm1zjfia-system-units.drv
/nix/store/jjzhp7x7hfw5sdlmysn4cbwjphrywjfg-unit-dbus.service.drv
/nix/store/ls6kib0gqngpn4nb3bwfwrid4ig06l1y-user-units.drv
/nix/store/gkqb5gpcldnjnppy4g2qh17xswlqxvv5-etc.drv
/nix/store/zs8w34pglgq3iqka86fldklijqcp745q-nixos-system-nixos-20.03.1619.ab3adfe1c76.drv
/nix/store/jcgk4sbr2ir4sbjvvkd63xrjis55c0ki-closure-info.drv
/nix/store/l5srdimiiav2ix5ggcfcf8yzprs4c653-run-nixos-vm.drv
/nix/store/8swgy4mkx9wkayy0yk0lyr07144c1fzs-nixos-vm.drv
building '/nix/store/vlbc7mpmbmcalanbwmj1mwprfrya4izz-system-path.drv'...
created 5331 symlinks in user environment
building '/nix/store/7srbcqni6sxpncnvn68015m9vmmp74ni-dbus-1.drv'...
building '/nix/store/ma234k9859hn4krv3f1h95m4mxb2aq8l-unit-polkit.service.drv'...
building '/nix/store/ylrnqqm8vkrfcrgxb4g3fshslfnk8p3f-unit-systemd-fsck-.service.drv'...
building '/nix/store/brax9nap3sbvqhvj6z8x6jx3r5gjwr5x-unit-dbus.service.drv'...
building '/nix/store/jjzhp7x7hfw5sdlmysn4cbwjphrywjfg-unit-dbus.service.drv'...
building '/nix/store/3prjamgmjhkw6slqgpnsgk3qpm1zjfia-system-units.drv'...
building '/nix/store/ls6kib0gqngpn4nb3bwfwrid4ig06l1y-user-units.drv'...
building '/nix/store/gkqb5gpcldnjnppy4g2qh17xswlqxvv5-etc.drv'...
building '/nix/store/zs8w34pglgq3iqka86fldklijqcp745q-nixos-system-nixos-20.03.1619.ab3adfe1c76.drv'...
building '/nix/store/jcgk4sbr2ir4sbjvvkd63xrjis55c0ki-closure-info.drv'...
building '/nix/store/l5srdimiiav2ix5ggcfcf8yzprs4c653-run-nixos-vm.drv'...
building '/nix/store/8swgy4mkx9wkayy0yk0lyr07144c1fzs-nixos-vm.drv'...
/nix/store/4ylbbc8c99f1l1k7x6k584xa018hi216-nixos-vm
(That last path is the one ./result
points to as well.)
You can then use /nix/store/4ylbbc8c99f1l1k7x6k584xa018hi216-nixos-vm/bin/run-nixos-vm
or result/bin/run-nixos-vm
to boot the resulting VM through QEMU. You will quite likely want to forward some ports, to be able to ssh into the VM and perhaps talk to some other services listening on some ports left open by the firewall. To accomplish this, you can set the QEMU_NET_OPTS
env var before running the VM.
For example, to forward the VM’s SSH port (22
) to the host’s port 2221
, and the VM’s HTTP port (80
) to the host’s 8080
, you could do (after making sure that 80
and 22
are in the VM configuration’s networking.firewall.allowedTCPPorts
):
export QEMU_NET_OPTS="hostfwd=tcp::2221-:22,hostfwd=tcp::8080-:80"
$ result/bin/run-nixos-vm $
run-nixos-vm
waits for the VM process to be over, so fire up another terminal and write:
ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no root@localhost -p 2221 $
When prompted for a password, just hit Enter (because of users.extraUsers.root.password = ""
), and you should now be logged in as root in the VM.
Powered by Hakyll - RSS feed - servant paper