Impossible to log in to result of nixos-rebuild build-vm

TLDR

How can you log in to any accounts on the VM created by nixos-rebuild build-vm?

My personal sob story

So I tried to upgrade my machine from NixOS 20.03 to 20.09. Unfortunately this gives me a system in which, after logging in via the graphical session manager, NONE of my (admittedly idiosyncratic) basic tools work! I am unable to start any of

  • terminal/shell
  • editor
  • launcher

This system is about as useful to me as a brick.

The good news is, I’m running NixOS, so booting into my previously working environment is totally trivial. Phew, and hooray for Nix!

When I first started running NixOS, I was excited to discover nixos-rebuild build-vm. What a wonderful idea for trying out such major upgrades without completely interrupting your life! Unfortunately, when I tried it running the VM, I was unable to log into the user account, so I sighed, and got on with my life in general and exploration of Nix in particular, and mostly forgot about build-vm.

Fast-forward to today: let’s try using nixos-rebuild build-vm to try to debug my new build, while still being able to get on with life on my old system. Unfortunately I am still unable to log into my account on the VM.

It’s excruciating that such a wonderful idea seems to be unusable for my purpose. So near, and yet so far!

2 Likes

How do you define password for your user account?

Often, people just set users.mutableUsers = false; and define users.users.<name>.hashedPassword in their configuration, which should allow them to log in successfully using the same password without any fuss. (example)

Even if you set password for your regular system imperatively, you might want to set one declaratively just for easy access in build-vm. Adding something like this to your imports list in your configuration.nix might work:

({options, lib, ...}: lib.mkIf (options ? virtualisation.memorySize) {
  users.users.jacg.password = "foo";
})

I am relying on the fact that nixos-rebuild build-vm instantiates the vm attribute from the nixos directory:

and the VM config loads the modules/virtualisation/qemu-vm.nix module, which is not loaded for regular systems so its options are only available when building a VM.

Of course, if you import this module or any other module that declares the virtualisation.memorySize option into your regular system configuration, you will need to find a different discriminator.

Or you might just want reconsider non-mutable users for simplicity.

1 Like

Declaratively …

… at least, I was under the impression that I was setting it declaratively … [I try to do everything declaratively, that’s pretty much the point of Nix AFAIAC: I’ve wasted too much time and energy in my life on hidden state screwing things up] …

… but it turns out I had switched it to imperative in some explorative hacking session, and hadn’t set it back.

So I switched it back to declarative. Still didn’t work. I even resorted to password = "aaa" to make absolutely sure that I can’t mistype it, even with my Dvorak keyboard (a is in the same place on Dvorak and Qwerty) and it still didn’t work.

Eventually, I came across the following in the manual:

Important: delete the $hostname.qcow2 file if you have started the virtual machine at least once without the right users, otherwise the changes will not get picked up.

When I removed this file, I could log in to the VM.

So … it was piece of implicit mutable state outside of my declarative Nix configuration which was screwing it up! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARRRRRRGHHHHHHH! This is soul-crushing.

When I recover the desire to live, the next hurdle will be to get the VM to pick up my user settings, so that I can actually start debugging and fixing them. I have these defined declaratively via home-manager … but the manual states that

The VM does not have any data from your host system, so your existing user accounts and home directories will not be available unless you have set mutableUsers = false.

I have mutableUsers = false … and yet my home directory on the VM remains empty.

Any suggestions?

1 Like

Do you mean you set your home-manager configuration in your configuration.nix, or do you use a separate home.nix and activate it through the home-manager command?

The manual is bit ambiguous here – I understand it like this:

  • The activation script will create the declaratively defined users and create empty home directories for them if they do not exist, when mutableUsers = false.
  • The home directories will not inherit the contents from the host system in either case.

But even that understanding is misleading, since the declaratively defined users and home directories will be created in either case and it is just that with mutableUsers = true, you will not be able to log in without setting password through initialHashedPassword.

Separate home.nix activated with home-manager command.

Indeed … I was suspecting that I was inferring something that wasn’t true.

So, given that my configuration is mostly in my home.nix, leaving to configuration.nix only those things which cannot really be done with home-manager, what’s the most sensible way to use the VM (or otherwise?) to get to understand why my new system is unusable?

I do not use home-manager so I might not be the person to answer this but from what I remember, you can import your home-manager configuration from your NixOS configuration:

If you combine it with the VM specific configuration trick from above, this can probably go a long way.

Alternately, you could use the home-manager command in the VM, just like you do on your regular system.

For completeness, the solution to my particular problem depended on spotting the following in the maual:

Important: delete the $hostname.qcow2 file if you have started the virtual machine at least once without the right users, otherwise the changes will not get picked up.

In the first reply @jtojnar provides other relevant and useful information, but all of that will be ignored by the system if you leave the .qcow2 file lying around!

6 Likes

Glad you got it fixed!

Erase your darlings: immutable infrastructure for mutable systems - Graham Christensen — it sounds like this sort of setup is what you’d like, and it should eliminate such unintended stateful effects of nixos.qcow2.

1 Like

This quite interesting feature is shown at an early stage of documentation for the flexibility of NixOS at Chapter 3. Changing the Configuration NixOS 23.11 manual | Nix & NixOS

At last version downloaded a week ago and installed such instruction does not work - or at least it is not clear enough for the newcomer where and how to set the
users.users.your-user.initialHashedPassword = “test”; or set mutableUsers = false

I’ve tried some changes by
sudo nano /etc/nixos/configuration.nix
sudo nixos-rebuild switch

I was sure to delete the .qcow2 file before, each time - and even restarted the all process.

Is there an configuration.nix example of this VM working?
An example of /etc/nixos/configuration.nix would be quite useful.

If not I find it is preferable not to include that feature so soon in the documentation.

Thank you

The initialHashedPassword should be a hash, not sure if that’s what you tried. E.g., the password test can be hashed with mkpasswd to get the hash that you can use:

users.users.your-user.initialHashedPassword = "$y$j9T$llM5/ZW4lxeKKdEqhrnAr.$NeUFEU3x4cWMTR0aLSNASu5uT5.RGrXNBa7dZPTN9A.";

You might be interested in the virtualisation.vmVariant option.

https://search.nixos.org/options?channel=unstable&show=virtualisation.vmVariant&from=0&size=50&sort=relevance&type=packages&query=vmvariant

2 Likes