about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2023-07-27 18:01:53 +0000
committerGitHub <noreply@github.com>2023-07-27 18:01:53 +0000
commit824f21d74883af5ebb0bd442213a0d97671ca588 (patch)
treee2be222e432693ab15aa5273c002628a88090a02
parent433ca822324e45d3f9267e3f7a2cc90e0e66bf04 (diff)
parent3e9a3ac490b7d0d0560b8f8290537ee148dd322b (diff)
Merge staging-next into staging
-rw-r--r--doc/common.nix4
-rw-r--r--doc/contributing/contributing-to-documentation.chapter.md8
-rw-r--r--doc/default.nix8
-rw-r--r--doc/shell.nix20
-rw-r--r--maintainers/maintainer-list.nix7
-rw-r--r--nixos/doc/manual/common.nix4
-rw-r--r--nixos/doc/manual/contributing-to-this-manual.chapter.md2
-rw-r--r--nixos/doc/manual/default.nix16
-rw-r--r--nixos/doc/manual/shell.nix20
-rw-r--r--nixos/lib/systemd-lib.nix17
-rw-r--r--nixos/modules/image/amend-repart-definitions.py113
-rw-r--r--nixos/modules/image/repart.md137
-rw-r--r--nixos/modules/image/repart.nix207
-rw-r--r--nixos/modules/services/databases/postgresql.nix4
-rw-r--r--nixos/modules/system/boot/systemd/repart.nix27
-rw-r--r--nixos/modules/system/boot/systemd/sysupdate.nix14
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/appliance-repart-image.nix116
-rw-r--r--pkgs/applications/editors/orbiton/default.nix4
-rw-r--r--pkgs/applications/file-managers/clifm/default.nix4
-rw-r--r--pkgs/applications/networking/p2p/zeronet-conservancy/default.nix10
-rw-r--r--pkgs/applications/video/mpv/default.nix17
-rw-r--r--pkgs/applications/virtualization/crun/default.nix5
-rw-r--r--pkgs/development/python-modules/aioslimproto/default.nix4
-rw-r--r--pkgs/development/python-modules/bluetooth-data-tools/default.nix4
-rw-r--r--pkgs/development/python-modules/home-assistant-bluetooth/default.nix4
-rw-r--r--pkgs/development/tools/language-servers/millet/Cargo.lock73
-rw-r--r--pkgs/development/tools/language-servers/millet/default.nix4
-rw-r--r--pkgs/development/tools/oh-my-posh/default.nix6
-rw-r--r--pkgs/servers/http/tengine/default.nix4
-rw-r--r--pkgs/tools/admin/lxd/default.nix24
-rw-r--r--pkgs/tools/admin/lxd/ui.nix3
-rw-r--r--pkgs/tools/filesystems/dwarfs/default.nix29
-rw-r--r--pkgs/tools/filesystems/dwarfs/version_info.patch34
-rw-r--r--pkgs/tools/misc/debian-devscripts/default.nix2
-rw-r--r--pkgs/tools/nix/devour-flake/default.nix27
-rw-r--r--pkgs/tools/nix/nixci/default.nix38
-rw-r--r--pkgs/tools/nix/web-devmode.nix117
-rw-r--r--pkgs/tools/security/enc/default.nix9
-rw-r--r--pkgs/tools/text/difftastic/Cargo.lock37
-rw-r--r--pkgs/tools/text/difftastic/default.nix4
-rw-r--r--pkgs/tools/virtualization/distrobuilder/default.nix2
-rw-r--r--pkgs/top-level/all-packages.nix7
43 files changed, 1035 insertions, 162 deletions
diff --git a/doc/common.nix b/doc/common.nix
new file mode 100644
index 0000000000000..56f723eb6bd7d
--- /dev/null
+++ b/doc/common.nix
@@ -0,0 +1,4 @@
+{
+  outputPath = "share/doc/nixpkgs";
+  indexPath = "manual.html";
+}
diff --git a/doc/contributing/contributing-to-documentation.chapter.md b/doc/contributing/contributing-to-documentation.chapter.md
index a732eee4b9627..0b7b49bf7dda1 100644
--- a/doc/contributing/contributing-to-documentation.chapter.md
+++ b/doc/contributing/contributing-to-documentation.chapter.md
@@ -23,6 +23,14 @@ $ nix-shell
 
 If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.html`.
 
+## devmode {#sec-contributing-devmode}
+
+The shell in the manual source directory makes available a command, `devmode`.
+It is a daemon, that:
+1. watches the manual's source for changes and when they occur — rebuilds
+2. HTTP serves the manual, injecting a script that triggers reload on changes
+3. opens the manual in the default browser
+
 ## Syntax {#sec-contributing-markup}
 
 As per [RFC 0072](https://github.com/NixOS/rfcs/pull/72), all new documentation content should be written in [CommonMark](https://commonmark.org/) Markdown dialect.
diff --git a/doc/default.nix b/doc/default.nix
index 8efa406ec1ea3..f4270ae856d5f 100644
--- a/doc/default.nix
+++ b/doc/default.nix
@@ -3,6 +3,8 @@ let
   inherit (pkgs) lib;
   inherit (lib) hasPrefix removePrefix;
 
+  common = import ./common.nix;
+
   lib-docs = import ./doc-support/lib-function-docs.nix {
     inherit pkgs nixpkgs;
     libsets = [
@@ -132,15 +134,15 @@ in pkgs.stdenv.mkDerivation {
   '';
 
   installPhase = ''
-    dest="$out/share/doc/nixpkgs"
+    dest="$out/${common.outputPath}"
     mkdir -p "$(dirname "$dest")"
     mv out "$dest"
-    mv "$dest/index.html" "$dest/manual.html"
+    mv "$dest/index.html" "$dest/${common.indexPath}"
 
     cp ${epub} "$dest/nixpkgs-manual.epub"
 
     mkdir -p $out/nix-support/
-    echo "doc manual $dest manual.html" >> $out/nix-support/hydra-build-products
+    echo "doc manual $dest ${common.indexPath}" >> $out/nix-support/hydra-build-products
     echo "doc manual $dest nixpkgs-manual.epub" >> $out/nix-support/hydra-build-products
   '';
 }
diff --git a/doc/shell.nix b/doc/shell.nix
new file mode 100644
index 0000000000000..d71e3f3a709ac
--- /dev/null
+++ b/doc/shell.nix
@@ -0,0 +1,20 @@
+let
+  pkgs = import ../. {
+    config = {};
+    overlays = [];
+  };
+
+  common = import ./common.nix;
+  inherit (common) outputPath indexPath;
+
+  web-devmode = import ../pkgs/tools/nix/web-devmode.nix {
+    inherit pkgs;
+    buildArgs = "./.";
+    open = "/${outputPath}/${indexPath}";
+  };
+in
+  pkgs.mkShell {
+    packages = [
+      web-devmode
+    ];
+  }
diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix
index 08d54dbd86191..79564e8a178f4 100644
--- a/maintainers/maintainer-list.nix
+++ b/maintainers/maintainer-list.nix
@@ -15727,6 +15727,13 @@
     githubId = 219362;
     name = "Sarah Brofeldt";
   };
+  srid = {
+    email = "srid@srid.ca";
+    matrix = "@srid:matrix.org";
+    github = "srid";
+    githubId = 3998;
+    name = "Sridhar Ratnakumar";
+  };
   srounce = {
     name = "Samuel Rounce";
     email = "me@samuelrounce.co.uk";
diff --git a/nixos/doc/manual/common.nix b/nixos/doc/manual/common.nix
new file mode 100644
index 0000000000000..48d1d909492d6
--- /dev/null
+++ b/nixos/doc/manual/common.nix
@@ -0,0 +1,4 @@
+{
+  outputPath = "share/doc/nixos";
+  indexPath = "index.html";
+}
diff --git a/nixos/doc/manual/contributing-to-this-manual.chapter.md b/nixos/doc/manual/contributing-to-this-manual.chapter.md
index c306cc084cdbe..4633c7e1b058f 100644
--- a/nixos/doc/manual/contributing-to-this-manual.chapter.md
+++ b/nixos/doc/manual/contributing-to-this-manual.chapter.md
@@ -11,6 +11,8 @@ $ nix-build nixos/release.nix -A manual.x86_64-linux
 
 If the build succeeds, the manual will be in `./result/share/doc/nixos/index.html`.
 
+There's also [a convenient development daemon](https://nixos.org/manual/nixpkgs/unstable/#sec-contributing-devmode).
+
 **Contributing to the man pages**
 
 The man pages are written in [DocBook] which is XML.
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index f2fd6a682934a..902dee7018010 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -16,6 +16,8 @@ let
 
   lib = pkgs.lib;
 
+  common = import ./common.nix;
+
   manpageUrls = pkgs.path + "/doc/manpage-urls.json";
 
   # We need to strip references to /nix/store/* from options,
@@ -78,11 +80,11 @@ let
     substituteInPlace ./nixos-options.md \
       --replace \
         '@NIXOS_OPTIONS_JSON@' \
-        ${optionsDoc.optionsJSON}/share/doc/nixos/options.json
+        ${optionsDoc.optionsJSON}/${common.outputPath}/options.json
     substituteInPlace ./development/writing-nixos-tests.section.md \
       --replace \
         '@NIXOS_TEST_OPTIONS_JSON@' \
-        ${testOptionsDoc.optionsJSON}/share/doc/nixos/options.json
+        ${testOptionsDoc.optionsJSON}/${common.outputPath}/options.json
     sed -e '/@PYTHON_MACHINE_METHODS@/ {' -e 'r ${testDriverMachineDocstrings}/machine-methods.md' -e 'd' -e '}' \
       -i ./development/writing-nixos-tests.section.md
   '';
@@ -99,7 +101,7 @@ in rec {
     }
     ''
       # Generate the HTML manual.
-      dst=$out/share/doc/nixos
+      dst=$out/${common.outputPath}
       mkdir -p $dst
 
       cp ${../../../doc/style.css} $dst/style.css
@@ -120,7 +122,7 @@ in rec {
         --toc-depth 1 \
         --chunk-toc-depth 1 \
         ./manual.md \
-        $dst/index.html
+        $dst/${common.indexPath}
 
       mkdir -p $out/nix-support
       echo "nix-build out $out" >> $out/nix-support/hydra-build-products
@@ -131,7 +133,7 @@ in rec {
   manual = manualHTML;
 
   # Index page of the NixOS manual.
-  manualHTMLIndex = "${manualHTML}/share/doc/nixos/index.html";
+  manualHTMLIndex = "${manualHTML}/${common.outputPath}/${common.indexPath}";
 
   manualEpub = runCommand "nixos-manual-epub"
     { nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin buildPackages.zip ];
@@ -162,7 +164,7 @@ in rec {
     }
     ''
       # Generate the epub manual.
-      dst=$out/share/doc/nixos
+      dst=$out/${common.outputPath}
 
       xsltproc \
         --param chapter.autolabel 0 \
@@ -197,7 +199,7 @@ in rec {
       mkdir -p $out/share/man/man5
       nixos-render-docs -j $NIX_BUILD_CORES options manpage \
         --revision ${lib.escapeShellArg revision} \
-        ${optionsJSON}/share/doc/nixos/options.json \
+        ${optionsJSON}/${common.outputPath}/options.json \
         $out/share/man/man5/configuration.nix.5
     '';
 
diff --git a/nixos/doc/manual/shell.nix b/nixos/doc/manual/shell.nix
new file mode 100644
index 0000000000000..70500a12b0374
--- /dev/null
+++ b/nixos/doc/manual/shell.nix
@@ -0,0 +1,20 @@
+let
+  pkgs = import ../../.. {
+    config = {};
+    overlays = [];
+  };
+
+  common = import ./common.nix;
+  inherit (common) outputPath indexPath;
+
+  web-devmode = import ../../../pkgs/tools/nix/web-devmode.nix {
+    inherit pkgs;
+    buildArgs = "../../release.nix -A manualHTML.${builtins.currentSystem}";
+    open = "/${outputPath}/${indexPath}";
+  };
+in
+  pkgs.mkShell {
+    packages = [
+      web-devmode
+    ];
+  }
diff --git a/nixos/lib/systemd-lib.nix b/nixos/lib/systemd-lib.nix
index 585c4e5146286..641b47def0397 100644
--- a/nixos/lib/systemd-lib.nix
+++ b/nixos/lib/systemd-lib.nix
@@ -443,4 +443,21 @@ in rec {
           ${attrsToSection def.sliceConfig}
         '';
     };
+
+  # Create a directory that contains systemd definition files from an attrset
+  # that contains the file names as keys and the content as values. The values
+  # in that attrset are determined by the supplied format.
+  definitions = directoryName: format: definitionAttrs:
+    let
+      listOfDefinitions = lib.mapAttrsToList
+        (name: format.generate "${name}.conf")
+        definitionAttrs;
+    in
+    pkgs.runCommand directoryName { } ''
+      mkdir -p $out
+      ${(lib.concatStringsSep "\n"
+        (map (pkg: "cp ${pkg} $out/${pkg.name}") listOfDefinitions)
+      )}
+    '';
+
 }
diff --git a/nixos/modules/image/amend-repart-definitions.py b/nixos/modules/image/amend-repart-definitions.py
new file mode 100644
index 0000000000000..e50ed6fd39a79
--- /dev/null
+++ b/nixos/modules/image/amend-repart-definitions.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+
+"""Amend systemd-repart definiton files.
+
+In order to avoid Import-From-Derivation (IFD) when building images with
+systemd-repart, the definition files created by Nix need to be amended with the
+store paths from the closure.
+
+This is achieved by adding CopyFiles= instructions to the definition files.
+
+The arbitrary files configured via `contents` are also added to the definition
+files using the same mechanism.
+"""
+
+import json
+import sys
+import shutil
+import os
+import tempfile
+from pathlib import Path
+
+
+def add_contents_to_definition(
+    definition: Path, contents: dict[str, dict[str, str]] | None
+) -> None:
+    """Add CopyFiles= instructions to a definition for all files in contents."""
+    if not contents:
+        return
+
+    copy_files_lines: list[str] = []
+    for target, options in contents.items():
+        source = options["source"]
+
+        copy_files_lines.append(f"CopyFiles={source}:{target}\n")
+
+    with open(definition, "a") as f:
+        f.writelines(copy_files_lines)
+
+
+def add_closure_to_definition(
+    definition: Path, closure: Path | None, strip_nix_store_prefix: bool | None
+) -> None:
+    """Add CopyFiles= instructions to a definition for all paths in the closure.
+
+    If strip_nix_store_prefix is True, `/nix/store` is stripped from the target path.
+    """
+    if not closure:
+        return
+
+    copy_files_lines: list[str] = []
+    with open(closure, "r") as f:
+        for line in f:
+            if not isinstance(line, str):
+                continue
+
+            source = Path(line.strip())
+            target = str(source.relative_to("/nix/store/"))
+            target = f":{target}" if strip_nix_store_prefix else ""
+
+            copy_files_lines.append(f"CopyFiles={source}{target}\n")
+
+    with open(definition, "a") as f:
+        f.writelines(copy_files_lines)
+
+
+def main() -> None:
+    """Amend the provided repart definitions by adding CopyFiles= instructions.
+
+    For each file specified in the `contents` field of a partition in the
+    partiton config file, a `CopyFiles=` instruction is added to the
+    corresponding definition file.
+
+    The same is done for every store path of the `closure` field.
+
+    Print the path to a directory that contains the amended repart
+    definitions to stdout.
+    """
+    partition_config_file = sys.argv[1]
+    if not partition_config_file:
+        print("No partition config file was supplied.")
+        sys.exit(1)
+
+    repart_definitions = sys.argv[2]
+    if not repart_definitions:
+        print("No repart definitions were supplied.")
+        sys.exit(1)
+
+    with open(partition_config_file, "rb") as f:
+        partition_config = json.load(f)
+
+    if not partition_config:
+        print("Partition config is empty.")
+        sys.exit(1)
+
+    temp = tempfile.mkdtemp()
+    shutil.copytree(repart_definitions, temp, dirs_exist_ok=True)
+
+    for name, config in partition_config.items():
+        definition = Path(f"{temp}/{name}.conf")
+        os.chmod(definition, 0o644)
+
+        contents = config.get("contents")
+        add_contents_to_definition(definition, contents)
+
+        closure = config.get("closure")
+        strip_nix_store_prefix = config.get("stripStorePaths")
+        add_closure_to_definition(definition, closure, strip_nix_store_prefix)
+
+    print(temp)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/nixos/modules/image/repart.md b/nixos/modules/image/repart.md
new file mode 100644
index 0000000000000..6d0675f21a033
--- /dev/null
+++ b/nixos/modules/image/repart.md
@@ -0,0 +1,137 @@
+# Building Images via `systemd-repart` {#sec-image-repart}
+
+You can build disk images in NixOS with the `image.repart` option provided by
+the module [image/repart.nix][]. This module uses `systemd-repart` to build the
+images and exposes it's entire interface via the `repartConfig` option.
+
+[image/repart.nix]: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/image/repart.nix
+
+An example of how to build an image:
+
+```nix
+{ config, modulesPath, ... }: {
+
+  imports = [ "${modulesPath}/image/repart.nix" ];
+
+  image.repart = {
+    name = "image";
+    partitions = {
+      "esp" = {
+        contents = {
+          ...
+        };
+        repartConfig = {
+          Type = "esp";
+          ...
+        };
+      };
+      "root" = {
+        storePaths = [ config.system.build.toplevel ];
+        repartConfig = {
+          Type = "root";
+          Label = "nixos";
+          ...
+        };
+      };
+    };
+  };
+
+}
+```
+
+## Nix Store Partition {#sec-image-repart-store-partition}
+
+You can define a partition that only contains the Nix store and then mount it
+under `/nix/store`. Because the `/nix/store` part of the paths is already
+determined by the mount point, you have to set `stripNixStorePrefix = true;` so
+that the prefix is stripped from the paths before copying them into the image.
+
+```nix
+fileSystems."/nix/store".device = "/dev/disk/by-partlabel/nix-store"
+
+image.repart.partitions = {
+  "store" = {
+    storePaths = [ config.system.build.toplevel ];
+    stripNixStorePrefix = true;
+    repartConfig = {
+      Type = "linux-generic";
+      Label = "nix-store";
+      ...
+    };
+  };
+};
+```
+
+## Appliance Image {#sec-image-repart-appliance}
+
+The `image/repart.nix` module can also be used to build self-contained [software
+appliances][].
+
+[software appliances]: https://en.wikipedia.org/wiki/Software_appliance
+
+The generation based update mechanism of NixOS is not suited for appliances.
+Updates of appliances are usually either performed by replacing the entire
+image with a new one or by updating partitions via an A/B scheme. See the
+[Chrome OS update process][chrome-os-update] for an example of how to achieve
+this. The appliance image built in the following example does not contain a
+`configuration.nix` and thus you will not be able to call `nixos-rebuild` from
+this system.
+
+[chrome-os-update]: https://chromium.googlesource.com/aosp/platform/system/update_engine/+/HEAD/README.md
+
+```nix
+let
+  pkgs = import <nixpkgs> { };
+  efiArch = pkgs.stdenv.hostPlatform.efiArch;
+in
+(pkgs.nixos [
+  ({ config, lib, pkgs, modulesPath, ... }: {
+
+    imports = [ "${modulesPath}/image/repart.nix" ];
+
+    boot.loader.grub.enable = false;
+
+    fileSystems."/".device = "/dev/disk/by-label/nixos";
+
+    image.repart = {
+      name = "image";
+      partitions = {
+        "esp" = {
+          contents = {
+            "/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source =
+              "${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+
+            "/loader/entries/nixos.conf".source = pkgs.writeText "nixos.conf" ''
+              title NixOS
+              linux /EFI/nixos/kernel.efi
+              initrd /EFI/nixos/initrd.efi
+              options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
+            '';
+
+            "/EFI/nixos/kernel.efi".source =
+              "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
+
+            "/EFI/nixos/initrd.efi".source =
+              "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
+          };
+          repartConfig = {
+            Type = "esp";
+            Format = "vfat";
+            SizeMinBytes = "96M";
+          };
+        };
+        "root" = {
+          storePaths = [ config.system.build.toplevel ];
+          repartConfig = {
+            Type = "root";
+            Format = "ext4";
+            Label = "nixos";
+            Minimize = "guess";
+          };
+        };
+      };
+    };
+
+  })
+]).image
+```
diff --git a/nixos/modules/image/repart.nix b/nixos/modules/image/repart.nix
new file mode 100644
index 0000000000000..9e7fe6932b317
--- /dev/null
+++ b/nixos/modules/image/repart.nix
@@ -0,0 +1,207 @@
+# This module exposes options to build a disk image with a GUID Partition Table
+# (GPT). It uses systemd-repart to build the image.
+
+{ config, pkgs, lib, utils, ... }:
+
+let
+  cfg = config.image.repart;
+
+  partitionOptions = {
+    options = {
+      storePaths = lib.mkOption {
+        type = with lib.types; listOf path;
+        default = [ ];
+        description = lib.mdDoc "The store paths to include in the partition.";
+      };
+
+      stripNixStorePrefix = lib.mkOption {
+        type = lib.types.bool;
+        default = false;
+        description = lib.mdDoc ''
+          Whether to strip `/nix/store/` from the store paths. This is useful
+          when you want to build a partition that only contains store paths and
+          is mounted under `/nix/store`.
+        '';
+      };
+
+      contents = lib.mkOption {
+        type = with lib.types; attrsOf (submodule {
+          options = {
+            source = lib.mkOption {
+              type = types.path;
+              description = lib.mdDoc "Path of the source file.";
+            };
+          };
+        });
+        default = { };
+        example = lib.literalExpression '' {
+          "/EFI/BOOT/BOOTX64.EFI".source =
+            "''${pkgs.systemd}/lib/systemd/boot/efi/systemd-bootx64.efi";
+
+          "/loader/entries/nixos.conf".source = systemdBootEntry;
+        }
+        '';
+        description = lib.mdDoc "The contents to end up in the filesystem image.";
+      };
+
+      repartConfig = lib.mkOption {
+        type = with lib.types; attrsOf (oneOf [ str int bool ]);
+        example = {
+          Type = "home";
+          SizeMinBytes = "512M";
+          SizeMaxBytes = "2G";
+        };
+        description = lib.mdDoc ''
+          Specify the repart options for a partiton as a structural setting.
+          See <https://www.freedesktop.org/software/systemd/man/repart.d.html>
+          for all available options.
+        '';
+      };
+    };
+  };
+in
+{
+  options.image.repart = {
+
+    name = lib.mkOption {
+      type = lib.types.str;
+      description = lib.mdDoc "The name of the image.";
+    };
+
+    seed = lib.mkOption {
+      type = with lib.types; nullOr str;
+      # Generated with `uuidgen`. Random but fixed to improve reproducibility.
+      default = "0867da16-f251-457d-a9e8-c31f9a3c220b";
+      description = lib.mdDoc ''
+        A UUID to use as a seed. You can set this to `null` to explicitly
+        randomize the partition UUIDs.
+      '';
+    };
+
+    split = lib.mkOption {
+      type = lib.types.bool;
+      default = false;
+      description = lib.mdDoc ''
+        Enables generation of split artifacts from partitions. If enabled, for
+        each partition with SplitName= set, a separate output file containing
+        just the contents of that partition is generated.
+      '';
+    };
+
+    partitions = lib.mkOption {
+      type = with lib.types; attrsOf (submodule partitionOptions);
+      default = { };
+      example = lib.literalExpression '' {
+        "10-esp" = {
+          contents = {
+            "/EFI/BOOT/BOOTX64.EFI".source =
+              "''${pkgs.systemd}/lib/systemd/boot/efi/systemd-bootx64.efi";
+          }
+          repartConfig = {
+            Type = "esp";
+            Format = "fat";
+          };
+        };
+        "20-root" = {
+          storePaths = [ config.system.build.toplevel ];
+          repartConfig = {
+            Type = "root";
+            Format = "ext4";
+            Minimize = "guess";
+          };
+        };
+      };
+      '';
+      description = lib.mdDoc ''
+        Specify partitions as a set of the names of the partitions with their
+        configuration as the key.
+      '';
+    };
+
+  };
+
+  config = {
+
+    system.build.image =
+      let
+        fileSystemToolMapping = with pkgs; {
+          "vfat" = [ dosfstools mtools ];
+          "ext4" = [ e2fsprogs.bin ];
+          "squashfs" = [ squashfsTools ];
+          "erofs" = [ erofs-utils ];
+          "btrfs" = [ btrfs-progs ];
+          "xfs" = [ xfsprogs ];
+        };
+
+        fileSystems = lib.filter
+          (f: f != null)
+          (lib.mapAttrsToList (_n: v: v.repartConfig.Format or null) cfg.partitions);
+
+        fileSystemTools = builtins.concatMap (f: fileSystemToolMapping."${f}") fileSystems;
+
+
+        makeClosure = paths: pkgs.closureInfo { rootPaths = paths; };
+
+        # Add the closure of the provided Nix store paths to cfg.partitions so
+        # that amend-repart-definitions.py can read it.
+        addClosure = _name: partitionConfig: partitionConfig // (
+          lib.optionalAttrs
+            (partitionConfig.storePaths or [ ] != [ ])
+            { closure = "${makeClosure partitionConfig.storePaths}/store-paths"; }
+        );
+
+
+        finalPartitions = lib.mapAttrs addClosure cfg.partitions;
+
+
+        amendRepartDefinitions = pkgs.runCommand "amend-repart-definitions.py"
+          {
+            nativeBuildInputs = with pkgs; [ black ruff mypy ];
+            buildInputs = [ pkgs.python3 ];
+          } ''
+          install ${./amend-repart-definitions.py} $out
+          patchShebangs --host $out
+
+          black --check --diff $out
+          ruff --line-length 88 $out
+          mypy --strict $out
+        '';
+
+        format = pkgs.formats.ini { };
+
+        definitionsDirectory = utils.systemdUtils.lib.definitions
+          "repart.d"
+          format
+          (lib.mapAttrs (_n: v: { Partition = v.repartConfig; }) finalPartitions);
+
+        partitions = pkgs.writeText "partitions.json" (builtins.toJSON finalPartitions);
+      in
+      pkgs.runCommand cfg.name
+        {
+          nativeBuildInputs = with pkgs; [
+            fakeroot
+            systemd
+          ] ++ fileSystemTools;
+        } ''
+        amendedRepartDefinitions=$(${amendRepartDefinitions} ${partitions} ${definitionsDirectory})
+
+        mkdir -p $out
+        cd $out
+
+        fakeroot systemd-repart \
+          --dry-run=no \
+          --empty=create \
+          --size=auto \
+          --seed="${cfg.seed}" \
+          --definitions="$amendedRepartDefinitions" \
+          --split="${lib.boolToString cfg.split}" \
+          image.raw
+      '';
+
+    meta = {
+      maintainers = with lib.maintainers; [ nikstur ];
+      doc = ./repart.md;
+    };
+
+  };
+}
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index a7016bbee3a86..0acaf0fd00a67 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -404,8 +404,8 @@ in
           {
             log_connections = true;
             log_statement = "all";
-            logging_collector = true
-            log_disconnections = true
+            logging_collector = true;
+            log_disconnections = true;
             log_destination = lib.mkForce "syslog";
           }
         '';
diff --git a/nixos/modules/system/boot/systemd/repart.nix b/nixos/modules/system/boot/systemd/repart.nix
index e81b3e4ff2a1b..2431c68ea17b8 100644
--- a/nixos/modules/system/boot/systemd/repart.nix
+++ b/nixos/modules/system/boot/systemd/repart.nix
@@ -1,28 +1,15 @@
-{ config, pkgs, lib, utils, ... }:
+{ config, lib, pkgs, utils, ... }:
 
 let
   cfg = config.systemd.repart;
   initrdCfg = config.boot.initrd.systemd.repart;
 
-  writeDefinition = name: partitionConfig: pkgs.writeText
-    "${name}.conf"
-    (lib.generators.toINI { } { Partition = partitionConfig; });
-
-  listOfDefinitions = lib.mapAttrsToList
-    writeDefinition
-    (lib.filterAttrs (k: _: !(lib.hasPrefix "_" k)) cfg.partitions);
-
-  # Create a directory in the store that contains a copy of all definition
-  # files. This is then passed to systemd-repart in the initrd so it can access
-  # the definition files after the sysroot has been mounted but before
-  # activation. This needs a hard copy of the files and not just symlinks
-  # because otherwise the files do not show up in the sysroot.
-  definitionsDirectory = pkgs.runCommand "systemd-repart-definitions" { } ''
-    mkdir -p $out
-    ${(lib.concatStringsSep "\n"
-      (map (pkg: "cp ${pkg} $out/${pkg.name}") listOfDefinitions)
-    )}
-  '';
+  format = pkgs.formats.ini { };
+
+  definitionsDirectory = utils.systemdUtils.lib.definitions
+    "repart.d"
+    format
+    (lib.mapAttrs (_n: v: { Partition = v; }) cfg.partitions);
 in
 {
   options = {
diff --git a/nixos/modules/system/boot/systemd/sysupdate.nix b/nixos/modules/system/boot/systemd/sysupdate.nix
index 2921e97f7560a..b1914a9c4e767 100644
--- a/nixos/modules/system/boot/systemd/sysupdate.nix
+++ b/nixos/modules/system/boot/systemd/sysupdate.nix
@@ -5,16 +5,10 @@ let
 
   format = pkgs.formats.ini { };
 
-  listOfDefinitions = lib.mapAttrsToList
-    (name: format.generate "${name}.conf")
-    (lib.filterAttrs (k: _: !(lib.hasPrefix "_" k)) cfg.transfers);
-
-  definitionsDirectory = pkgs.runCommand "sysupdate.d" { } ''
-    mkdir -p $out
-    ${(lib.concatStringsSep "\n"
-      (map (pkg: "cp ${pkg} $out/${pkg.name}") listOfDefinitions)
-    )}
-  '';
+  definitionsDirectory = utils.systemdUtils.lib.definitions
+    "sysupdate.d"
+    format
+    cfg.transfers;
 in
 {
   options.systemd.sysupdate = {
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index c9ce2ebe91f33..c707200def09c 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -112,6 +112,7 @@ in {
   anuko-time-tracker = handleTest ./anuko-time-tracker.nix {};
   apcupsd = handleTest ./apcupsd.nix {};
   apfs = runTest ./apfs.nix;
+  appliance-repart-image = runTest ./appliance-repart-image.nix;
   apparmor = handleTest ./apparmor.nix {};
   atd = handleTest ./atd.nix {};
   atop = handleTest ./atop.nix {};
diff --git a/nixos/tests/appliance-repart-image.nix b/nixos/tests/appliance-repart-image.nix
new file mode 100644
index 0000000000000..3f256db846214
--- /dev/null
+++ b/nixos/tests/appliance-repart-image.nix
@@ -0,0 +1,116 @@
+# Tests building and running a GUID Partition Table (GPT) appliance image.
+# "Appliance" here means that the image does not contain the normal NixOS
+# infrastructure of a system profile and cannot be re-built via
+# `nixos-rebuild`.
+
+{ lib, ... }:
+
+let
+  rootPartitionLabel = "root";
+
+  bootLoaderConfigPath = "/loader/entries/nixos.conf";
+  kernelPath = "/EFI/nixos/kernel.efi";
+  initrdPath = "/EFI/nixos/initrd.efi";
+in
+{
+  name = "appliance-gpt-image";
+
+  meta.maintainers = with lib.maintainers; [ nikstur ];
+
+  nodes.machine = { config, lib, pkgs, ... }: {
+
+    imports = [ ../modules/image/repart.nix ];
+
+    virtualisation.directBoot.enable = false;
+    virtualisation.mountHostNixStore = false;
+    virtualisation.useEFIBoot = true;
+
+    # Disable boot loaders because we install one "manually".
+    # TODO(raitobezarius): revisit this when #244907 lands
+    boot.loader.grub.enable = false;
+
+    virtualisation.fileSystems = lib.mkForce {
+      "/" = {
+        device = "/dev/disk/by-partlabel/${rootPartitionLabel}";
+        fsType = "ext4";
+      };
+    };
+
+    image.repart = {
+      name = "appliance-gpt-image";
+      partitions = {
+        "esp" = {
+          contents =
+            let
+              efiArch = config.nixpkgs.hostPlatform.efiArch;
+            in
+            {
+              "/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source =
+                "${pkgs.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+
+              # TODO: create an abstraction for Boot Loader Specification (BLS) entries.
+              "${bootLoaderConfigPath}".source = pkgs.writeText "nixos.conf" ''
+                title NixOS
+                linux ${kernelPath}
+                initrd ${initrdPath}
+                options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
+              '';
+
+              "${kernelPath}".source =
+                "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}";
+
+              "${initrdPath}".source =
+                "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}";
+            };
+          repartConfig = {
+            Type = "esp";
+            Format = "vfat";
+            # Minimize = "guess" seems to not work very vell for vfat
+            # partitons. It's better to set a sensible default instead. The
+            # aarch64 kernel seems to generally be a little bigger than the
+            # x86_64 kernel. To stay on the safe side, leave some more slack
+            # for every platform other than x86_64.
+            SizeMinBytes = if config.nixpkgs.hostPlatform.isx86_64 then "64M" else "96M";
+          };
+        };
+        "root" = {
+          storePaths = [ config.system.build.toplevel ];
+          repartConfig = {
+            Type = "root";
+            Format = config.fileSystems."/".fsType;
+            Label = rootPartitionLabel;
+            Minimize = "guess";
+          };
+        };
+      };
+    };
+  };
+
+  testScript = { nodes, ... }: ''
+    import os
+    import subprocess
+    import tempfile
+
+    tmp_disk_image = tempfile.NamedTemporaryFile()
+
+    subprocess.run([
+      "${nodes.machine.virtualisation.qemu.package}/bin/qemu-img",
+      "create",
+      "-f",
+      "qcow2",
+      "-b",
+      "${nodes.machine.system.build.image}/image.raw",
+      "-F",
+      "raw",
+      tmp_disk_image.name,
+    ])
+
+    # Set NIX_DISK_IMAGE so that the qemu script finds the right disk image.
+    os.environ['NIX_DISK_IMAGE'] = tmp_disk_image.name
+
+    bootctl_status = machine.succeed("bootctl status")
+    assert "${bootLoaderConfigPath}" in bootctl_status
+    assert "${kernelPath}" in bootctl_status
+    assert "${initrdPath}" in bootctl_status
+  '';
+}
diff --git a/pkgs/applications/editors/orbiton/default.nix b/pkgs/applications/editors/orbiton/default.nix
index 05f8c9a2ce5d6..d02aaf2dd03d9 100644
--- a/pkgs/applications/editors/orbiton/default.nix
+++ b/pkgs/applications/editors/orbiton/default.nix
@@ -4,13 +4,13 @@
 
 buildGoModule rec {
   pname = "orbiton";
-  version = "2.62.6";
+  version = "2.62.7";
 
   src = fetchFromGitHub {
     owner = "xyproto";
     repo = "orbiton";
     rev = "v${version}";
-    hash = "sha256-wSefvbpqxEbzgReOBPcot+VeXazwK/NPzh+wmmYhrls=";
+    hash = "sha256-NQBFplrYh33zcKfXrcZpWrF3Uac7YXdxh3D+wixEzP0=";
   };
 
   vendorHash = null;
diff --git a/pkgs/applications/file-managers/clifm/default.nix b/pkgs/applications/file-managers/clifm/default.nix
index c4c2d9e6528b5..f07309a8ad806 100644
--- a/pkgs/applications/file-managers/clifm/default.nix
+++ b/pkgs/applications/file-managers/clifm/default.nix
@@ -2,13 +2,13 @@
 
 stdenv.mkDerivation rec {
   pname = "clifm";
-  version = "1.10";
+  version = "1.13";
 
   src = fetchFromGitHub {
     owner = "leo-arch";
     repo = pname;
     rev = "v${version}";
-    sha256 = "sha256-kXnI8a1nGKBDc+isv9RYvputKk+/FHmM9j+G4UnI5Z4=";
+    sha256 = "sha256-Y9z3HT36Z1fwweOnniRgyNQX1cbrLSGGgB5UAxkq9mI=";
   };
 
   buildInputs = [ libcap acl file readline ];
diff --git a/pkgs/applications/networking/p2p/zeronet-conservancy/default.nix b/pkgs/applications/networking/p2p/zeronet-conservancy/default.nix
index e1a2a38264477..c8ac75683ae29 100644
--- a/pkgs/applications/networking/p2p/zeronet-conservancy/default.nix
+++ b/pkgs/applications/networking/p2p/zeronet-conservancy/default.nix
@@ -6,29 +6,33 @@
 
 python3Packages.buildPythonApplication rec {
   pname = "zeronet-conservancy";
-  version = "0.7.8.1";
+  version = "0.7.10";
   format = "other";
 
   src = fetchFromGitHub {
     owner = "zeronet-conservancy";
     repo = "zeronet-conservancy";
     rev = "v${version}";
-    sha256 = "sha256-+wZiwUy5bmW8+3h4SuvNN8I6mCIPOlOeFmiXlMu12OU=";
+    sha256 = "sha256-ZQYdK0B0z0cXTx7ujFngW3wSa/j8sEuwHB+BC5Xqq8o=";
   };
 
   propagatedBuildInputs = with python3Packages; [
     gevent msgpack base58 merkletools rsa pysocks pyasn1 websocket-client
     gevent-websocket rencode bitcoinlib maxminddb pyopenssl rich defusedxml
-    pyaes
+    pyaes coincurve
   ];
 
   buildPhase = ''
+    runHook preBuild
     ${python3Packages.python.pythonForBuild.interpreter} -O -m compileall .
+    runHook postBuild
   '';
 
   installPhase = ''
+    runHook preInstall
     mkdir -p $out/share
     cp -r plugins src *.py $out/share/
+    runHook postInstall
   '';
 
   postFixup = ''
diff --git a/pkgs/applications/video/mpv/default.nix b/pkgs/applications/video/mpv/default.nix
index 70aaa32526e7b..b93d7d6606c49 100644
--- a/pkgs/applications/video/mpv/default.nix
+++ b/pkgs/applications/video/mpv/default.nix
@@ -67,7 +67,7 @@
 , sdl2Support        ? true,           SDL2
 , sixelSupport       ? false,          libsixel
 , speexSupport       ? true,           speex
-, swiftSupport       ? stdenv.isDarwin && stdenv.isAarch64, swift
+, swiftSupport       ? stdenv.isDarwin, swift
 , theoraSupport      ? true,           libtheora
 , vaapiSupport       ? x11Support || waylandSupport, libva
 , vapoursynthSupport ? false,          vapoursynth
@@ -82,7 +82,20 @@ let
   inherit (darwin.apple_sdk_11_0.frameworks)
     AVFoundation CoreFoundation CoreMedia Cocoa CoreAudio MediaPlayer Accelerate;
   luaEnv = lua.withPackages (ps: with ps; [ luasocket ]);
-in stdenv.mkDerivation (finalAttrs: {
+
+  overrideSDK = platform: version:
+    platform // lib.optionalAttrs (platform ? darwinMinVersion) {
+      darwinMinVersion = version;
+    };
+
+  stdenv' = if swiftSupport && stdenv.isDarwin && stdenv.isx86_64
+    then stdenv.override (old: {
+      buildPlatform = overrideSDK old.buildPlatform "10.15";
+      hostPlatform = overrideSDK old.hostPlatform "10.15";
+      targetPlatform = overrideSDK old.targetPlatform "10.15";
+    })
+    else stdenv;
+in stdenv'.mkDerivation (finalAttrs: {
   pname = "mpv";
   version = "0.35.1";
 
diff --git a/pkgs/applications/virtualization/crun/default.nix b/pkgs/applications/virtualization/crun/default.nix
index fbc4482536f1f..7b994433840b0 100644
--- a/pkgs/applications/virtualization/crun/default.nix
+++ b/pkgs/applications/virtualization/crun/default.nix
@@ -23,6 +23,7 @@ let
     "test_exec.py"
     "test_hooks.py"
     "test_hostname.py"
+    "test_oci_features"
     "test_paths.py"
     "test_pid.py"
     "test_pid_file.py"
@@ -38,13 +39,13 @@ let
 in
 stdenv.mkDerivation rec {
   pname = "crun";
-  version = "1.8.5";
+  version = "1.8.6";
 
   src = fetchFromGitHub {
     owner = "containers";
     repo = pname;
     rev = version;
-    hash = "sha256-T51dVNtqQbXoPshlAkBzJOGTNTPM+AlqRYbqS8GX2NE=";
+    hash = "sha256-qPbJ8h/s4E7EmNlgBdrNZ0AW0D/N7PkK57C1cXjuM9U=";
     fetchSubmodules = true;
   };
 
diff --git a/pkgs/development/python-modules/aioslimproto/default.nix b/pkgs/development/python-modules/aioslimproto/default.nix
index c2cdb28e399a2..af681eec8ad40 100644
--- a/pkgs/development/python-modules/aioslimproto/default.nix
+++ b/pkgs/development/python-modules/aioslimproto/default.nix
@@ -10,7 +10,7 @@
 
 buildPythonPackage rec {
   pname = "aioslimproto";
-  version = "2.3.2";
+  version = "2.3.3";
   format = "pyproject";
 
   disabled = pythonOlder "3.9";
@@ -19,7 +19,7 @@ buildPythonPackage rec {
     owner = "home-assistant-libs";
     repo = pname;
     rev = "refs/tags/${version}";
-    hash = "sha256-vKIqBbWQNgv1v73P6K51K+yaqXgC1BtllZ59yTNPr2g=";
+    hash = "sha256-d+PEzCF1Cw/7NmumxIRRlr3hojpNsZM/JMQ0KWdosXk=";
   };
 
   nativeBuildInputs = [
diff --git a/pkgs/development/python-modules/bluetooth-data-tools/default.nix b/pkgs/development/python-modules/bluetooth-data-tools/default.nix
index 729547d17237b..918cba4f54b1a 100644
--- a/pkgs/development/python-modules/bluetooth-data-tools/default.nix
+++ b/pkgs/development/python-modules/bluetooth-data-tools/default.nix
@@ -9,7 +9,7 @@
 
 buildPythonPackage rec {
   pname = "bluetooth-data-tools";
-  version = "1.6.0";
+  version = "1.6.1";
   format = "pyproject";
 
   disabled = pythonOlder "3.9";
@@ -18,7 +18,7 @@ buildPythonPackage rec {
     owner = "Bluetooth-Devices";
     repo = pname;
     rev = "refs/tags/v${version}";
-    hash = "sha256-Doz8T7XuX/8JFu1yutTUxrtvasDLWD3Fp/+JMLEUIQM=";
+    hash = "sha256-A3zdM2kVmz8cUix9JT8cnIABZK64r6yiZisvb8A1RSQ=";
   };
 
   nativeBuildInputs = [
diff --git a/pkgs/development/python-modules/home-assistant-bluetooth/default.nix b/pkgs/development/python-modules/home-assistant-bluetooth/default.nix
index 85a6b7b5a0edb..bae4dc5a71d92 100644
--- a/pkgs/development/python-modules/home-assistant-bluetooth/default.nix
+++ b/pkgs/development/python-modules/home-assistant-bluetooth/default.nix
@@ -11,7 +11,7 @@
 
 buildPythonPackage rec {
   pname = "home-assistant-bluetooth";
-  version = "1.10.0";
+  version = "1.10.2";
   format = "pyproject";
 
   disabled = pythonOlder "3.9";
@@ -20,7 +20,7 @@ buildPythonPackage rec {
     owner = "home-assistant-libs";
     repo = pname;
     rev = "refs/tags/v${version}";
-    hash = "sha256-g8vdg7YU3rkXW85U4w9Hvb6u9uvoDphbkIlVXchCRxQ=";
+    hash = "sha256-zNhqiWYZ3tv6lwYgmi6Yue+mFcgk7Y1dDMbzWlsvVJM=";
   };
 
   postPatch = ''
diff --git a/pkgs/development/tools/language-servers/millet/Cargo.lock b/pkgs/development/tools/language-servers/millet/Cargo.lock
index 44ac46ca3f4e9..96f0e67abb303 100644
--- a/pkgs/development/tools/language-servers/millet/Cargo.lock
+++ b/pkgs/development/tools/language-servers/millet/Cargo.lock
@@ -28,11 +28,12 @@ dependencies = [
 
 [[package]]
 name = "analysis"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "config",
  "diagnostic",
  "elapsed",
+ "fast-hash",
  "fmt-util",
  "input",
  "mlb-statics",
@@ -114,7 +115,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chain-map"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "str-util",
@@ -127,7 +128,7 @@ source = "git+https://github.com/azdavis/language-util.git#f2c149459f0544fb6a8e1
 
 [[package]]
 name = "cm-syntax"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "lex-util",
  "paths",
@@ -156,7 +157,7 @@ dependencies = [
 
 [[package]]
 name = "config"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "serde",
@@ -184,7 +185,7 @@ checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
 
 [[package]]
 name = "cov-mark"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "once_cell",
@@ -411,7 +412,7 @@ dependencies = [
 
 [[package]]
 name = "input"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "cm-syntax",
  "config",
@@ -459,7 +460,7 @@ checksum = "3752f229dcc5a481d60f385fa479ff46818033d881d2d801aa27dffcfb5e8306"
 
 [[package]]
 name = "lang-srv"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "analysis",
  "anyhow",
@@ -487,7 +488,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "lex-util"
-version = "0.12.7"
+version = "0.12.8"
 
 [[package]]
 name = "libc"
@@ -559,7 +560,7 @@ dependencies = [
 
 [[package]]
 name = "millet-cli"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "analysis",
  "codespan-reporting",
@@ -577,7 +578,7 @@ dependencies = [
 
 [[package]]
 name = "millet-ls"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "anyhow",
  "env_logger",
@@ -597,7 +598,7 @@ dependencies = [
 
 [[package]]
 name = "mlb-hir"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "paths",
@@ -608,7 +609,7 @@ dependencies = [
 
 [[package]]
 name = "mlb-statics"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "config",
  "diagnostic",
@@ -632,7 +633,7 @@ dependencies = [
 
 [[package]]
 name = "mlb-syntax"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "lex-util",
  "paths",
@@ -695,7 +696,7 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
 
 [[package]]
 name = "panic-hook"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "better-panic",
 ]
@@ -898,7 +899,7 @@ dependencies = [
 
 [[package]]
 name = "slash-var-path"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "str-util",
@@ -906,14 +907,14 @@ dependencies = [
 
 [[package]]
 name = "sml-comment"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "sml-syntax",
 ]
 
 [[package]]
 name = "sml-dynamics"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "fmt-util",
@@ -924,7 +925,7 @@ dependencies = [
 
 [[package]]
 name = "sml-dynamics-tests"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "config",
  "pretty_assertions",
@@ -940,7 +941,7 @@ dependencies = [
 
 [[package]]
 name = "sml-file-syntax"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "config",
  "elapsed",
@@ -954,7 +955,7 @@ dependencies = [
 
 [[package]]
 name = "sml-fixity"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "once_cell",
@@ -963,7 +964,7 @@ dependencies = [
 
 [[package]]
 name = "sml-hir"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "la-arena",
  "sml-lab",
@@ -974,7 +975,7 @@ dependencies = [
 
 [[package]]
 name = "sml-hir-lower"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "config",
  "cov-mark",
@@ -989,14 +990,14 @@ dependencies = [
 
 [[package]]
 name = "sml-lab"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "str-util",
 ]
 
 [[package]]
 name = "sml-lex"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "cov-mark",
  "diagnostic",
@@ -1011,7 +1012,7 @@ source = "git+https://github.com/azdavis/sml-libs.git#3948485e5bf5649e50271caf3e
 
 [[package]]
 name = "sml-naive-fmt"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "sml-comment",
@@ -1020,11 +1021,11 @@ dependencies = [
 
 [[package]]
 name = "sml-namespace"
-version = "0.12.7"
+version = "0.12.8"
 
 [[package]]
 name = "sml-parse"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "diagnostic",
  "event-parse",
@@ -1036,14 +1037,14 @@ dependencies = [
 
 [[package]]
 name = "sml-path"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "str-util",
 ]
 
 [[package]]
 name = "sml-scon"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "num-bigint",
  "num-traits",
@@ -1052,7 +1053,7 @@ dependencies = [
 
 [[package]]
 name = "sml-statics"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "chain-map",
  "config",
@@ -1075,7 +1076,7 @@ dependencies = [
 
 [[package]]
 name = "sml-statics-types"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "chain-map",
  "code-h2-md-map",
@@ -1094,7 +1095,7 @@ dependencies = [
 
 [[package]]
 name = "sml-symbol-kind"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "sml-namespace",
  "sml-statics-types",
@@ -1102,7 +1103,7 @@ dependencies = [
 
 [[package]]
 name = "sml-syntax"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "code-h2-md-map",
  "fast-hash",
@@ -1113,7 +1114,7 @@ dependencies = [
 
 [[package]]
 name = "sml-ty-var-scope"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "fast-hash",
  "sml-hir",
@@ -1171,7 +1172,7 @@ dependencies = [
 
 [[package]]
 name = "tests"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "analysis",
  "cm-syntax",
@@ -1515,7 +1516,7 @@ dependencies = [
 
 [[package]]
 name = "xtask"
-version = "0.12.7"
+version = "0.12.8"
 dependencies = [
  "anyhow",
  "flate2",
diff --git a/pkgs/development/tools/language-servers/millet/default.nix b/pkgs/development/tools/language-servers/millet/default.nix
index 017474c692706..d28677fc3a8ff 100644
--- a/pkgs/development/tools/language-servers/millet/default.nix
+++ b/pkgs/development/tools/language-servers/millet/default.nix
@@ -2,13 +2,13 @@
 
 rustPlatform.buildRustPackage rec {
   pname = "millet";
-  version = "0.12.7";
+  version = "0.12.8";
 
   src = fetchFromGitHub {
     owner = "azdavis";
     repo = pname;
     rev = "v${version}";
-    hash = "sha256-W1Iq9vd7rkqx+0d+BIUnSxLQZG7X6K4JkGKc7zJSEIQ=";
+    hash = "sha256-H44aQGrLv/A1yo44DaR9FJ0ReXiHU4SQ3zLoEkxF9M8=";
   };
 
   cargoLock = {
diff --git a/pkgs/development/tools/oh-my-posh/default.nix b/pkgs/development/tools/oh-my-posh/default.nix
index 08dfc02cbd15c..bf1787e23ae86 100644
--- a/pkgs/development/tools/oh-my-posh/default.nix
+++ b/pkgs/development/tools/oh-my-posh/default.nix
@@ -6,16 +6,16 @@
 
 buildGoModule rec {
   pname = "oh-my-posh";
-  version = "17.12.0";
+  version = "18.1.0";
 
   src = fetchFromGitHub {
     owner = "jandedobbeleer";
     repo = pname;
     rev = "refs/tags/v${version}";
-    hash = "sha256-evZ8o6KMbnhVGY7gGicvs5hYxxHGxfkGAtcZPQd0Bvc=";
+    hash = "sha256-qK9hjsWhVTzxFo4SSvKb5IgZteVabWlCtoetu9v9xIE=";
   };
 
-  vendorHash = "sha256-sdUvtp/qXneP1z2MnV2XNGbBV/LXgAug5ueO83foNCA=";
+  vendorHash = "sha256-cATGMi/nL8dvlsR+cuvKH6Y9eR3UqcVjvZAj35Ydn2c=";
 
   sourceRoot = "source/src";
 
diff --git a/pkgs/servers/http/tengine/default.nix b/pkgs/servers/http/tengine/default.nix
index 5b1edb5a2d86c..e80185ac5cbb4 100644
--- a/pkgs/servers/http/tengine/default.nix
+++ b/pkgs/servers/http/tengine/default.nix
@@ -10,14 +10,14 @@
 with lib;
 
 stdenv.mkDerivation rec {
-  version = "2.4.1";
+  version = "3.0.0";
   pname = "tengine";
 
   src = fetchFromGitHub {
     owner = "alibaba";
     repo = pname;
     rev = version;
-    hash = "sha256-h9PFzJc/29WFe4mW+xpJAL1Z2XqBxMEtQeN5DMgOVBA=";
+    hash = "sha256-nUwPT7374dfE/T6yuCUynObq6LxBHDp90Dj2JGwJ4+M=";
   };
 
   buildInputs =
diff --git a/pkgs/tools/admin/lxd/default.nix b/pkgs/tools/admin/lxd/default.nix
index 7d4c10688b80b..02bf8cbd4e6c3 100644
--- a/pkgs/tools/admin/lxd/default.nix
+++ b/pkgs/tools/admin/lxd/default.nix
@@ -18,14 +18,11 @@
 
 buildGoModule rec {
   pname = "lxd-unwrapped";
-  version = "5.15";
+  version = "5.16";
 
   src = fetchurl {
-    urls = [
-      "https://linuxcontainers.org/downloads/lxd/lxd-${version}.tar.gz"
-      "https://github.com/lxc/lxd/releases/download/lxd-${version}/lxd-${version}.tar.gz"
-    ];
-    hash = "sha256-ez/875yu0XYu5ORf4ak6RN1jWGxuGk0n9023zJkoluM=";
+    url = "https://github.com/canonical/lxd/releases/download/lxd-${version}/lxd-${version}.tar.gz";
+    hash = "sha256-evtNPZvnx8rzr/tJkEp0E7BhUBWHBSJdMtZJQk3VZI8=";
   };
 
   vendorHash = null;
@@ -35,7 +32,7 @@ buildGoModule rec {
       --replace "/usr/share/misc/usb.ids" "${hwdata}/share/hwdata/usb.ids"
   '';
 
-  excludedPackages = [ "test" "lxd/db/generate" ];
+  excludedPackages = [ "test" "lxd/db/generate" "lxd-agent" "lxd-migrate" ];
 
   nativeBuildInputs = [ installShellFiles pkg-config ];
   buildInputs = [
@@ -52,10 +49,15 @@ buildGoModule rec {
   tags = [ "libsqlite3" ];
 
   preBuild = ''
-    # required for go-dqlite. See: https://github.com/lxc/lxd/pull/8939
+    # required for go-dqlite. See: https://github.com/canonical/lxd/pull/8939
     export CGO_LDFLAGS_ALLOW="(-Wl,-wrap,pthread_create)|(-Wl,-z,now)"
   '';
 
+  # build static binaries: https://github.com/canonical/lxd/blob/6fd175c45e65cd475d198db69d6528e489733e19/Makefile#L43-L51
+  postBuild = ''
+    make lxd-agent lxd-migrate
+  '';
+
   preCheck =
     let skippedTests = [
       "TestValidateConfig"
@@ -78,14 +80,14 @@ buildGoModule rec {
   passthru.tests.lxd-ui = nixosTests.lxd-ui;
   passthru.ui = callPackage ./ui.nix { };
   passthru.updateScript = gitUpdater {
-    url = "https://github.com/lxc/lxd.git";
+    url = "https://github.com/canonical/lxd.git";
     rev-prefix = "lxd-";
   };
 
   meta = with lib; {
     description = "Daemon based on liblxc offering a REST API to manage containers";
-    homepage = "https://linuxcontainers.org/lxd/";
-    changelog = "https://github.com/lxc/lxd/releases/tag/lxd-${version}";
+    homepage = "https://ubuntu.com/lxd";
+    changelog = "https://github.com/canonical/lxd/releases/tag/lxd-${version}";
     license = licenses.asl20;
     maintainers = with maintainers; [ marsam adamcstephens ];
     platforms = platforms.linux;
diff --git a/pkgs/tools/admin/lxd/ui.nix b/pkgs/tools/admin/lxd/ui.nix
index 3ffcb00a9e378..a6d41659a9da3 100644
--- a/pkgs/tools/admin/lxd/ui.nix
+++ b/pkgs/tools/admin/lxd/ui.nix
@@ -33,8 +33,7 @@ mkYarnPackage rec {
 
   meta = {
     description = "Web user interface for LXD.";
-    homepage = "https://linuxcontainers.org/lxd/";
-    changelog = "https://github.com/canonical/lxd-ui";
+    homepage = "https://github.com/canonical/lxd-ui";
     license = lib.licenses.gpl3;
     maintainers = with lib.maintainers; [ jnsgruk ];
     platforms = lib.platforms.linux;
diff --git a/pkgs/tools/filesystems/dwarfs/default.nix b/pkgs/tools/filesystems/dwarfs/default.nix
index cd774395c2c1d..e5804f3785296 100644
--- a/pkgs/tools/filesystems/dwarfs/default.nix
+++ b/pkgs/tools/filesystems/dwarfs/default.nix
@@ -7,7 +7,7 @@
 , boost
 , cmake
 , double-conversion
-, fmt_8
+, fmt
 , fuse3
 , glog
 , gtest
@@ -20,30 +20,27 @@
 , pkg-config
 , ronn
 , xxHash
+, utf8cpp
 , zstd
 }:
 
 stdenv.mkDerivation rec {
   pname = "dwarfs";
-  version = "0.6.2";
+  version = "0.7.2";
 
   src = fetchFromGitHub {
     owner = "mhx";
     repo = "dwarfs";
     rev = "v${version}";
     fetchSubmodules = true;
-    sha256 = "sha256-fA/3AooDndqYiK215cu/zTqCqeccHnwIX2CfJ9sC+Fc=";
+    hash = "sha256-DcPRrATI2cpLZWAL+sSCoXvJ1R0O3yHqhlJW1aEpDpA=";
   };
 
-  patches = with lib.versions; [
-    (substituteAll {
+  patches = [
+    (with lib.versions; substituteAll {
       src = ./version_info.patch;
 
-      gitRev = "v${version}";
-      gitDesc = "v${version}";
-      gitBranch = "v${version}";
-      gitId = "v${version}"; # displayed as version number
-
+      versionFull = version; # displayed as version number (with v prepended)
       versionMajor = major version;
       versionMinor = minor version;
       versionPatch = patch version;
@@ -54,14 +51,11 @@ stdenv.mkDerivation rec {
     "-DPREFER_SYSTEM_ZSTD=ON"
     "-DPREFER_SYSTEM_XXHASH=ON"
     "-DPREFER_SYSTEM_GTEST=ON"
+    "-DPREFER_SYSTEM_LIBFMT=ON"
 
     # may be added under an option in the future
     # "-DWITH_LEGACY_FUSE=ON"
     "-DWITH_TESTS=ON"
-
-    # temporary hack until folly builds work on aarch64,
-    # see https://github.com/facebook/folly/issues/1880
-    "-DCMAKE_LIBRARY_ARCHITECTURE=${if stdenv.isx86_64 then "x86_64" else "dummy"}"
   ];
 
   nativeBuildInputs = [
@@ -74,12 +68,13 @@ stdenv.mkDerivation rec {
   buildInputs = [
     # dwarfs
     boost
-    fmt_8
+    fmt
     fuse3
     jemalloc
     libarchive
     lz4
     xxHash
+    utf8cpp
     zstd
 
     # folly
@@ -92,9 +87,9 @@ stdenv.mkDerivation rec {
 
   doCheck = true;
   nativeCheckInputs = [ gtest ];
-  # this fails inside of the sandbox due to missing access
+  # these fail inside of the sandbox due to missing access
   # to the FUSE device
-  GTEST_FILTER = "-tools.everything";
+  GTEST_FILTER = "-dwarfs/tools_test.end_to_end/*:dwarfs/tools_test.mutating_ops/*";
 
   meta = with lib; {
     description = "A fast high compression read-only file system";
diff --git a/pkgs/tools/filesystems/dwarfs/version_info.patch b/pkgs/tools/filesystems/dwarfs/version_info.patch
index 59936302ace01..8d62bd8d22957 100644
--- a/pkgs/tools/filesystems/dwarfs/version_info.patch
+++ b/pkgs/tools/filesystems/dwarfs/version_info.patch
@@ -1,6 +1,24 @@
+diff --git a/cmake/package_version.cmake b/cmake/package_version.cmake
+new file mode 100644
+index 0000000..d4fdb9c
+--- /dev/null
++++ b/cmake/package_version.cmake
+@@ -0,0 +1,12 @@
++# autogenerated code, do not modify
++
++set(PRJ_GIT_REV "v@versionFull@")
++set(PRJ_GIT_DESC "v@versionFull@")
++set(PRJ_GIT_BRANCH "HEAD")
++set(PRJ_GIT_ID "v@versionFull@")
++set(PRJ_GIT_RELEASE_TAG "v@versionFull@")
++set(PRJ_VERSION_FULL "@versionFull@")
++set(PRJ_VERSION_SHORT "@versionFull@")
++set(PRJ_VERSION_MAJOR "@versionMajor@")
++set(PRJ_VERSION_MINOR "@versionMinor@")
++set(PRJ_VERSION_PATCH "@versionPatch@")
 diff --git a/include/dwarfs/version.h b/include/dwarfs/version.h
-new file mode 100755
-index 0000000..9b12c59
+new file mode 100644
+index 0000000..54cf86a
 --- /dev/null
 +++ b/include/dwarfs/version.h
 @@ -0,0 +1,16 @@
@@ -21,8 +39,8 @@ index 0000000..9b12c59
 +
 +} // namespace dwarfs
 diff --git a/src/dwarfs/version.cpp b/src/dwarfs/version.cpp
-new file mode 100755
-index 0000000..3af0215
+new file mode 100644
+index 0000000..5759120
 --- /dev/null
 +++ b/src/dwarfs/version.cpp
 @@ -0,0 +1,12 @@
@@ -32,9 +50,9 @@ index 0000000..3af0215
 +
 +namespace dwarfs {
 +
-+char const* PRJ_GIT_REV = "@gitRev@";
-+char const* PRJ_GIT_DESC = "@gitDesc@";
-+char const* PRJ_GIT_BRANCH = "@gitBranch@";
-+char const* PRJ_GIT_ID = "@gitId@";
++char const* PRJ_GIT_REV = "@versionFull@";
++char const* PRJ_GIT_DESC = "v@versionFull@";
++char const* PRJ_GIT_BRANCH = "HEAD";
++char const* PRJ_GIT_ID = "v@versionFull@";
 +
 +} // namespace dwarfs
diff --git a/pkgs/tools/misc/debian-devscripts/default.nix b/pkgs/tools/misc/debian-devscripts/default.nix
index 6109ef3b0c08f..e1ee9757fe89a 100644
--- a/pkgs/tools/misc/debian-devscripts/default.nix
+++ b/pkgs/tools/misc/debian-devscripts/default.nix
@@ -76,6 +76,6 @@ in stdenv.mkDerivation rec {
     description = "Debian package maintenance scripts";
     license = licenses.free; # Mix of public domain, Artistic+GPL, GPL1+, GPL2+, GPL3+, and GPL2-only... TODO
     maintainers = with maintainers; [raskin];
-    platforms = with platforms; linux;
+    platforms = platforms.unix;
   };
 }
diff --git a/pkgs/tools/nix/devour-flake/default.nix b/pkgs/tools/nix/devour-flake/default.nix
new file mode 100644
index 0000000000000..a42483653550f
--- /dev/null
+++ b/pkgs/tools/nix/devour-flake/default.nix
@@ -0,0 +1,27 @@
+{ writeShellApplication
+, fetchFromGitHub
+, nix
+}:
+
+let
+  devour-flake = fetchFromGitHub {
+    owner = "srid";
+    repo = "devour-flake";
+    rev = "v2";
+    hash = "sha256-CZedJtbZlWAbv/b/aYgOEFd9vcTBn/oJNI3p29UitLk=";
+  };
+in
+writeShellApplication {
+  name = "devour-flake";
+  runtimeInputs = [ nix ];
+  text = ''
+    FLAKE="$1"
+    shift 1 || true
+
+    nix build ${devour-flake}#default \
+      "$@" \
+      -L --no-link --print-out-paths \
+      --override-input flake "$FLAKE" \
+      | xargs cat
+  '';
+}
diff --git a/pkgs/tools/nix/nixci/default.nix b/pkgs/tools/nix/nixci/default.nix
new file mode 100644
index 0000000000000..0d881d6976edc
--- /dev/null
+++ b/pkgs/tools/nix/nixci/default.nix
@@ -0,0 +1,38 @@
+{ lib, stdenv
+, rustPlatform
+, fetchCrate
+, libiconv
+, openssl
+, pkg-config
+, Security
+, devour-flake
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "nixci";
+  version = "0.1.3";
+
+  src = fetchCrate {
+    inherit version;
+    pname = "nixci";
+    hash = "sha256-sM/1G1mf+msWbG4CX/pZNt4FmSKR2hWXdcq5h7W1AM0=";
+  };
+
+  cargoHash = "sha256-PKBNQKuWV4PE7iSKr+LugayroFjDBT4/vyyjJiw/E+I=";
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ libiconv openssl ]
+    ++ lib.optionals stdenv.isDarwin [ Security ];
+
+  # The rust program expects an environment (at build time) that points to the
+  # devour-flake executable.
+  DEVOUR_FLAKE = lib.getExe devour-flake;
+
+  meta = with lib; {
+    description = "Define and build CI for Nix projects anywhere";
+    homepage = "https://github.com/srid/nixci";
+    license = licenses.agpl3Only;
+    maintainers = with maintainers; [ srid ];
+    mainProgram = "nixci";
+  };
+}
diff --git a/pkgs/tools/nix/web-devmode.nix b/pkgs/tools/nix/web-devmode.nix
new file mode 100644
index 0000000000000..6ebdc31118f0e
--- /dev/null
+++ b/pkgs/tools/nix/web-devmode.nix
@@ -0,0 +1,117 @@
+{
+  pkgs,
+  # arguments to `nix-build`, e.g. `"foo.nix -A bar"`
+  buildArgs,
+  # what path to open a browser at
+  open,
+}: let
+  inherit (pkgs) lib;
+
+  error_page = pkgs.writeShellScriptBin "error_page" ''
+    echo "<!DOCTYPE html>
+    <html>
+    <head>
+      <style>
+        @media (prefers-color-scheme: dark) {
+          :root { filter: invert(100%); }
+        }
+      </style>
+    </head>
+    <body><pre>$1</pre></body>
+    </html>"
+  '';
+
+  # The following would have been simpler:
+  # 1. serve from `$serve`
+  # 2. pass each build a `--out-link $serve/result`
+  # But that way live-server does not seem to detect changes and therefore no
+  # auto-reloads occur.
+  # Instead, we copy the contents of each build to the `$serve` directory.
+  # Using rsync here, instead of `cp`, to get as close to an atomic
+  # directory copy operation as possible. `--delay-updates` should
+  # also go towards that.
+  build_and_copy = pkgs.writeShellScriptBin "build_and_copy" ''
+    set -euxo pipefail
+
+    set +e
+    stderr=$(2>&1 nix-build --out-link $out_link ${buildArgs})
+    exit_status=$?
+    set -e
+
+    if [ $exit_status -eq 0 ];
+    then
+      # setting permissions to be able to clean up
+      ${lib.getBin pkgs.rsync}/bin/rsync \
+        --recursive \
+        --chmod=u=rwX \
+        --delete-before \
+        --delay-updates \
+        $out_link/ \
+        $serve/
+    else
+      set +x
+      ${lib.getBin error_page}/bin/error_page "$stderr" > $error_page_absolute
+      set -x
+
+      ${lib.getBin pkgs.findutils}/bin/find $serve \
+        -type f \
+        ! -name $error_page_relative \
+        -delete
+    fi
+  '';
+
+  # https://watchexec.github.io/
+  watcher = pkgs.writeShellScriptBin "watcher" ''
+    set -euxo pipefail
+
+    ${lib.getBin pkgs.watchexec}/bin/watchexec \
+      --shell=none \
+      --restart \
+      --print-events \
+      ${lib.getBin build_and_copy}/bin/build_and_copy
+  '';
+
+  # A Rust alternative to live-server exists, but it was not in nixpkgs.
+  # `--no-css-inject`: without this it seems that only CSS is auto-reloaded.
+  # https://www.npmjs.com/package/live-server
+  server = pkgs.writeShellScriptBin "server" ''
+    set -euxo pipefail
+
+    ${lib.getBin pkgs.nodePackages_latest.live-server}/bin/live-server \
+      --host=127.0.0.1 \
+      --verbose \
+      --no-css-inject \
+      --entry-file=$error_page_relative \
+      --open=${open} \
+      $serve
+  '';
+
+  devmode =
+    pkgs.writeShellScriptBin "devmode"
+    ''
+      set -euxo pipefail
+
+      function handle_exit {
+        rm -rf "$tmpdir"
+      }
+
+      tmpdir=$(mktemp -d)
+      trap handle_exit EXIT
+
+      export out_link="$tmpdir/result"
+      export serve="$tmpdir/serve"
+      mkdir $serve
+      export error_page_relative=error.html
+      export error_page_absolute=$serve/$error_page_relative
+      ${lib.getBin error_page}/bin/error_page "building …" > $error_page_absolute
+
+      ${lib.getBin pkgs.parallel}/bin/parallel \
+        --will-cite \
+        --line-buffer \
+        --tagstr '{/}' \
+        ::: \
+        "${lib.getBin watcher}/bin/watcher" \
+        "${lib.getBin server}/bin/server"
+    '';
+in
+  devmode
diff --git a/pkgs/tools/security/enc/default.nix b/pkgs/tools/security/enc/default.nix
index 00d6d0211f80c..646d7c80559eb 100644
--- a/pkgs/tools/security/enc/default.nix
+++ b/pkgs/tools/security/enc/default.nix
@@ -7,17 +7,16 @@
 
 buildGoModule rec {
   pname = "enc";
-  version = "1.1.0";
+  version = "1.1.2";
 
   src = fetchFromGitHub {
     owner = "life4";
     repo = "enc";
-    rev = "v${version}";
-    sha256 = "Tt+J/MnYJNewSl5UeewS0b47NGW2yzfcVHA5+9UQWSs=";
+    rev = version;
+    hash = "sha256-kVK/+pR3Rzg7oCjHKr+i+lK6nhqlBN6Wj92i4SKU2l0=";
   };
-  vendorSha256 = "lB6GkE6prfBG7OCOJ1gm23Ee5+nAgmJg8I9Nqe1fsRw=";
 
-  proxyVendor = true;
+  vendorHash = "sha256-6LNo4iBZDc0DTn8f/2PdCb6CNFCjU6o1xDkB5m/twJk=";
 
   nativeBuildInputs = [ installShellFiles ];
 
diff --git a/pkgs/tools/text/difftastic/Cargo.lock b/pkgs/tools/text/difftastic/Cargo.lock
index 2711be4d25836..25e3c8e41fe29 100644
--- a/pkgs/tools/text/difftastic/Cargo.lock
+++ b/pkgs/tools/text/difftastic/Cargo.lock
@@ -187,9 +187,9 @@ dependencies = [
 
 [[package]]
 name = "crossterm"
-version = "0.25.0"
+version = "0.26.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
+checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13"
 dependencies = [
  "bitflags",
  "crossterm_winapi",
@@ -217,7 +217,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c"
 dependencies = [
  "quote",
- "syn",
+ "syn 1.0.95",
 ]
 
 [[package]]
@@ -234,7 +234,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
 
 [[package]]
 name = "difftastic"
-version = "0.48.0"
+version = "0.49.0"
 dependencies = [
  "assert_cmd",
  "bumpalo",
@@ -621,9 +621,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.39"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
 dependencies = [
  "unicode-ident",
 ]
@@ -636,9 +636,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
 
 [[package]]
 name = "quote"
-version = "1.0.18"
+version = "1.0.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
 dependencies = [
  "proc-macro2",
 ]
@@ -774,24 +774,24 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
 
 [[package]]
 name = "strum"
-version = "0.24.1"
+version = "0.25.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
+checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
 dependencies = [
  "strum_macros",
 ]
 
 [[package]]
 name = "strum_macros"
-version = "0.24.3"
+version = "0.25.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
+checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232"
 dependencies = [
  "heck",
  "proc-macro2",
  "quote",
  "rustversion",
- "syn",
+ "syn 2.0.27",
 ]
 
 [[package]]
@@ -806,6 +806,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "syn"
+version = "2.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
 name = "termcolor"
 version = "1.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/pkgs/tools/text/difftastic/default.nix b/pkgs/tools/text/difftastic/default.nix
index 86b8fd3eacd1f..3842fb6b14734 100644
--- a/pkgs/tools/text/difftastic/default.nix
+++ b/pkgs/tools/text/difftastic/default.nix
@@ -16,13 +16,13 @@ in
 
 rustPlatform.buildRustPackage rec {
   pname = "difftastic";
-  version = "0.48.0";
+  version = "0.49.0";
 
   src = fetchFromGitHub {
     owner = "wilfred";
     repo = pname;
     rev = version;
-    hash = "sha256-kCCORQKqt9rDydxvddD30RMQ1eS73rgvJzCCx93lRuI=";
+    hash = "sha256-jFBvMRkuAaQAi/28BBf/9cm6FcNMOYS5M69YoSXsX4Q=";
   };
 
   cargoLock = {
diff --git a/pkgs/tools/virtualization/distrobuilder/default.nix b/pkgs/tools/virtualization/distrobuilder/default.nix
index a6ae67b07e7bf..ac65ea3f54b9d 100644
--- a/pkgs/tools/virtualization/distrobuilder/default.nix
+++ b/pkgs/tools/virtualization/distrobuilder/default.nix
@@ -38,7 +38,7 @@ buildGoModule rec {
 
   patches = [
     # go.mod update: needed to to include a newer lxd which contains
-    # https://github.com/lxc/lxd/commit/d83f061a21f509d42b7a334b97403d2a019a7b52
+    # https://github.com/canonical/lxd/commit/d83f061a21f509d42b7a334b97403d2a019a7b52
     # which is needed to fix the build w/glibc-2.36.
     (fetchpatch {
       url = "https://github.com/lxc/distrobuilder/commit/5346bcc77dd7f141a36a8da851f016d0b929835e.patch";
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 3515a5d73bc60..dce1ef52a2054 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -577,6 +577,8 @@ with pkgs;
 
   dec-decode = callPackage ../development/tools/dec-decode { };
 
+  devour-flake = callPackage ../tools/nix/devour-flake { };
+
   dnf5 = callPackage ../tools/package-management/dnf5 { };
 
   dsq = callPackage ../tools/misc/dsq { };
@@ -33599,6 +33601,7 @@ with pkgs;
   } // (config.mplayer or {}));
 
   mpv-unwrapped = darwin.apple_sdk_11_0.callPackage ../applications/video/mpv {
+    stdenv = if stdenv.isDarwin then swiftPackages.stdenv else stdenv;
     inherit lua;
   };
 
@@ -40316,6 +40319,10 @@ with pkgs;
 
   alejandra = callPackage ../tools/nix/alejandra { };
 
+  nixci = callPackage ../tools/nix/nixci {
+    inherit (darwin.apple_sdk.frameworks) Security;
+  };
+
   nixfmt = haskellPackages.nixfmt.bin;
 
   nixpkgs-fmt = callPackage ../tools/nix/nixpkgs-fmt { };