Installing NixOS on Lenovo E7470 fails

I am currently trying to install NixOS on a Lenovo e7470, unfortunately I am failing at it right now. The problem is that I still have a Windows 10 partition on my computer, which I would also like to keep. My partitions look like this on my computer:

Therefore, I can install there at all my NixOS with on it and a Grub as bootloader. If so, how do I have to edit the configuration.nix? At the moment I get the error:

building Nix...
building the system configuration...
these derivations will be built:
  /nix/store/g7bccgfi6z8v9n8kclydcq9nb5ni1bbc-nixos-21.11.335733.f6ddd55d5f9.drv
  /nix/store/ngg8fvwaf8vn7pwyk46hv7kjqmvxfanx-configuration.nix.drv
  /nix/store/1spd2k6f32nn5y9lr8kdph9y54fbxmwm-local-cmds.drv
  /nix/store/2jbyb03ahxqzyn1ir9dmbx3nvp31dhrr-stage-2-init.sh.drv
  /nix/store/73m3wl7qinsphbws5vx0cfj1xskh7pbl-nixos-system-nixos-21.11.335733.f6ddd55d5f9.drv
building '/nix/store/ngg8fvwaf8vn7pwyk46hv7kjqmvxfanx-configuration.nix.drv'...
building '/nix/store/g7bccgfi6z8v9n8kclydcq9nb5ni1bbc-nixos-21.11.335733.f6ddd55d5f9.drv'...
building '/nix/store/1spd2k6f32nn5y9lr8kdph9y54fbxmwm-local-cmds.drv'...
building '/nix/store/2jbyb03ahxqzyn1ir9dmbx3nvp31dhrr-stage-2-init.sh.drv'...
building '/nix/store/73m3wl7qinsphbws5vx0cfj1xskh7pbl-nixos-system-nixos-21.11.335733.f6ddd55d5f9.drv'...
**Warning: do not know how to make this configuration bootable; please enable a boot loader.**
activating the configuration...
setting up /etc...
reloading user units for nixos...
setting up tmpfiles
the following new units were started: avahi-daemon.service

My configuration.nix looks like this at the moment, do I have errors in it at the moment?

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];
  
  nixpkgs.config.allowUnfree = true;

  nixpkgs.config.permittedInsecurePackages = [
         "ffmpeg-2.8.17"
         "python2.7-Pillow-6.2.2"
         "openssl-1.0.2u"
       ];

  # Use the systemd-boot EFI boot loader.
  #boot.loader.systemd-boot.enable = true;
  #boot.loader.efi.canTouchEfiVariables = true;
  boot.loader.grub.useOSProber = true;
  boot.loader.grub.enable                = true;
  boot.loader.grub.copyKernels           = true;
  boot.loader.grub.efiInstallAsRemovable = true;
  boot.loader.grub.devices = [ "/dev/nvme0n1" ];
  boot.loader.grub.efiSupport            = true;
  boot.loader.grub.fsIdentifier          = "label";
  boot.loader.grub.splashImage           = ./backgrounds/grub-nixos-3.png;
  boot.loader.grub.splashMode            = "stretch";
  boot.loader.grub.devices               = [ "nodev" ];
  networking.hostName = "thorinshalle"; # Define your hostname.

  # networking.hostName = "nixos"; # Define your hostname.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Set your time zone.
  # time.timeZone = "Europe/Amsterdam";

  # The global useDHCP flag is deprecated, therefore explicitly set to false here.
  # Per-interface useDHCP will be mandatory in the future, so this generated config
  # replicates the default behaviour.
  networking.useDHCP = false;
  networking.interfaces.enp0s31f6.useDHCP = true;
  networking.interfaces.wlp1s0.useDHCP = true;

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Select internationalisation properties.
  # i18n.defaultLocale = "en_US.UTF-8";
  # console = {
  #   font = "Lat2-Terminus16";
  #   keyMap = "us";
  # };
  i18n = {
    defaultLocale = "de_DE.UTF-8";
  };
  console.font = "Lat2-Terminus16";
  console.keyMap = "de";

  # Set your time zone.
  time.timeZone = "Europe/Berlin";


  # Enable the X11 windowing system.
  services.xserver.enable = true;


  # Enable the GNOME Desktop Environment.
  services.xserver.displayManager.gdm.enable = true;
  services.xserver.desktopManager.gnome.enable = true;
  services.gnome.chrome-gnome-shell.enable = true;
  nixpkgs.config.firefox.enableGnomeExtensions = true;

  # Configure keymap in X11
  services.xserver.layout = "de";
  services.xserver.xkbOptions = "eurosign:e";

  # Enable CUPS to print documents.
   services.printing.enable = true;

  # Enable sound.
  sound.enable = true;
  hardware.pulseaudio.enable = true;

  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  # users.users.jane = {
  #   isNormalUser = true;
  #   extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
  # };
  users.extraUsers.bavramor = {
	isNormalUser = true;
        createHome = true;
        extraGroups = [ "wheel" "networkmanager" "tty" "messagebus" "postfix" "postdrop" "audio" "disk" "uucp" "lp" "video" "wwwrun" "adm" "lightdm" "mysql"];
	home = "/home/bavramor";
	};
  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
     vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
     wget
     firefox
     google-chrome
     chromium
     #vivaldi
     firefox  
     libreoffice-fresh
     filezilla
     gparted
     gimp
     inkscape
     #scribus
     blender
     guake 
     clementine
     cmus
     vlc 	   
     git
     hexchat
     busybox
     pciutils
     deluge
     transmission
     #drush
     unrar
     ntfs3g
     brasero
     putty
     xsane
     cups
     signal-desktop
     empathy
     kid3
     adoptopenjdk-jre-bin
     gnome.gnome-tweaks
     #evolution
     #evolution-data-server
     hunspell
     hunspellDicts.de_DE
     aspell
     aspellDicts.de
     keepassxc
     #php74Packages.composer
     #tor-browser-bundle-bin
     jetbrains.jdk
     jetbrains.phpstorm
     jetbrains.goland
     jetbrains.pycharm-professional
     #go_bootstrap
     gnomeExtensions.tweaks-in-system-menu
     gnomeExtensions.caffeine
     gnome.gnome-tweaks    
     gnome.adwaita-icon-theme
     gnomeExtensions.appindicator
     gnome.gnome-shell-extensions
     gnome.gnome-settings-daemon
     gnome-menus
     gnomeExtensions.applications-menu
     python39Full   
     chrome-gnome-shell
     whatsapp-for-linux
     tdesktop
     anydesk
     putty
     krita
     #scribus
     #pgadmin
     pgmanage
     putty
     zoom-us
     clinfo
     vulkan-tools
     mumble     
     #numix-gtk-theme
   ];

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  # services.openssh.enable = true;

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "21.11"; # Did you read the comment?

}

