summary refs log tree commit diff
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2021-02-21 18:17:22 +0000
committerGitHub <noreply@github.com>2021-02-21 18:17:22 +0000
commit93b17c1b4d29ca2f42b04f1413cf3557efe18a06 (patch)
tree1c51fd619ed886fd3aa940805fccaabb32bbe7dc
parentcf22d5fee78d8fa5e6fef32acb17d3df3d3c5b28 (diff)
parent60450f6b8dd5566106e1bfb0e9946686f91ed8c6 (diff)
downloadnixpkgs-93b17c1b4d29ca2f42b04f1413cf3557efe18a06.tar
nixpkgs-93b17c1b4d29ca2f42b04f1413cf3557efe18a06.tar.gz
nixpkgs-93b17c1b4d29ca2f42b04f1413cf3557efe18a06.tar.bz2
nixpkgs-93b17c1b4d29ca2f42b04f1413cf3557efe18a06.tar.lz
nixpkgs-93b17c1b4d29ca2f42b04f1413cf3557efe18a06.tar.xz
nixpkgs-93b17c1b4d29ca2f42b04f1413cf3557efe18a06.tar.zst
nixpkgs-93b17c1b4d29ca2f42b04f1413cf3557efe18a06.zip
Merge master into staging-next
-rw-r--r--doc/builders/fetchers.chapter.md4
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix17
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-aarch64.nix84
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix61
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix50
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix18
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image.nix247
-rw-r--r--nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix6
-rw-r--r--nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel-installer.nix6
-rw-r--r--nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel.nix7
-rw-r--r--nixos/modules/installer/sd-card/sd-image-aarch64.nix79
-rw-r--r--nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform-installer.nix6
-rw-r--r--nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform.nix56
-rw-r--r--nixos/modules/installer/sd-card/sd-image-raspberryp4-installer.nix6
-rw-r--r--nixos/modules/installer/sd-card/sd-image-raspberrypi-installer.nix6
-rw-r--r--nixos/modules/installer/sd-card/sd-image-raspberrypi.nix45
-rw-r--r--nixos/modules/installer/sd-card/sd-image-raspberrypi4.nix8
-rw-r--r--nixos/modules/installer/sd-card/sd-image.nix245
-rw-r--r--nixos/modules/services/networking/dnscrypt-proxy2.nix1
-rw-r--r--nixos/modules/services/ttys/kmscon.nix7
-rw-r--r--nixos/modules/services/x11/display-managers/gdm.nix12
-rw-r--r--nixos/release.nix10
-rw-r--r--pkgs/applications/networking/mailreaders/claws-mail/default.nix204
-rw-r--r--pkgs/applications/networking/mailreaders/claws-mail/gtk3.nix121
-rw-r--r--pkgs/build-support/fetchgithub/default.nix20
-rw-r--r--pkgs/development/ocaml-modules/qcheck/core.nix4
-rw-r--r--pkgs/development/ocaml-modules/stdint/default.nix10
-rw-r--r--pkgs/shells/nushell/default.nix6
-rw-r--r--pkgs/tools/nix/nix-output-monitor/default.nix6
-rw-r--r--pkgs/tools/security/jwt-cli/default.nix6
-rw-r--r--pkgs/top-level/all-packages.nix3
31 files changed, 716 insertions, 645 deletions
diff --git a/doc/builders/fetchers.chapter.md b/doc/builders/fetchers.chapter.md
index d4cab056c70..16e4baa966b 100644
--- a/doc/builders/fetchers.chapter.md
+++ b/doc/builders/fetchers.chapter.md
@@ -31,6 +31,8 @@ Used with Subversion. Expects `url` to a Subversion directory, `rev`, and `sha25
 
 Used with Git. Expects `url` to a Git repo, `rev`, and `sha256`. `rev` in this case can be full the git commit id (SHA1 hash) or a tag name like `refs/tags/v1.0`.
 
+Additionally the following optional arguments can be given: `fetchSubmodules = true` makes `fetchgit` also fetch the submodules of a repository. If `deepClone` is set to true, the entire repository is cloned as opposing to just creating a shallow clone. `deepClone = true` also implies `leaveDotGit = true` which means that the `.git` directory of the clone won't be removed after checkout.
+
 ## `fetchfossil`
 
 Used with Fossil. Expects `url` to a Fossil archive, `rev`, and `sha256`.
@@ -49,6 +51,8 @@ A number of fetcher functions wrap part of `fetchurl` and `fetchzip`. They are m
 
 `fetchFromGitHub` expects four arguments. `owner` is a string corresponding to the GitHub user or organization that controls this repository. `repo` corresponds to the name of the software repository. These are located at the top of every GitHub HTML page as `owner`/`repo`. `rev` corresponds to the Git commit hash or tag (e.g `v1.0`) that will be downloaded from Git. Finally, `sha256` corresponds to the hash of the extracted directory. Again, other hash algorithms are also available but `sha256` is currently preferred.
 
+`fetchFromGitHub` uses `fetchzip` to download the source archive generated by GitHub for the specified revision. If `leaveDotGit`, `deepClone` or `fetchSubmodules` are set to `true`, `fetchFromGitHub` will use `fetchgit` instead. Refer to its section for documentation of these options.
+
 ## `fetchFromGitLab`
 
 This is used with GitLab repositories. The arguments expected are very similar to fetchFromGitHub above.
diff --git a/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix b/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix
index 2882fbcc730..a669d61571f 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix
@@ -1,7 +1,14 @@
-{ pkgs, ... }:
-
+{ config, ... }:
 {
-  imports = [ ./sd-image-aarch64.nix ];
-
-  boot.kernelPackages = pkgs.linuxPackages_latest;
+  imports = [
+    ../sd-card/sd-image-aarch64-new-kernel-installer.nix
+  ];
+  config = {
+    warnings = [
+      ''
+      .../cd-dvd/sd-image-aarch64-new-kernel.nix is deprecated and will eventually be removed.
+      Please switch to .../sd-card/sd-image-aarch64-new-kernel-installer.nix, instead.
+      ''
+    ];
+  };
 }
diff --git a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
index e4ec2d6240d..76c1509b8f7 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix
@@ -1,80 +1,14 @@
-# To build, use:
-# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-aarch64.nix -A config.system.build.sdImage
-{ config, lib, pkgs, ... }:
-
+{ config, ... }:
 {
   imports = [
-    ../../profiles/base.nix
-    ../../profiles/installation-device.nix
-    ./sd-image.nix
+    ../sd-card/sd-image-aarch64-installer.nix
   ];
-
-  boot.loader.grub.enable = false;
-  boot.loader.generic-extlinux-compatible.enable = true;
-
-  boot.consoleLogLevel = lib.mkDefault 7;
-
-  # The serial ports listed here are:
-  # - ttyS0: for Tegra (Jetson TX1)
-  # - ttyAMA0: for QEMU's -machine virt
-  boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
-
-  boot.initrd.availableKernelModules = [
-    # Allows early (earlier) modesetting for the Raspberry Pi
-    "vc4" "bcm2835_dma" "i2c_bcm2835"
-    # Allows early (earlier) modesetting for Allwinner SoCs
-    "sun4i_drm" "sun8i_drm_hdmi" "sun8i_mixer"
-  ];
-
-  sdImage = {
-    populateFirmwareCommands = let
-      configTxt = pkgs.writeText "config.txt" ''
-        [pi3]
-        kernel=u-boot-rpi3.bin
-
-        [pi4]
-        kernel=u-boot-rpi4.bin
-        enable_gic=1
-        armstub=armstub8-gic.bin
-
-        # Otherwise the resolution will be weird in most cases, compared to
-        # what the pi3 firmware does by default.
-        disable_overscan=1
-
-        [all]
-        # Boot in 64-bit mode.
-        arm_64bit=1
-
-        # U-Boot needs this to work, regardless of whether UART is actually used or not.
-        # Look in arch/arm/mach-bcm283x/Kconfig in the U-Boot tree to see if this is still
-        # a requirement in the future.
-        enable_uart=1
-
-        # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
-        # when attempting to show low-voltage or overtemperature warnings.
-        avoid_warnings=1
-      '';
-      in ''
-        (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
-
-        # Add the config
-        cp ${configTxt} firmware/config.txt
-
-        # Add pi3 specific files
-        cp ${pkgs.ubootRaspberryPi3_64bit}/u-boot.bin firmware/u-boot-rpi3.bin
-
-        # Add pi4 specific files
-        cp ${pkgs.ubootRaspberryPi4_64bit}/u-boot.bin firmware/u-boot-rpi4.bin
-        cp ${pkgs.raspberrypi-armstubs}/armstub8-gic.bin firmware/armstub8-gic.bin
-        cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-4-b.dtb firmware/
-      '';
-    populateRootCommands = ''
-      mkdir -p ./files/boot
-      ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
-    '';
+  config = {
+    warnings = [
+      ''
+      .../cd-dvd/sd-image-aarch64.nix is deprecated and will eventually be removed.
+      Please switch to .../sd-card/sd-image-aarch64-installer.nix, instead.
+      ''
+    ];
   };
-
-  # the installation media is also the installation target,
-  # so we don't want to provide the installation configuration.nix.
-  installer.cloneConfig = false;
 }
diff --git a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
index d2ba611532e..6ee0eb9e9b8 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
@@ -1,57 +1,14 @@
-# To build, use:
-# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix -A config.system.build.sdImage
-{ config, lib, pkgs, ... }:
-
+{ config, ... }:
 {
   imports = [
-    ../../profiles/base.nix
-    ../../profiles/installation-device.nix
-    ./sd-image.nix
+    ../sd-card/sd-image-armv7l-multiplatform-installer.nix
   ];
-
-  boot.loader.grub.enable = false;
-  boot.loader.generic-extlinux-compatible.enable = true;
-
-  boot.consoleLogLevel = lib.mkDefault 7;
-  boot.kernelPackages = pkgs.linuxPackages_latest;
-  # The serial ports listed here are:
-  # - ttyS0: for Tegra (Jetson TK1)
-  # - ttymxc0: for i.MX6 (Wandboard)
-  # - ttyAMA0: for Allwinner (pcDuino3 Nano) and QEMU's -machine virt
-  # - ttyO0: for OMAP (BeagleBone Black)
-  # - ttySAC2: for Exynos (ODROID-XU3)
-  boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=ttyO0,115200n8" "console=ttySAC2,115200n8" "console=tty0"];
-
-  sdImage = {
-    populateFirmwareCommands = let
-      configTxt = pkgs.writeText "config.txt" ''
-        # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
-        # when attempting to show low-voltage or overtemperature warnings.
-        avoid_warnings=1
-
-        [pi2]
-        kernel=u-boot-rpi2.bin
-
-        [pi3]
-        kernel=u-boot-rpi3.bin
-
-        # U-Boot used to need this to work, regardless of whether UART is actually used or not.
-        # TODO: check when/if this can be removed.
-        enable_uart=1
-      '';
-      in ''
-        (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
-        cp ${pkgs.ubootRaspberryPi2}/u-boot.bin firmware/u-boot-rpi2.bin
-        cp ${pkgs.ubootRaspberryPi3_32bit}/u-boot.bin firmware/u-boot-rpi3.bin
-        cp ${configTxt} firmware/config.txt
-      '';
-    populateRootCommands = ''
-      mkdir -p ./files/boot
-      ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
-    '';
+  config = {
+    warnings = [
+      ''
+      .../cd-dvd/sd-image-armv7l-multiplatform.nix is deprecated and will eventually be removed.
+      Please switch to .../sd-card/sd-image-armv7l-multiplatform-installer.nix, instead.
+      ''
+    ];
   };
-
-  # the installation media is also the installation target,
-  # so we don't want to provide the installation configuration.nix.
-  installer.cloneConfig = false;
 }
diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
index 40a01f96177..747440ba9c6 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
@@ -1,46 +1,14 @@
-# To build, use:
-# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix -A config.system.build.sdImage
-{ config, lib, pkgs, ... }:
-
+{ config, ... }:
 {
   imports = [
-    ../../profiles/base.nix
-    ../../profiles/installation-device.nix
-    ./sd-image.nix
+    ../sd-card/sd-image-raspberrypi-installer.nix
   ];
-
-  boot.loader.grub.enable = false;
-  boot.loader.generic-extlinux-compatible.enable = true;
-
-  boot.consoleLogLevel = lib.mkDefault 7;
-  boot.kernelPackages = pkgs.linuxPackages_rpi1;
-
-  sdImage = {
-    populateFirmwareCommands = let
-      configTxt = pkgs.writeText "config.txt" ''
-        # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
-        # when attempting to show low-voltage or overtemperature warnings.
-        avoid_warnings=1
-
-        [pi0]
-        kernel=u-boot-rpi0.bin
-
-        [pi1]
-        kernel=u-boot-rpi1.bin
-      '';
-      in ''
-        (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
-        cp ${pkgs.ubootRaspberryPiZero}/u-boot.bin firmware/u-boot-rpi0.bin
-        cp ${pkgs.ubootRaspberryPi}/u-boot.bin firmware/u-boot-rpi1.bin
-        cp ${configTxt} firmware/config.txt
-      '';
-    populateRootCommands = ''
-      mkdir -p ./files/boot
-      ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
-    '';
+  config = {
+    warnings = [
+      ''
+      .../cd-dvd/sd-image-raspberrypi.nix is deprecated and will eventually be removed.
+      Please switch to .../sd-card/sd-image-raspberrypi-installer.nix, instead.
+      ''
+    ];
   };
-
-  # the installation media is also the installation target,
-  # so we don't want to provide the installation configuration.nix.
-  installer.cloneConfig = false;
 }
diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix
index 5bdec7de86e..79db1fa29bc 100644
--- a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix
@@ -1,8 +1,14 @@
-# To build, use:
-# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix -A config.system.build.sdImage
-{ config, lib, pkgs, ... }:
-
+{ config, ... }:
 {
-  imports = [ ./sd-image-aarch64.nix ];
-  boot.kernelPackages = pkgs.linuxPackages_rpi4;
+  imports = [
+    ../sd-card/sd-image-raspberrypi4-installer.nix
+  ];
+  config = {
+    warnings = [
+      ''
+      .../cd-dvd/sd-image-raspberrypi4.nix is deprecated and will eventually be removed.
+      Please switch to .../sd-card/sd-image-raspberrypi4-installer.nix, instead.
+      ''
+    ];
+  };
 }
diff --git a/nixos/modules/installer/cd-dvd/sd-image.nix b/nixos/modules/installer/cd-dvd/sd-image.nix
index b811ae07eb0..e2d6dcb3fe3 100644
--- a/nixos/modules/installer/cd-dvd/sd-image.nix
+++ b/nixos/modules/installer/cd-dvd/sd-image.nix
@@ -1,245 +1,14 @@
-# This module creates a bootable SD card image containing the given NixOS
-# configuration. The generated image is MBR partitioned, with a FAT
-# /boot/firmware partition, and ext4 root partition. The generated image
-# is sized to fit its contents, and a boot script automatically resizes
-# the root partition to fit the device on the first boot.
-#
-# The firmware partition is built with expectation to hold the Raspberry
-# Pi firmware and bootloader, and be removed and replaced with a firmware
-# build for the target SoC for other board families.
-#
-# The derivation for the SD image will be placed in
-# config.system.build.sdImage
-
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-  rootfsImage = pkgs.callPackage ../../../lib/make-ext4-fs.nix ({
-    inherit (config.sdImage) storePaths;
-    compressImage = true;
-    populateImageCommands = config.sdImage.populateRootCommands;
-    volumeLabel = "NIXOS_SD";
-  } // optionalAttrs (config.sdImage.rootPartitionUUID != null) {
-    uuid = config.sdImage.rootPartitionUUID;
-  });
-in
+{ config, ... }:
 {
   imports = [
-    (mkRemovedOptionModule [ "sdImage" "bootPartitionID" ] "The FAT partition for SD image now only holds the Raspberry Pi firmware files. Use firmwarePartitionID to configure that partition's ID.")
-    (mkRemovedOptionModule [ "sdImage" "bootSize" ] "The boot files for SD image have been moved to the main ext4 partition. The FAT partition now only holds the Raspberry Pi firmware files. Changing its size may not be required.")
+    ../sd-card/sd-image.nix
   ];
-
-  options.sdImage = {
-    imageName = mkOption {
-      default = "${config.sdImage.imageBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.img";
-      description = ''
-        Name of the generated image file.
-      '';
-    };
-
-    imageBaseName = mkOption {
-      default = "nixos-sd-image";
-      description = ''
-        Prefix of the name of the generated image file.
-      '';
-    };
-
-    storePaths = mkOption {
-      type = with types; listOf package;
-      example = literalExample "[ pkgs.stdenv ]";
-      description = ''
-        Derivations to be included in the Nix store in the generated SD image.
-      '';
-    };
-
-    firmwarePartitionID = mkOption {
-      type = types.str;
-      default = "0x2178694e";
-      description = ''
-        Volume ID for the /boot/firmware partition on the SD card. This value
-        must be a 32-bit hexadecimal number.
-      '';
-    };
-
-    firmwarePartitionName = mkOption {
-      type = types.str;
-      default = "FIRMWARE";
-      description = ''
-        Name of the filesystem which holds the boot firmware.
-      '';
-    };
-
-    rootPartitionUUID = mkOption {
-      type = types.nullOr types.str;
-      default = null;
-      example = "14e19a7b-0ae0-484d-9d54-43bd6fdc20c7";
-      description = ''
-        UUID for the filesystem on the main NixOS partition on the SD card.
-      '';
-    };
-
-    firmwareSize = mkOption {
-      type = types.int;
-      # As of 2019-08-18 the Raspberry pi firmware + u-boot takes ~18MiB
-      default = 30;
-      description = ''
-        Size of the /boot/firmware partition, in megabytes.
-      '';
-    };
-
-    populateFirmwareCommands = mkOption {
-      example = literalExample "'' cp \${pkgs.myBootLoader}/u-boot.bin firmware/ ''";
-      description = ''
-        Shell commands to populate the ./firmware directory.
-        All files in that directory are copied to the
-        /boot/firmware partition on the SD image.
-      '';
-    };
-
-    populateRootCommands = mkOption {
-      example = literalExample "''\${config.boot.loader.generic-extlinux-compatible.populateCmd} -c \${config.system.build.toplevel} -d ./files/boot''";
-      description = ''
-        Shell commands to populate the ./files directory.
-        All files in that directory are copied to the
-        root (/) partition on the SD image. Use this to
-        populate the ./files/boot (/boot) directory.
-      '';
-    };
-
-    postBuildCommands = mkOption {
-      example = literalExample "'' dd if=\${pkgs.myBootLoader}/SPL of=$img bs=1024 seek=1 conv=notrunc ''";
-      default = "";
-      description = ''
-        Shell commands to run after the image is built.
-        Can be used for boards requiring to dd u-boot SPL before actual partitions.
-      '';
-    };
-
-    compressImage = mkOption {
-      type = types.bool;
-      default = true;
-      description = ''
-        Whether the SD image should be compressed using
-        <command>zstd</command>.
-      '';
-    };
-
-  };
-
   config = {
-    fileSystems = {
-      "/boot/firmware" = {
-        device = "/dev/disk/by-label/${config.sdImage.firmwarePartitionName}";
-        fsType = "vfat";
-        # Alternatively, this could be removed from the configuration.
-        # The filesystem is not needed at runtime, it could be treated
-        # as an opaque blob instead of a discrete FAT32 filesystem.
-        options = [ "nofail" "noauto" ];
-      };
-      "/" = {
-        device = "/dev/disk/by-label/NIXOS_SD";
-        fsType = "ext4";
-      };
-    };
-
-    sdImage.storePaths = [ config.system.build.toplevel ];
-
-    system.build.sdImage = pkgs.callPackage ({ stdenv, dosfstools, e2fsprogs,
-    mtools, libfaketime, util-linux, zstd }: stdenv.mkDerivation {
-      name = config.sdImage.imageName;
-
-      nativeBuildInputs = [ dosfstools e2fsprogs mtools libfaketime util-linux zstd ];
-
-      inherit (config.sdImage) compressImage;
-
-      buildCommand = ''
-        mkdir -p $out/nix-support $out/sd-image
-        export img=$out/sd-image/${config.sdImage.imageName}
-
-        echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system
-        if test -n "$compressImage"; then
-          echo "file sd-image $img.zst" >> $out/nix-support/hydra-build-products
-        else
-          echo "file sd-image $img" >> $out/nix-support/hydra-build-products
-        fi
-
-        echo "Decompressing rootfs image"
-        zstd -d --no-progress "${rootfsImage}" -o ./root-fs.img
-
-        # Gap in front of the first partition, in MiB
-        gap=8
-
-        # Create the image file sized to fit /boot/firmware and /, plus slack for the gap.
-        rootSizeBlocks=$(du -B 512 --apparent-size ./root-fs.img | awk '{ print $1 }')
-        firmwareSizeBlocks=$((${toString config.sdImage.firmwareSize} * 1024 * 1024 / 512))
-        imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
-        truncate -s $imageSize $img
-
-        # type=b is 'W95 FAT32', type=83 is 'Linux'.
-        # The "bootable" partition is where u-boot will look file for the bootloader
-        # information (dtbs, extlinux.conf file).
-        sfdisk $img <<EOF
-            label: dos
-            label-id: ${config.sdImage.firmwarePartitionID}
-
-            start=''${gap}M, size=$firmwareSizeBlocks, type=b
-            start=$((gap + ${toString config.sdImage.firmwareSize}))M, type=83, bootable
-        EOF
-
-        # Copy the rootfs into the SD image
-        eval $(partx $img -o START,SECTORS --nr 2 --pairs)
-        dd conv=notrunc if=./root-fs.img of=$img seek=$START count=$SECTORS
-
-        # Create a FAT32 /boot/firmware partition of suitable size into firmware_part.img
-        eval $(partx $img -o START,SECTORS --nr 1 --pairs)
-        truncate -s $((SECTORS * 512)) firmware_part.img
-        faketime "1970-01-01 00:00:00" mkfs.vfat -i ${config.sdImage.firmwarePartitionID} -n ${config.sdImage.firmwarePartitionName} firmware_part.img
-
-        # Populate the files intended for /boot/firmware
-        mkdir firmware
-        ${config.sdImage.populateFirmwareCommands}
-
-        # Copy the populated /boot/firmware into the SD image
-        (cd firmware; mcopy -psvm -i ../firmware_part.img ./* ::)
-        # Verify the FAT partition before copying it.
-        fsck.vfat -vn firmware_part.img
-        dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
-
-        ${config.sdImage.postBuildCommands}
-
-        if test -n "$compressImage"; then
-            zstd -T$NIX_BUILD_CORES --rm $img
-        fi
-      '';
-    }) {};
-
-    boot.postBootCommands = ''
-      # On the first boot do some maintenance tasks
-      if [ -f /nix-path-registration ]; then
-        set -euo pipefail
-        set -x
-        # Figure out device names for the boot device and root filesystem.
-        rootPart=$(${pkgs.util-linux}/bin/findmnt -n -o SOURCE /)
-        bootDevice=$(lsblk -npo PKNAME $rootPart)
-        partNum=$(lsblk -npo MAJ:MIN $rootPart | ${pkgs.gawk}/bin/awk -F: '{print $2}')
-
-        # Resize the root partition and the filesystem to fit the disk
-        echo ",+," | sfdisk -N$partNum --no-reread $bootDevice
-        ${pkgs.parted}/bin/partprobe
-        ${pkgs.e2fsprogs}/bin/resize2fs $rootPart
-
-        # Register the contents of the initial Nix store
-        ${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration
-
-        # nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
-        touch /etc/NIXOS
-        ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
-
-        # Prevents this from running on later boots.
-        rm -f /nix-path-registration
-      fi
-    '';
+    warnings = [
+      ''
+      .../cd-dvd/sd-image.nix is deprecated and will eventually be removed.
+      Please switch to .../sd-card/sd-image.nix, instead.
+      ''
+    ];
   };
 }
diff --git a/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix b/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix
new file mode 100644
index 00000000000..b9e8a3ec81f
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix
@@ -0,0 +1,6 @@
+{
+  imports = [
+    ../../profiles/installation-device.nix
+    ./sd-image-aarch64.nix
+  ];
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel-installer.nix b/nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel-installer.nix
new file mode 100644
index 00000000000..fdb6da31f4c
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel-installer.nix
@@ -0,0 +1,6 @@
+{
+  imports = [
+    ../../profiles/installation-device.nix
+    ./sd-image-aarch64-new-kernel.nix
+  ];
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel.nix b/nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel.nix
new file mode 100644
index 00000000000..2882fbcc730
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel.nix
@@ -0,0 +1,7 @@
+{ pkgs, ... }:
+
+{
+  imports = [ ./sd-image-aarch64.nix ];
+
+  boot.kernelPackages = pkgs.linuxPackages_latest;
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-aarch64.nix b/nixos/modules/installer/sd-card/sd-image-aarch64.nix
new file mode 100644
index 00000000000..ea696cbbc71
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-aarch64.nix
@@ -0,0 +1,79 @@
+# To build, use:
+# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-aarch64.nix -A config.system.build.sdImage
+{ config, lib, pkgs, ... }:
+
+{
+  imports = [
+    ../../profiles/base.nix
+    ./sd-image.nix
+  ];
+
+  boot.loader.grub.enable = false;
+  boot.loader.generic-extlinux-compatible.enable = true;
+
+  boot.consoleLogLevel = lib.mkDefault 7;
+
+  # The serial ports listed here are:
+  # - ttyS0: for Tegra (Jetson TX1)
+  # - ttyAMA0: for QEMU's -machine virt
+  boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
+
+  boot.initrd.availableKernelModules = [
+    # Allows early (earlier) modesetting for the Raspberry Pi
+    "vc4" "bcm2835_dma" "i2c_bcm2835"
+    # Allows early (earlier) modesetting for Allwinner SoCs
+    "sun4i_drm" "sun8i_drm_hdmi" "sun8i_mixer"
+  ];
+
+  sdImage = {
+    populateFirmwareCommands = let
+      configTxt = pkgs.writeText "config.txt" ''
+        [pi3]
+        kernel=u-boot-rpi3.bin
+
+        [pi4]
+        kernel=u-boot-rpi4.bin
+        enable_gic=1
+        armstub=armstub8-gic.bin
+
+        # Otherwise the resolution will be weird in most cases, compared to
+        # what the pi3 firmware does by default.
+        disable_overscan=1
+
+        [all]
+        # Boot in 64-bit mode.
+        arm_64bit=1
+
+        # U-Boot needs this to work, regardless of whether UART is actually used or not.
+        # Look in arch/arm/mach-bcm283x/Kconfig in the U-Boot tree to see if this is still
+        # a requirement in the future.
+        enable_uart=1
+
+        # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
+        # when attempting to show low-voltage or overtemperature warnings.
+        avoid_warnings=1
+      '';
+      in ''
+        (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
+
+        # Add the config
+        cp ${configTxt} firmware/config.txt
+
+        # Add pi3 specific files
+        cp ${pkgs.ubootRaspberryPi3_64bit}/u-boot.bin firmware/u-boot-rpi3.bin
+
+        # Add pi4 specific files
+        cp ${pkgs.ubootRaspberryPi4_64bit}/u-boot.bin firmware/u-boot-rpi4.bin
+        cp ${pkgs.raspberrypi-armstubs}/armstub8-gic.bin firmware/armstub8-gic.bin
+        cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/bcm2711-rpi-4-b.dtb firmware/
+      '';
+    populateRootCommands = ''
+      mkdir -p ./files/boot
+      ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
+    '';
+  };
+
+  # the installation media is also the installation target,
+  # so we don't want to provide the installation configuration.nix.
+  installer.cloneConfig = false;
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform-installer.nix b/nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform-installer.nix
new file mode 100644
index 00000000000..36b59b1ef93
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform-installer.nix
@@ -0,0 +1,6 @@
+{
+  imports = [
+    ../../profiles/installation-device.nix
+    ./sd-image-armv7l-multiplatform.nix
+  ];
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform.nix
new file mode 100644
index 00000000000..08f2fbaaaf2
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform.nix
@@ -0,0 +1,56 @@
+# To build, use:
+# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix -A config.system.build.sdImage
+{ config, lib, pkgs, ... }:
+
+{
+  imports = [
+    ../../profiles/base.nix
+    ./sd-image.nix
+  ];
+
+  boot.loader.grub.enable = false;
+  boot.loader.generic-extlinux-compatible.enable = true;
+
+  boot.consoleLogLevel = lib.mkDefault 7;
+  boot.kernelPackages = pkgs.linuxPackages_latest;
+  # The serial ports listed here are:
+  # - ttyS0: for Tegra (Jetson TK1)
+  # - ttymxc0: for i.MX6 (Wandboard)
+  # - ttyAMA0: for Allwinner (pcDuino3 Nano) and QEMU's -machine virt
+  # - ttyO0: for OMAP (BeagleBone Black)
+  # - ttySAC2: for Exynos (ODROID-XU3)
+  boot.kernelParams = ["console=ttyS0,115200n8" "console=ttymxc0,115200n8" "console=ttyAMA0,115200n8" "console=ttyO0,115200n8" "console=ttySAC2,115200n8" "console=tty0"];
+
+  sdImage = {
+    populateFirmwareCommands = let
+      configTxt = pkgs.writeText "config.txt" ''
+        # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
+        # when attempting to show low-voltage or overtemperature warnings.
+        avoid_warnings=1
+
+        [pi2]
+        kernel=u-boot-rpi2.bin
+
+        [pi3]
+        kernel=u-boot-rpi3.bin
+
+        # U-Boot used to need this to work, regardless of whether UART is actually used or not.
+        # TODO: check when/if this can be removed.
+        enable_uart=1
+      '';
+      in ''
+        (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
+        cp ${pkgs.ubootRaspberryPi2}/u-boot.bin firmware/u-boot-rpi2.bin
+        cp ${pkgs.ubootRaspberryPi3_32bit}/u-boot.bin firmware/u-boot-rpi3.bin
+        cp ${configTxt} firmware/config.txt
+      '';
+    populateRootCommands = ''
+      mkdir -p ./files/boot
+      ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
+    '';
+  };
+
+  # the installation media is also the installation target,
+  # so we don't want to provide the installation configuration.nix.
+  installer.cloneConfig = false;
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-raspberryp4-installer.nix b/nixos/modules/installer/sd-card/sd-image-raspberryp4-installer.nix
new file mode 100644
index 00000000000..8f2715569be
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-raspberryp4-installer.nix
@@ -0,0 +1,6 @@
+{
+  imports = [
+    ../../profiles/installation-device.nix
+    ./sd-image-raspberrypi4.nix
+  ];
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-raspberrypi-installer.nix b/nixos/modules/installer/sd-card/sd-image-raspberrypi-installer.nix
new file mode 100644
index 00000000000..6bfbeb3cfcd
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-raspberrypi-installer.nix
@@ -0,0 +1,6 @@
+{
+  imports = [
+    ../../profiles/installation-device.nix
+    ./sd-image-raspberrypi.nix
+  ];
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-raspberrypi.nix b/nixos/modules/installer/sd-card/sd-image-raspberrypi.nix
new file mode 100644
index 00000000000..d16d2d0fa28
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-raspberrypi.nix
@@ -0,0 +1,45 @@
+# To build, use:
+# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix -A config.system.build.sdImage
+{ config, lib, pkgs, ... }:
+
+{
+  imports = [
+    ../../profiles/base.nix
+    ./sd-image.nix
+  ];
+
+  boot.loader.grub.enable = false;
+  boot.loader.generic-extlinux-compatible.enable = true;
+
+  boot.consoleLogLevel = lib.mkDefault 7;
+  boot.kernelPackages = pkgs.linuxPackages_rpi1;
+
+  sdImage = {
+    populateFirmwareCommands = let
+      configTxt = pkgs.writeText "config.txt" ''
+        # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
+        # when attempting to show low-voltage or overtemperature warnings.
+        avoid_warnings=1
+
+        [pi0]
+        kernel=u-boot-rpi0.bin
+
+        [pi1]
+        kernel=u-boot-rpi1.bin
+      '';
+      in ''
+        (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
+        cp ${pkgs.ubootRaspberryPiZero}/u-boot.bin firmware/u-boot-rpi0.bin
+        cp ${pkgs.ubootRaspberryPi}/u-boot.bin firmware/u-boot-rpi1.bin
+        cp ${configTxt} firmware/config.txt
+      '';
+    populateRootCommands = ''
+      mkdir -p ./files/boot
+      ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
+    '';
+  };
+
+  # the installation media is also the installation target,
+  # so we don't want to provide the installation configuration.nix.
+  installer.cloneConfig = false;
+}
diff --git a/nixos/modules/installer/sd-card/sd-image-raspberrypi4.nix b/nixos/modules/installer/sd-card/sd-image-raspberrypi4.nix
new file mode 100644
index 00000000000..5bdec7de86e
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image-raspberrypi4.nix
@@ -0,0 +1,8 @@
+# To build, use:
+# nix-build nixos -I nixos-config=nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix -A config.system.build.sdImage
+{ config, lib, pkgs, ... }:
+
+{
+  imports = [ ./sd-image-aarch64.nix ];
+  boot.kernelPackages = pkgs.linuxPackages_rpi4;
+}
diff --git a/nixos/modules/installer/sd-card/sd-image.nix b/nixos/modules/installer/sd-card/sd-image.nix
new file mode 100644
index 00000000000..b811ae07eb0
--- /dev/null
+++ b/nixos/modules/installer/sd-card/sd-image.nix
@@ -0,0 +1,245 @@
+# This module creates a bootable SD card image containing the given NixOS
+# configuration. The generated image is MBR partitioned, with a FAT
+# /boot/firmware partition, and ext4 root partition. The generated image
+# is sized to fit its contents, and a boot script automatically resizes
+# the root partition to fit the device on the first boot.
+#
+# The firmware partition is built with expectation to hold the Raspberry
+# Pi firmware and bootloader, and be removed and replaced with a firmware
+# build for the target SoC for other board families.
+#
+# The derivation for the SD image will be placed in
+# config.system.build.sdImage
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  rootfsImage = pkgs.callPackage ../../../lib/make-ext4-fs.nix ({
+    inherit (config.sdImage) storePaths;
+    compressImage = true;
+    populateImageCommands = config.sdImage.populateRootCommands;
+    volumeLabel = "NIXOS_SD";
+  } // optionalAttrs (config.sdImage.rootPartitionUUID != null) {
+    uuid = config.sdImage.rootPartitionUUID;
+  });
+in
+{
+  imports = [
+    (mkRemovedOptionModule [ "sdImage" "bootPartitionID" ] "The FAT partition for SD image now only holds the Raspberry Pi firmware files. Use firmwarePartitionID to configure that partition's ID.")
+    (mkRemovedOptionModule [ "sdImage" "bootSize" ] "The boot files for SD image have been moved to the main ext4 partition. The FAT partition now only holds the Raspberry Pi firmware files. Changing its size may not be required.")
+  ];
+
+  options.sdImage = {
+    imageName = mkOption {
+      default = "${config.sdImage.imageBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.img";
+      description = ''
+        Name of the generated image file.
+      '';
+    };
+
+    imageBaseName = mkOption {
+      default = "nixos-sd-image";
+      description = ''
+        Prefix of the name of the generated image file.
+      '';
+    };
+
+    storePaths = mkOption {
+      type = with types; listOf package;
+      example = literalExample "[ pkgs.stdenv ]";
+      description = ''
+        Derivations to be included in the Nix store in the generated SD image.
+      '';
+    };
+
+    firmwarePartitionID = mkOption {
+      type = types.str;
+      default = "0x2178694e";
+      description = ''
+        Volume ID for the /boot/firmware partition on the SD card. This value
+        must be a 32-bit hexadecimal number.
+      '';
+    };
+
+    firmwarePartitionName = mkOption {
+      type = types.str;
+      default = "FIRMWARE";
+      description = ''
+        Name of the filesystem which holds the boot firmware.
+      '';
+    };
+
+    rootPartitionUUID = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      example = "14e19a7b-0ae0-484d-9d54-43bd6fdc20c7";
+      description = ''
+        UUID for the filesystem on the main NixOS partition on the SD card.
+      '';
+    };
+
+    firmwareSize = mkOption {
+      type = types.int;
+      # As of 2019-08-18 the Raspberry pi firmware + u-boot takes ~18MiB
+      default = 30;
+      description = ''
+        Size of the /boot/firmware partition, in megabytes.
+      '';
+    };
+
+    populateFirmwareCommands = mkOption {
+      example = literalExample "'' cp \${pkgs.myBootLoader}/u-boot.bin firmware/ ''";
+      description = ''
+        Shell commands to populate the ./firmware directory.
+        All files in that directory are copied to the
+        /boot/firmware partition on the SD image.
+      '';
+    };
+
+    populateRootCommands = mkOption {
+      example = literalExample "''\${config.boot.loader.generic-extlinux-compatible.populateCmd} -c \${config.system.build.toplevel} -d ./files/boot''";
+      description = ''
+        Shell commands to populate the ./files directory.
+        All files in that directory are copied to the
+        root (/) partition on the SD image. Use this to
+        populate the ./files/boot (/boot) directory.
+      '';
+    };
+
+    postBuildCommands = mkOption {
+      example = literalExample "'' dd if=\${pkgs.myBootLoader}/SPL of=$img bs=1024 seek=1 conv=notrunc ''";
+      default = "";
+      description = ''
+        Shell commands to run after the image is built.
+        Can be used for boards requiring to dd u-boot SPL before actual partitions.
+      '';
+    };
+
+    compressImage = mkOption {
+      type = types.bool;
+      default = true;
+      description = ''
+        Whether the SD image should be compressed using
+        <command>zstd</command>.
+      '';
+    };
+
+  };
+
+  config = {
+    fileSystems = {
+      "/boot/firmware" = {
+        device = "/dev/disk/by-label/${config.sdImage.firmwarePartitionName}";
+        fsType = "vfat";
+        # Alternatively, this could be removed from the configuration.
+        # The filesystem is not needed at runtime, it could be treated
+        # as an opaque blob instead of a discrete FAT32 filesystem.
+        options = [ "nofail" "noauto" ];
+      };
+      "/" = {
+        device = "/dev/disk/by-label/NIXOS_SD";
+        fsType = "ext4";
+      };
+    };
+
+    sdImage.storePaths = [ config.system.build.toplevel ];
+
+    system.build.sdImage = pkgs.callPackage ({ stdenv, dosfstools, e2fsprogs,
+    mtools, libfaketime, util-linux, zstd }: stdenv.mkDerivation {
+      name = config.sdImage.imageName;
+
+      nativeBuildInputs = [ dosfstools e2fsprogs mtools libfaketime util-linux zstd ];
+
+      inherit (config.sdImage) compressImage;
+
+      buildCommand = ''
+        mkdir -p $out/nix-support $out/sd-image
+        export img=$out/sd-image/${config.sdImage.imageName}
+
+        echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system
+        if test -n "$compressImage"; then
+          echo "file sd-image $img.zst" >> $out/nix-support/hydra-build-products
+        else
+          echo "file sd-image $img" >> $out/nix-support/hydra-build-products
+        fi
+
+        echo "Decompressing rootfs image"
+        zstd -d --no-progress "${rootfsImage}" -o ./root-fs.img
+
+        # Gap in front of the first partition, in MiB
+        gap=8
+
+        # Create the image file sized to fit /boot/firmware and /, plus slack for the gap.
+        rootSizeBlocks=$(du -B 512 --apparent-size ./root-fs.img | awk '{ print $1 }')
+        firmwareSizeBlocks=$((${toString config.sdImage.firmwareSize} * 1024 * 1024 / 512))
+        imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
+        truncate -s $imageSize $img
+
+        # type=b is 'W95 FAT32', type=83 is 'Linux'.
+        # The "bootable" partition is where u-boot will look file for the bootloader
+        # information (dtbs, extlinux.conf file).
+        sfdisk $img <<EOF
+            label: dos
+            label-id: ${config.sdImage.firmwarePartitionID}
+
+            start=''${gap}M, size=$firmwareSizeBlocks, type=b
+            start=$((gap + ${toString config.sdImage.firmwareSize}))M, type=83, bootable
+        EOF
+
+        # Copy the rootfs into the SD image
+        eval $(partx $img -o START,SECTORS --nr 2 --pairs)
+        dd conv=notrunc if=./root-fs.img of=$img seek=$START count=$SECTORS
+
+        # Create a FAT32 /boot/firmware partition of suitable size into firmware_part.img
+        eval $(partx $img -o START,SECTORS --nr 1 --pairs)
+        truncate -s $((SECTORS * 512)) firmware_part.img
+        faketime "1970-01-01 00:00:00" mkfs.vfat -i ${config.sdImage.firmwarePartitionID} -n ${config.sdImage.firmwarePartitionName} firmware_part.img
+
+        # Populate the files intended for /boot/firmware
+        mkdir firmware
+        ${config.sdImage.populateFirmwareCommands}
+
+        # Copy the populated /boot/firmware into the SD image
+        (cd firmware; mcopy -psvm -i ../firmware_part.img ./* ::)
+        # Verify the FAT partition before copying it.
+        fsck.vfat -vn firmware_part.img
+        dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
+
+        ${config.sdImage.postBuildCommands}
+
+        if test -n "$compressImage"; then
+            zstd -T$NIX_BUILD_CORES --rm $img
+        fi
+      '';
+    }) {};
+
+    boot.postBootCommands = ''
+      # On the first boot do some maintenance tasks
+      if [ -f /nix-path-registration ]; then
+        set -euo pipefail
+        set -x
+        # Figure out device names for the boot device and root filesystem.
+        rootPart=$(${pkgs.util-linux}/bin/findmnt -n -o SOURCE /)
+        bootDevice=$(lsblk -npo PKNAME $rootPart)
+        partNum=$(lsblk -npo MAJ:MIN $rootPart | ${pkgs.gawk}/bin/awk -F: '{print $2}')
+
+        # Resize the root partition and the filesystem to fit the disk
+        echo ",+," | sfdisk -N$partNum --no-reread $bootDevice
+        ${pkgs.parted}/bin/partprobe
+        ${pkgs.e2fsprogs}/bin/resize2fs $rootPart
+
+        # Register the contents of the initial Nix store
+        ${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration
+
+        # nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
+        touch /etc/NIXOS
+        ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
+
+        # Prevents this from running on later boots.
+        rm -f /nix-path-registration
+      fi
+    '';
+  };
+}
diff --git a/nixos/modules/services/networking/dnscrypt-proxy2.nix b/nixos/modules/services/networking/dnscrypt-proxy2.nix
index afc2a6d1c75..72965c267a8 100644
--- a/nixos/modules/services/networking/dnscrypt-proxy2.nix
+++ b/nixos/modules/services/networking/dnscrypt-proxy2.nix
@@ -113,7 +113,6 @@ in
           "~@memlock"
           "~@resources"
           "~@setuid"
-          "~@sync"
           "~@timer"
         ];
       };
diff --git a/nixos/modules/services/ttys/kmscon.nix b/nixos/modules/services/ttys/kmscon.nix
index dc37f9bee4b..4fe720bf044 100644
--- a/nixos/modules/services/ttys/kmscon.nix
+++ b/nixos/modules/services/ttys/kmscon.nix
@@ -82,11 +82,8 @@ in {
       X-RestartIfChanged=false
     '';
 
-    systemd.units."autovt@.service".unit = pkgs.runCommand "unit" { preferLocalBuild = true; }
-        ''
-          mkdir -p $out
-          ln -s ${config.systemd.units."kmsconvt@.service".unit}/kmsconvt@.service $out/autovt@.service
-        '';
+    systemd.suppressedSystemUnits = [ "autovt@.service" ];
+    systemd.units."kmsconvt@.service".aliases = [ "autovt@.service" ];
 
     systemd.services.systemd-vconsole-setup.enable = false;
 
diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix
index e3c5adb9737..f79eb64b5a6 100644
--- a/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixos/modules/services/x11/display-managers/gdm.nix
@@ -183,14 +183,20 @@ in
       "systemd-udev-settle.service"
     ];
     systemd.services.display-manager.conflicts = [
-       "getty@tty${gdm.initialVT}.service"
-       # TODO: Add "plymouth-quit.service" so GDM can control when plymouth quits.
-       # Currently this breaks switching configurations while using plymouth.
+      "getty@tty${gdm.initialVT}.service"
+      "plymouth-quit.service"
     ];
     systemd.services.display-manager.onFailure = [
       "plymouth-quit.service"
     ];
 
+    # Prevent nixos-rebuild switch from bringing down the graphical
+    # session. (If multi-user.target wants plymouth-quit.service which
+    # conflicts display-manager.service, then when nixos-rebuild
+    # switch starts multi-user.target, display-manager.service is
+    # stopped so plymouth-quit.service can be started.)
+    systemd.services.plymouth-quit.wantedBy = lib.mkForce [];
+
     systemd.services.display-manager.serviceConfig = {
       # Restart = "always"; - already defined in xserver.nix
       KillMode = "mixed";
diff --git a/nixos/release.nix b/nixos/release.nix
index 109747945f7..327a259de7f 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -171,23 +171,23 @@ in rec {
 
   sd_image = forMatchingSystems [ "armv6l-linux" "armv7l-linux" "aarch64-linux" ] (system: makeSdImage {
     module = {
-        armv6l-linux = ./modules/installer/cd-dvd/sd-image-raspberrypi.nix;
-        armv7l-linux = ./modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix;
-        aarch64-linux = ./modules/installer/cd-dvd/sd-image-aarch64.nix;
+        armv6l-linux = ./modules/installer/sd-card/sd-image-raspberrypi-installer.nix;
+        armv7l-linux = ./modules/installer/sd-card/sd-image-armv7l-multiplatform-installer.nix;
+        aarch64-linux = ./modules/installer/sd-card/sd-image-aarch64-installer.nix;
       }.${system};
     inherit system;
   });
 
   sd_image_new_kernel = forMatchingSystems [ "aarch64-linux" ] (system: makeSdImage {
     module = {
-        aarch64-linux = ./modules/installer/cd-dvd/sd-image-aarch64-new-kernel.nix;
+        aarch64-linux = ./modules/installer/sd-card/sd-image-aarch64-new-kernel-installer.nix;
       }.${system};
     type = "minimal-new-kernel";
     inherit system;
   });
 
   sd_image_raspberrypi4 = forMatchingSystems [ "aarch64-linux" ] (system: makeSdImage {
-    module = ./modules/installer/cd-dvd/sd-image-raspberrypi4.nix;
+    module = ./modules/installer/sd-card/sd-image-raspberrypi4-installer.nix;
     inherit system;
   });
 
diff --git a/pkgs/applications/networking/mailreaders/claws-mail/default.nix b/pkgs/applications/networking/mailreaders/claws-mail/default.nix
index 7eaefdd91c4..a9cea58902a 100644
--- a/pkgs/applications/networking/mailreaders/claws-mail/default.nix
+++ b/pkgs/applications/networking/mailreaders/claws-mail/default.nix
@@ -1,52 +1,135 @@
-{ lib, config, fetchurl, stdenv, wrapGAppsHook, autoreconfHook
-, curl, dbus, dbus-glib, enchant, gtk2, gnutls, gnupg, gpgme, gumbo
-, libarchive, libcanberra-gtk2, libetpan, libnotify, libsoup, libxml2, networkmanager
-, openldap, perl, pkg-config, poppler, python, shared-mime-info
-, glib-networking, gsettings-desktop-schemas, libSM, libytnef, libical
-# Build options
-# TODO: A flag to build the manual.
-# TODO: Plugins that complain about their missing dependencies, even when
-#       provided:
-#         gdata requires libgdata
-#         geolocation requires libchamplain
-, enableLdap ? false
-, enableNetworkManager ? config.networking.networkmanager.enable or false
+{ stdenv, lib, fetchgit, wrapGAppsHook, autoreconfHook, bison, flex
+, curl, gtk2, gtk3, pkg-config, python2, python3, shared-mime-info
+, glib-networking, gsettings-desktop-schemas
+
+# Use the experimental gtk3 branch.
+, useGtk3 ? false
+
+# Package compatibility: old parameters whose name were not directly derived
 , enablePgp ? true
-, enablePluginArchive ? false
-, enablePluginLitehtmlViewer ? false
 , enablePluginNotificationDialogs ? true
 , enablePluginNotificationSounds ? true
-, enablePluginPdf ? false
-, enablePluginPython ? false
-, enablePluginRavatar ? false
-, enablePluginRssyl ? false
-, enablePluginSmime ? false
-, enablePluginSpamassassin ? false
-, enablePluginSpamReport ? false
-, enablePluginVcalendar ? false
-, enableSpellcheck ? false
+, enablePluginPdf ? true
+, enablePluginRavatar ? true
+, enableSpellcheck ? true
+
+# Arguments to include external libraries
+, enableLibSM ? true, libSM
+, enableGnuTLS ? true, gnutls
+, enableEnchant ? enableSpellcheck, enchant
+, enableDbus ? true, dbus, dbus-glib
+, enableLdap ? true, openldap
+, enableNetworkManager ? true, networkmanager
+, enableLibetpan ? true, libetpan
+, enableValgrind ? true, valgrind
+, enableSvg ? true, librsvg
+
+# Configure claws-mail's plugins
+, enablePluginAcpiNotifier ? true
+, enablePluginAddressKeeper ? true
+, enablePluginArchive ? true, libarchive
+, enablePluginAttRemover ? true
+, enablePluginAttachWarner ? true
+, enablePluginBogofilter ? true
+, enablePluginBsfilter ? true
+, enablePluginClamd ? true
+, enablePluginDillo ? true
+, enablePluginFetchInfo ? true
+, enablePluginLibravatar ? enablePluginRavatar
+, enablePluginLitehtmlViewer ? true, gumbo
+, enablePluginMailmbox ? true
+, enablePluginManageSieve ? true
+, enablePluginNewMail ? true
+, enablePluginNotification ? (enablePluginNotificationDialogs || enablePluginNotificationSounds), libcanberra-gtk2, libcanberra-gtk3, libnotify
+, enablePluginPdfViewer ? enablePluginPdf, poppler
+, enablePluginPerl ? true, perl
+, enablePluginPython ? true
+, enablePluginPgp ? enablePgp, gnupg, gpgme
+, enablePluginRssyl ? true, libxml2
+, enablePluginSmime ? true
+, enablePluginSpamassassin ? true
+, enablePluginSpamReport ? true
+, enablePluginTnefParse ? true, libytnef
+, enablePluginVcalendar ? true, libical
 }:
 
 with lib;
 
-stdenv.mkDerivation rec {
-  pname = "claws-mail";
-  version = "3.17.8";
+let
+  version = if useGtk3 then "3.99.0" else "3.17.8";
 
-  src = fetchurl {
-    url = "https://www.claws-mail.org/download.php?file=releases/claws-mail-${version}.tar.xz";
-    sha256 = "sha256-zbeygUmV1vSpw7HwvBRn7Vw88qXg2hcwqqJaisyv3a8=";
+  # The official release uses gtk2 and contains the version tag.
+  gtk2src = {
+    sha256 = "0l4f8q11iyj8pi120lrapgq51k5j64xf0jlczkzbm99rym752ch5";
   };
 
-  outputs = [ "out" "dev" ];
+  # The corresponding commit in the gtk3 branch.
+  gtk3src = {
+    sha256 = "176h1swh1zx6dqyzfz470x4a1xicnv0zhy8ir47k7p23g6y17i2k";
+  };
+
+  python = if useGtk3 then python3 else python2;
+  pythonPkgs = if useGtk3
+    then
+      with python.pkgs; [ python wrapPython pygobject3 ]
+    else
+      with python.pkgs; [ python wrapPython pygtk pygobject2 ];
 
-  patches = [
-    ./mime.patch
+  features = [
+    { flags = [ "acpi_notifier-plugin" ]; enabled = enablePluginAcpiNotifier; }
+    { flags = [ "address_keeper-plugin" ]; enabled = enablePluginAddressKeeper; }
+    { flags = [ "archive-plugin" ]; enabled = enablePluginArchive; deps = [ libarchive ]; }
+    { flags = [ "att_remover-plugin" ]; enabled = enablePluginAttRemover; }
+    { flags = [ "attachwarner-plugin" ]; enabled = enablePluginAttachWarner; }
+    { flags = [ "bogofilter-plugin" ]; enabled = enablePluginBogofilter; }
+    { flags = [ "bsfilter-plugin" ]; enabled = enablePluginBsfilter; }
+    { flags = [ "clamd-plugin" ]; enabled = enablePluginClamd; }
+    { flags = [ "dbus" ]; enabled = enableDbus; deps = [ dbus dbus-glib ]; }
+    { flags = [ "dillo-plugin" ]; enabled = enablePluginDillo; }
+    { flags = [ "enchant" ]; enabled = enableEnchant; deps = [ enchant ]; }
+    { flags = [ "fetchinfo-plugin" ]; enabled = enablePluginFetchInfo; }
+    { flags = [ "gnutls" ]; enabled = enableGnuTLS; deps = [ gnutls ]; }
+    { flags = [ "ldap" ]; enabled = enableLdap; deps = [ openldap ]; }
+    { flags = [ "libetpan" ]; enabled = enableLibetpan; deps = [ libetpan ]; }
+    { flags = [ "libravatar-plugin" ]; enabled = enablePluginLibravatar; }
+    { flags = [ "libsm" ]; enabled = enableLibSM; deps = [ libSM ]; }
+    { flags = [ "litehtml_viewer-plugin" ]; enabled = enablePluginLitehtmlViewer; deps = [ gumbo ]; }
+    { flags = [ "mailmbox-plugin" ]; enabled = enablePluginMailmbox; }
+    { flags = [ "managesieve-plugin" ]; enabled = enablePluginManageSieve; }
+    { flags = [ "networkmanager" ]; enabled = enableNetworkManager; deps = [ networkmanager ]; }
+    { flags = [ "newmail-plugin" ]; enabled = enablePluginNewMail; }
+    { flags = [ "notification-plugin" ]; enabled = enablePluginNotification; deps = [ libnotify ] ++ [(if useGtk3 then libcanberra-gtk3 else libcanberra-gtk2)]; }
+    { flags = [ "pdf_viewer-plugin" ]; enabled = enablePluginPdfViewer; deps = [ poppler ]; }
+    { flags = [ "perl-plugin" ]; enabled = enablePluginPerl; deps = [ perl ]; }
+    { flags = [ "pgpcore-plugin" "pgpinline-plugin" "pgpmime-plugin" ]; enabled = enablePluginPgp; deps = [ gnupg gpgme ]; }
+    { flags = [ "python-plugin" ]; enabled = enablePluginPython; }
+    { flags = [ "rssyl-plugin" ]; enabled = enablePluginRssyl; deps = [ libxml2 ]; }
+    { flags = [ "smime-plugin" ]; enabled = enablePluginSmime; }
+    { flags = [ "spam_report-plugin" ]; enabled = enablePluginSpamReport; }
+    { flags = [ "spamassassin-plugin" ]; enabled = enablePluginSpamassassin; }
+    { flags = [ "svg" ]; enabled = enableSvg; deps = [ librsvg ]; }
+    { flags = [ "tnef_parse-plugin" ]; enabled = enablePluginTnefParse; deps = [ libytnef ]; }
+    { flags = [ "valgrind" ]; enabled = enableValgrind; deps = [ valgrind ]; }
+    { flags = [ "vcalendar-plugin" ]; enabled = enablePluginVcalendar; deps = [ libical ]; }
   ];
+in stdenv.mkDerivation rec {
+  pname = "claws-mail";
+  inherit version;
+
+  src = fetchgit ({
+    rev = version;
+    url = "git://git.claws-mail.org/claws.git";
+  } // (if useGtk3 then gtk3src else gtk2src));
+
+  outputs = [ "out" "dev" ];
+
+  patches = [ ./mime.patch ];
 
   preConfigure = ''
     # autotools check tries to dlopen libpython as a requirement for the python plugin
     export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${python}/lib
+    # generate version without .git
+    [ -e version ] || echo "echo ${version}" > version
   '';
 
   postPatch = ''
@@ -54,51 +137,30 @@ stdenv.mkDerivation rec {
         --subst-var-by MIMEROOTDIR ${shared-mime-info}/share
   '';
 
-  nativeBuildInputs = [ autoreconfHook pkg-config wrapGAppsHook python.pkgs.wrapPython ];
-  propagatedBuildInputs = with python.pkgs; [ python ] ++ optionals enablePluginPython [ pygtk pygobject2 ];
+  nativeBuildInputs = [ autoreconfHook pkg-config bison flex wrapGAppsHook ];
+  propagatedBuildInputs = pythonPkgs;
 
   buildInputs =
-    [ curl dbus dbus-glib gtk2 gnutls gsettings-desktop-schemas
-      libetpan perl glib-networking libSM libytnef
-    ]
-    ++ optional enableSpellcheck enchant
-    ++ optionals (enablePgp || enablePluginSmime) [ gnupg gpgme ]
-    ++ optional enablePluginArchive libarchive
-    ++ optional enablePluginNotificationSounds libcanberra-gtk2
-    ++ optional enablePluginNotificationDialogs libnotify
-    ++ optional enablePluginLitehtmlViewer gumbo
-    ++ optional enablePluginRssyl libxml2
-    ++ optional enableNetworkManager networkmanager
-    ++ optional enableLdap openldap
-    ++ optional enablePluginPdf poppler
-    ++ optional enablePluginVcalendar libical;
+    [ curl gsettings-desktop-schemas glib-networking ]
+    ++ [(if useGtk3 then gtk3 else gtk2)]
+    ++ concatMap (f: optionals f.enabled f.deps) (filter (f: f ? deps) features)
+  ;
 
   configureFlags =
-    optional (!enableLdap) "--disable-ldap"
-    ++ optional (!enableNetworkManager) "--disable-networkmanager"
-    ++ optionals (!enablePgp) [
-      "--disable-pgpcore-plugin"
-      "--disable-pgpinline-plugin"
-      "--disable-pgpmime-plugin"
-    ]
-    ++ optional (!enablePluginArchive) "--disable-archive-plugin"
-    ++ optional (!enablePluginLitehtmlViewer) "--disable-litehtml_viewer-plugin"
-    ++ optional (!enablePluginPdf) "--disable-pdf_viewer-plugin"
-    ++ optional (!enablePluginPython) "--disable-python-plugin"
-    ++ optional (!enablePluginRavatar) "--disable-libravatar-plugin"
-    ++ optional (!enablePluginRssyl) "--disable-rssyl-plugin"
-    ++ optional (!enablePluginSmime) "--disable-smime-plugin"
-    ++ optional (!enablePluginSpamassassin) "--disable-spamassassin-plugin"
-    ++ optional (!enablePluginSpamReport) "--disable-spam_report-plugin"
-    ++ optional (!enablePluginVcalendar) "--disable-vcalendar-plugin"
-    ++ optional (!enableSpellcheck) "--disable-enchant";
+    [
+      "--disable-manual"   # Missing docbook-tools, e.g., docbook2html
+      "--disable-compface" # Missing compface library
+      "--disable-jpilot"   # Missing jpilot library
 
-  enableParallelBuilding = true;
+      "--disable-gdata-plugin" # Complains about missing libgdata, even when provided
+      "--disable-fancy-plugin" # Missing libwebkit-1.0 library
+    ] ++
+    (map (feature: map (flag: strings.enableFeature feature.enabled flag) feature.flags) features);
 
-  pythonPath = with python.pkgs; [ pygobject2 pygtk ];
+  enableParallelBuilding = true;
 
   preFixup = ''
-    buildPythonPath "$out $pythonPath"
+    buildPythonPath "$out $pythonPkgs"
     gappsWrapperArgs+=(--prefix XDG_DATA_DIRS : "${shared-mime-info}/share" --prefix PYTHONPATH : "$program_PYTHONPATH")
   '';
 
@@ -112,6 +174,6 @@ stdenv.mkDerivation rec {
     homepage = "https://www.claws-mail.org/";
     license = licenses.gpl3;
     platforms = platforms.linux;
-    maintainers = with maintainers; [ fpletz globin orivej ];
+    maintainers = with maintainers; [ fpletz globin orivej oxzi ajs124 ];
   };
 }
diff --git a/pkgs/applications/networking/mailreaders/claws-mail/gtk3.nix b/pkgs/applications/networking/mailreaders/claws-mail/gtk3.nix
deleted file mode 100644
index d5223092446..00000000000
--- a/pkgs/applications/networking/mailreaders/claws-mail/gtk3.nix
+++ /dev/null
@@ -1,121 +0,0 @@
-{ lib, config, fetchgit, stdenv, wrapGAppsHook, autoreconfHook, bison, flex
-, curl, dbus, dbus-glib, enchant, gtk3, gnutls, gnupg, gpgme
-, libarchive, libcanberra-gtk3, libetpan, libnotify, libsoup, libxml2, networkmanager
-, openldap, perl, pkg-config, poppler, python, shared-mime-info, webkitgtk
-, glib-networking, gsettings-desktop-schemas, libSM, libytnef, libical
-# Build options
-# TODO: A flag to build the manual.
-# TODO: Plugins that complain about their missing dependencies, even when
-#       provided:
-#         gdata requires libgdata
-#         geolocation requires libchamplain
-, enableLdap ? false
-, enableNetworkManager ? config.networking.networkmanager.enable or false
-, enablePgp ? true
-, enablePluginArchive ? false
-, enablePluginFancy ? true
-, enablePluginNotificationDialogs ? true
-, enablePluginNotificationSounds ? true
-, enablePluginPdf ? false
-, enablePluginPython ? false
-, enablePluginRavatar ? false
-, enablePluginRssyl ? false
-, enablePluginSmime ? false
-, enablePluginSpamassassin ? false
-, enablePluginSpamReport ? false
-, enablePluginVcalendar ? false
-, enableSpellcheck ? false
-}:
-
-with lib;
-
-stdenv.mkDerivation rec {
-  pname = "claws-mail-gtk3";
-  version = "3.99.0";
-
-  src = fetchgit {
-    url = "git://git.claws-mail.org/claws.git";
-    rev = version;
-    sha256 = "176h1swh1zx6dqyzfz470x4a1xicnv0zhy8ir47k7p23g6y17i2k";
-  };
-
-  outputs = [ "out" "dev" ];
-
-  patches = [ ./mime.patch ];
-
-  preConfigure = ''
-    # autotools check tries to dlopen libpython as a requirement for the python plugin
-    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${python}/lib
-    # generate version without .git
-    [ -e version ] || echo "echo ${version}" > version
-  '';
-
-  postPatch = ''
-    substituteInPlace src/procmime.c \
-        --subst-var-by MIMEROOTDIR ${shared-mime-info}/share
-  '';
-
-  nativeBuildInputs = [ autoreconfHook bison flex pkg-config wrapGAppsHook python.pkgs.wrapPython ];
-  propagatedBuildInputs = with python.pkgs; [ python ] ++ optionals enablePluginPython [ pygtk pygobject2 ];
-
-  buildInputs =
-    [ curl dbus dbus-glib gtk3 gnutls gsettings-desktop-schemas
-      libetpan perl glib-networking libSM libytnef
-    ]
-    ++ optional enableSpellcheck enchant
-    ++ optionals (enablePgp || enablePluginSmime) [ gnupg gpgme ]
-    ++ optional enablePluginArchive libarchive
-    ++ optional enablePluginNotificationSounds libcanberra-gtk3
-    ++ optional enablePluginNotificationDialogs libnotify
-    ++ optional enablePluginFancy libsoup
-    ++ optional enablePluginRssyl libxml2
-    ++ optional enableNetworkManager networkmanager
-    ++ optional enableLdap openldap
-    ++ optional enablePluginPdf poppler
-    ++ optional enablePluginFancy webkitgtk
-    ++ optional enablePluginVcalendar libical;
-
-  configureFlags =
-    optional (!enableLdap) "--disable-ldap"
-    ++ optional (!enableNetworkManager) "--disable-networkmanager"
-    ++ optionals (!enablePgp) [
-      "--disable-pgpcore-plugin"
-      "--disable-pgpinline-plugin"
-      "--disable-pgpmime-plugin"
-    ]
-    ++ optional (!enablePluginArchive) "--disable-archive-plugin"
-    ++ optional (!enablePluginFancy) "--disable-fancy-plugin"
-    ++ optional (!enablePluginPdf) "--disable-pdf_viewer-plugin"
-    ++ optional (!enablePluginPython) "--disable-python-plugin"
-    ++ optional (!enablePluginRavatar) "--disable-libravatar-plugin"
-    ++ optional (!enablePluginRssyl) "--disable-rssyl-plugin"
-    ++ optional (!enablePluginSmime) "--disable-smime-plugin"
-    ++ optional (!enablePluginSpamassassin) "--disable-spamassassin-plugin"
-    ++ optional (!enablePluginSpamReport) "--disable-spam_report-plugin"
-    ++ optional (!enablePluginVcalendar) "--disable-vcalendar-plugin"
-    ++ optional (!enableSpellcheck) "--disable-enchant";
-
-  enableParallelBuilding = true;
-
-  pythonPath = with python.pkgs; [ pygobject2 pygtk ];
-
-  preFixup = ''
-    buildPythonPath "$out $pythonPath"
-    gappsWrapperArgs+=(--prefix XDG_DATA_DIRS : "${shared-mime-info}/share" --prefix PYTHONPATH : "$program_PYTHONPATH")
-  '';
-
-  postInstall = ''
-    mkdir -p $out/share/applications
-    cp claws-mail.desktop $out/share/applications
-  '';
-
-  NIX_CFLAGS_COMPILE = [ "-Wno-deprecated-declarations" ];
-
-  meta = {
-    description = "The user-friendly, lightweight, and fast email client";
-    homepage = "https://www.claws-mail.org/";
-    license = licenses.gpl3;
-    platforms = platforms.linux;
-    maintainers = with maintainers; [ fpletz globin orivej ];
-  };
-}
diff --git a/pkgs/build-support/fetchgithub/default.nix b/pkgs/build-support/fetchgithub/default.nix
index 66671dd0a6a..3f355d10f8a 100644
--- a/pkgs/build-support/fetchgithub/default.nix
+++ b/pkgs/build-support/fetchgithub/default.nix
@@ -1,17 +1,19 @@
 { lib, fetchgit, fetchzip }:
 
 { owner, repo, rev, name ? "source"
-, fetchSubmodules ? false, private ? false
+, fetchSubmodules ? false, leaveDotGit ? null
+, deepClone ? false, private ? false
 , githubBase ? "github.com", varPrefix ? null
 , ... # For hash agility
-}@args: assert private -> !fetchSubmodules;
+}@args:
 let
   baseUrl = "https://${githubBase}/${owner}/${repo}";
   passthruAttrs = removeAttrs args [ "owner" "repo" "rev" "fetchSubmodules" "private" "githubBase" "varPrefix" ];
   varBase = "NIX${if varPrefix == null then "" else "_${varPrefix}"}_GITHUB_PRIVATE_";
+  useFetchGit = fetchSubmodules || (leaveDotGit == true) || deepClone;
   # We prefer fetchzip in cases we don't need submodules as the hash
   # is more stable in that case.
-  fetcher = if fetchSubmodules then fetchgit else fetchzip;
+  fetcher = if useFetchGit then fetchgit else fetchzip;
   privateAttrs = lib.optionalAttrs private {
     netrcPhase = ''
       if [ -z "''$${varBase}USERNAME" -o -z "''$${varBase}PASSWORD" ]; then
@@ -26,8 +28,14 @@ let
     '';
     netrcImpureEnvVars = [ "${varBase}USERNAME" "${varBase}PASSWORD" ];
   };
-  fetcherArgs = (if fetchSubmodules
-    then { inherit rev fetchSubmodules; url = "${baseUrl}.git"; }
+  fetcherArgs = (if useFetchGit
+    then {
+      inherit rev deepClone fetchSubmodules; url = "${baseUrl}.git";
+    } // lib.optionalAttrs (leaveDotGit != null) { inherit leaveDotGit; }
     else ({ url = "${baseUrl}/archive/${rev}.tar.gz"; } // privateAttrs)
   ) // passthruAttrs // { inherit name; };
-in fetcher fetcherArgs // { meta.homepage = baseUrl; inherit rev; }
+in
+
+assert private -> !useFetchGit;
+
+fetcher fetcherArgs // { meta.homepage = baseUrl; inherit rev; }
diff --git a/pkgs/development/ocaml-modules/qcheck/core.nix b/pkgs/development/ocaml-modules/qcheck/core.nix
index 03de70237a4..e1b3503b541 100644
--- a/pkgs/development/ocaml-modules/qcheck/core.nix
+++ b/pkgs/development/ocaml-modules/qcheck/core.nix
@@ -2,7 +2,7 @@
 
 buildDunePackage rec {
   pname = "qcheck-core";
-  version = "0.16";
+  version = "0.17";
 
   useDune2 = true;
 
@@ -12,7 +12,7 @@ buildDunePackage rec {
     owner = "c-cube";
     repo = "qcheck";
     rev = version;
-    sha256 = "1s5dpqj8zvd3wr2w3fp4wb6yc57snjpxzzfv9fb6l9qgigswwjdr";
+    sha256 = "0qfyqhfg98spmfci9z6f527a16gwjnx2lrbbgw67p37ys5acrfar";
   };
 
   meta = {
diff --git a/pkgs/development/ocaml-modules/stdint/default.nix b/pkgs/development/ocaml-modules/stdint/default.nix
index c849ffee479..52d97e12998 100644
--- a/pkgs/development/ocaml-modules/stdint/default.nix
+++ b/pkgs/development/ocaml-modules/stdint/default.nix
@@ -21,14 +21,18 @@ buildDunePackage rec {
     })
   ];
 
-  # disable remaining broken tests, see
-  # https://github.com/andrenth/ocaml-stdint/issues/59
+  # 1. disable remaining broken tests, see
+  #    https://github.com/andrenth/ocaml-stdint/issues/59
+  # 2. fix tests to liberal test range
+  #    https://github.com/andrenth/ocaml-stdint/pull/61
   postPatch = ''
     substituteInPlace tests/stdint_test.ml \
       --replace 'test "An integer should perform left-shifts correctly"' \
                 'skip "An integer should perform left-shifts correctly"' \
       --replace 'test "Logical shifts must not sign-extend"' \
-                'skip "Logical shifts must not sign-extend"'
+                'skip "Logical shifts must not sign-extend"' \
+      --replace 'let pos_int = QCheck.map_same_type abs in_range' \
+                'let pos_int = QCheck.int_range 0 maxi'
   '';
 
   doCheck = true;
diff --git a/pkgs/shells/nushell/default.nix b/pkgs/shells/nushell/default.nix
index 804fea0102f..5b0ba490bf5 100644
--- a/pkgs/shells/nushell/default.nix
+++ b/pkgs/shells/nushell/default.nix
@@ -15,16 +15,16 @@
 
 rustPlatform.buildRustPackage rec {
   pname = "nushell";
-  version = "0.27.0";
+  version = "0.27.1";
 
   src = fetchFromGitHub {
     owner = pname;
     repo = pname;
     rev = version;
-    sha256 = "sha256-OesIOL5jn5a3yvOSayMXmZQK9XpYxspOvDvZ6OY5JD4=";
+    sha256 = "sha256-Ms3ofPU7pd1qOxTJ7jImT2DawTcFLeI7Fi+xihsWhKY=";
   };
 
-  cargoSha256 = "sha256-YFtpg5IXhWJmBtX79MIBme4SKOoq+13UakvAJnTzJFo=";
+  cargoSha256 = "sha256-cJ+P/AaptZGOyjIu+66M1/rMYpVPFZGQDPeakUws3CQ=";
 
   nativeBuildInputs = [ pkg-config ]
     ++ lib.optionals (withStableFeatures && stdenv.isLinux) [ python3 ];
diff --git a/pkgs/tools/nix/nix-output-monitor/default.nix b/pkgs/tools/nix/nix-output-monitor/default.nix
index 1aa6117c295..f3b080938eb 100644
--- a/pkgs/tools/nix/nix-output-monitor/default.nix
+++ b/pkgs/tools/nix/nix-output-monitor/default.nix
@@ -4,12 +4,12 @@
 }:
 mkDerivation {
   pname = "nix-output-monitor";
-  version = "1.0.1.0";
+  version = "1.0.1.1";
   src = fetchFromGitHub {
     owner = "maralorn";
     repo = "nix-output-monitor";
-    sha256 = "10a3sn5isdb9q13yzdclng35jwfaf4lxrkdxwbhwms1k2ll08qk6";
-    rev = "1.0.1.0";
+    sha256 = "1wi1gsl5q1sy7k6k5wxhwpwzki7rghhbsyzm84hnw6h93w6401ax";
+    rev = "v1.0.1.1";
   };
   isLibrary = true;
   isExecutable = true;
diff --git a/pkgs/tools/security/jwt-cli/default.nix b/pkgs/tools/security/jwt-cli/default.nix
index 6b4639a5307..0b3a94d816b 100644
--- a/pkgs/tools/security/jwt-cli/default.nix
+++ b/pkgs/tools/security/jwt-cli/default.nix
@@ -2,16 +2,16 @@
 
 rustPlatform.buildRustPackage rec {
   pname = "jwt-cli";
-  version = "3.3.0";
+  version = "4.0.0";
 
   src = fetchFromGitHub {
     owner = "mike-engel";
     repo = pname;
     rev = version;
-    sha256 = "09zi55ffkhsckvqj84xnxn9bgfkrj9wnzqbh9hfsxzbk4xy7fc2h";
+    sha256 = "sha256-82Le0kdt/fnSQwsRRYHy4Jv9rsCPGf5dIWmoZE2cPxY=";
   };
 
-  cargoSha256 = "1k13pw202fr5mvd0ys39n3dxwcl3sd01j6izfb28k06b6pav3wc8";
+  cargoSha256 = "sha256-nk4nrsePiUirVPoOPehCOf5ZoGVj3jy7PnSZENnpcaM=";
 
   buildInputs = lib.optional stdenv.isDarwin Security;
 
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index abfacab1d53..e28d2b5f273 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -21568,8 +21568,9 @@ in
   claws-mail = callPackage ../applications/networking/mailreaders/claws-mail {
     inherit (xorg) libSM;
   };
-  claws-mail-gtk3 = callPackage ../applications/networking/mailreaders/claws-mail/gtk3.nix {
+  claws-mail-gtk3 = callPackage ../applications/networking/mailreaders/claws-mail {
     inherit (xorg) libSM;
+    useGtk3 = true;
   };
 
   clfswm = callPackage ../applications/window-managers/clfswm { };