Or is there already something wrong with the partitions. Of course I could also change it. Then I would have to install only Windows 10 again, which would be of course much effort for me. Therefore I would like to avoid that. But how do I partition the drive then best for Win10 and NixOS Thank you for your help.

Greetz Bavra

You’re doing it pretty much right, NixOS is actually fully installed and working. You just didn’t install the boot loader.

The error you need to fix is:

I’m not 100% sure what exactly this is caused by, but the issue is almost definitely with this part of your grub config:

The grub config must have a device set to actually install a bootloader. Setting nodev is basically saying “please don’t install a boot loader for me”, which is probably why you’re seeing that error.

If you fix that, the next issue will be that "/dev/nvme0n1" isn’t actually a partition. If I understand your partitioning scheme you wanted "/dev/nvme0n1p5" (this won’t actually work the way you intend it to, but more on that later). Since you’re only installing grub to one device, I would also recommend using boot.loader.grub.device instead of devices.

Finally, your partitioning scheme is a bit fundamentally broken. UEFI doesn’t work like this - UEFI boot loaders are expected to all live in exactly one EFI partition, the firmware should (unless buggy) detect them all and allow you to switch between them in its GUI. That means you actually want to point grub at "/dev/nvme0n1p1", and just remove the "/dev/nvme0n1p5" partition again (and perhaps resize the windows partition to include it, but windows often really doesn’t like that, so maybe that’s just lost space now).

Your OSes will then both independently set which boot loader to use. Since you use boot.loader.grub.useOSProber, grub will also be able to boot windows, so you won’t notice this from the Linux side, however occasionally Windows updates will reset the default boot loader to the Windows one, in which case you’ll need to switch this back in your UEFI UI (or in the worst case, with an EFI variable editor in windows, or efibootmgr in a live CD).

Setting "nodev" is exactly what one has to do for EFI boot.

Though instead of doing grub + OSprober and then chainload windows, I’d go for systemd-boot which is usually easier to setup for EFI, and then use the systems EFI boot selection to switch between windows and nixos.

1 Like

Oh, huh, you’re absolutely right, apparently the efi path setting is in boot.loader.efi.efiSysMountPoint. I still think there’s space for grub on dual-boot setups, because usually the UEFI is slower to get through, what with all modern ones wanting mouse cursor input.

Having read through the grub config code, it seems that the module checks specifically if boot.loader.grub.devices == ["nodev"], so if you set it twice like @bavramor does it will fail that check and end up doing things that weren’t intended (install non-EFI grub I think?).

The grub module seems far more complex than it should be… Wonder if it could be split into grub and grubEfi modules.

It is even weird that this config tries to even install something. It shouldn’t be evaluatable, as it defines the same key twice in the same set…

I’d expect an error like this:

nix-repl> {foo = 0; foo = 1;}
error: attribute 'foo' already defined at (string):1:2