about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2024-01-07 18:00:54 +0000
committerGitHub <noreply@github.com>2024-01-07 18:00:54 +0000
commitf85fe5fc293d310e635b6c0363819d7ca1159528 (patch)
tree954bac96e4a7bcb75b1e9865ccd0850b1cabc1e2
parentff42d23313880d627c7dea5addf744db4562dee5 (diff)
parent57a00c9d0456576a5366a5cdebb2bcd12d983971 (diff)
downloadnixlib-f85fe5fc293d310e635b6c0363819d7ca1159528.tar
nixlib-f85fe5fc293d310e635b6c0363819d7ca1159528.tar.gz
nixlib-f85fe5fc293d310e635b6c0363819d7ca1159528.tar.bz2
nixlib-f85fe5fc293d310e635b6c0363819d7ca1159528.tar.lz
nixlib-f85fe5fc293d310e635b6c0363819d7ca1159528.tar.xz
nixlib-f85fe5fc293d310e635b6c0363819d7ca1159528.tar.zst
nixlib-f85fe5fc293d310e635b6c0363819d7ca1159528.zip
Merge master into staging-next
-rw-r--r--maintainers/maintainer-list.nix6
-rw-r--r--nixos/modules/module-list.nix2
-rw-r--r--nixos/modules/programs/firefox.nix1
-rw-r--r--nixos/modules/services/development/nixseparatedebuginfod.nix105
-rw-r--r--nixos/modules/services/security/bitwarden-directory-connector-cli.nix323
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/nixseparatedebuginfod.nix80
-rw-r--r--pkgs/applications/editors/emacs/elisp-packages/manual-packages/wat-mode/default.nix19
-rw-r--r--pkgs/applications/emulators/citra/default.nix8
-rw-r--r--pkgs/applications/emulators/citra/generic.nix6
-rw-r--r--pkgs/applications/misc/electrum/ltc.nix2
-rw-r--r--pkgs/applications/misc/gimoji/default.nix6
-rw-r--r--pkgs/applications/misc/joplin-desktop/default.nix8
-rw-r--r--pkgs/applications/misc/kbt/default.nix6
-rw-r--r--pkgs/applications/networking/cluster/kubedb-cli/default.nix4
-rw-r--r--pkgs/applications/science/misc/snakemake/default.nix34
-rw-r--r--pkgs/applications/version-management/gogs/default.nix7
-rw-r--r--pkgs/applications/virtualization/virt-manager/default.nix10
-rw-r--r--pkgs/by-name/bi/bitwarden-directory-connector-cli/package.nix66
-rw-r--r--pkgs/by-name/me/memtree/package.nix6
-rw-r--r--pkgs/by-name/ni/nixseparatedebuginfod/package.nix49
-rw-r--r--pkgs/data/misc/osinfo-db/default.nix4
-rw-r--r--pkgs/data/themes/alacritty-theme/default.nix2
-rw-r--r--pkgs/development/julia-modules/tests/.gitignore3
-rw-r--r--pkgs/development/julia-modules/tests/README.md25
-rw-r--r--pkgs/development/julia-modules/tests/julia-top-n/app/Main.hs89
-rw-r--r--pkgs/development/julia-modules/tests/julia-top-n/default.nix16
-rw-r--r--pkgs/development/julia-modules/tests/julia-top-n/julia-top-n.cabal34
-rw-r--r--pkgs/development/julia-modules/tests/julia-top-n/package.yaml37
-rw-r--r--pkgs/development/julia-modules/tests/julia-top-n/stack.yaml11
-rw-r--r--pkgs/development/julia-modules/tests/julia-top-n/stack.yaml.lock13
-rwxr-xr-xpkgs/development/julia-modules/tests/process_top_n.py33
-rwxr-xr-xpkgs/development/julia-modules/tests/run_tests.sh15
-rw-r--r--pkgs/development/julia-modules/tests/top-julia-packages.nix28
-rw-r--r--pkgs/development/libraries/physics/fastnlo-toolkit/default.nix (renamed from pkgs/development/libraries/physics/fastnlo_toolkit/default.nix)2
-rw-r--r--pkgs/development/libraries/valhalla/default.nix8
-rw-r--r--pkgs/development/python-modules/py-scrypt/default.nix (renamed from pkgs/development/python-modules/py_scrypt/default.nix)5
-rw-r--r--pkgs/development/python-modules/snakemake-executor-plugin-cluster-generic/default.nix38
-rw-r--r--pkgs/development/python-modules/snakemake-interface-common/default.nix38
-rw-r--r--pkgs/development/python-modules/snakemake-interface-executor-plugins/default.nix40
-rw-r--r--pkgs/development/python-modules/snakemake-interface-storage-plugins/default.nix43
-rw-r--r--pkgs/development/python-modules/thumborpexif/default.nix23
-rw-r--r--pkgs/development/tools/micronaut/default.nix4
-rw-r--r--pkgs/misc/drivers/epkowa/default.nix32
-rw-r--r--pkgs/os-specific/linux/kernel/zen-kernels.nix8
-rw-r--r--pkgs/os-specific/linux/qmk-udev-rules/default.nix7
-rw-r--r--pkgs/servers/monitoring/plugins/default.nix36
-rw-r--r--pkgs/tools/admin/wander/default.nix4
-rw-r--r--pkgs/tools/graphics/maskromtool/default.nix4
-rw-r--r--pkgs/tools/misc/killport/default.nix6
-rw-r--r--pkgs/tools/security/kubernetes-polaris/default.nix4
-rw-r--r--pkgs/top-level/aliases.nix3
-rw-r--r--pkgs/top-level/all-packages.nix2
-rw-r--r--pkgs/top-level/python-aliases.nix3
-rw-r--r--pkgs/top-level/python-packages.nix14
55 files changed, 1271 insertions, 112 deletions
diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix
index 23975a5a33a6..fe4e8bdf24b5 100644
--- a/maintainers/maintainer-list.nix
+++ b/maintainers/maintainer-list.nix
@@ -17018,6 +17018,12 @@
       fingerprint = "ADF4 C13D 0E36 1240 BD01  9B51 D1DE 6D7F 6936 63A5";
     }];
   };
+  Silver-Golden = {
+    name = "Brendan Golden";
+    email = "github+nixpkgs@brendan.ie";
+    github = "Silver-Golden";
+    githubId = 7858375;
+  };
   simarra = {
     name = "simarra";
     email = "loic.martel@protonmail.com";
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 893a49e5763a..5aee2340932c 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -497,6 +497,7 @@
   ./services/development/jupyterhub/default.nix
   ./services/development/livebook.nix
   ./services/development/lorri.nix
+  ./services/development/nixseparatedebuginfod.nix
   ./services/development/rstudio-server/default.nix
   ./services/development/zammad.nix
   ./services/display-managers/greetd.nix
@@ -1175,6 +1176,7 @@
   ./services/search/typesense.nix
   ./services/security/aesmd.nix
   ./services/security/authelia.nix
+  ./services/security/bitwarden-directory-connector-cli.nix
   ./services/security/certmgr.nix
   ./services/security/cfssl.nix
   ./services/security/clamav.nix
diff --git a/nixos/modules/programs/firefox.nix b/nixos/modules/programs/firefox.nix
index 1edf935d1649..29c567783e27 100644
--- a/nixos/modules/programs/firefox.nix
+++ b/nixos/modules/programs/firefox.nix
@@ -284,6 +284,7 @@ in
 
     # Preferences are converted into a policy
     programs.firefox.policies = {
+      DisableAppUpdate = true;
       Preferences = (mapAttrs
         (_: value: { Value = value; Status = cfg.preferencesStatus; })
         cfg.preferences);
diff --git a/nixos/modules/services/development/nixseparatedebuginfod.nix b/nixos/modules/services/development/nixseparatedebuginfod.nix
new file mode 100644
index 000000000000..daf85153d339
--- /dev/null
+++ b/nixos/modules/services/development/nixseparatedebuginfod.nix
@@ -0,0 +1,105 @@
+{ pkgs, lib, config, ... }:
+let
+  cfg = config.services.nixseparatedebuginfod;
+  url = "127.0.0.1:${toString cfg.port}";
+in
+{
+  options = {
+    services.nixseparatedebuginfod = {
+      enable = lib.mkEnableOption "separatedebuginfod, a debuginfod server providing source and debuginfo for nix packages";
+      port = lib.mkOption {
+        description = "port to listen";
+        default = 1949;
+        type = lib.types.port;
+      };
+      nixPackage = lib.mkOption {
+        type = lib.types.package;
+        default = pkgs.nix;
+        defaultText = lib.literalExpression "pkgs.nix";
+        description = ''
+          The version of nix that nixseparatedebuginfod should use as client for the nix daemon. It is strongly advised to use nix version >= 2.18, otherwise some debug info may go missing.
+        '';
+      };
+      allowOldNix = lib.mkOption {
+        type = lib.types.bool;
+        default = false;
+        description = ''
+          Do not fail evaluation when {option}`services.nixseparatedebuginfod.nixPackage` is older than nix 2.18.
+        '';
+      };
+    };
+  };
+  config = lib.mkIf cfg.enable {
+    assertions = [ {
+      assertion = cfg.allowOldNix || (lib.versionAtLeast cfg.nixPackage.version "2.18");
+      message = "nixseparatedebuginfod works better when `services.nixseparatedebuginfod.nixPackage` is set to nix >= 2.18 (instead of ${cfg.nixPackage.name}). Set `services.nixseparatedebuginfod.allowOldNix` to bypass.";
+    } ];
+
+    systemd.services.nixseparatedebuginfod = {
+      wantedBy = [ "multi-user.target" ];
+      wants = [ "nix-daemon.service" ];
+      after = [ "nix-daemon.service" ];
+      path = [ cfg.nixPackage ];
+      serviceConfig = {
+        ExecStart = [ "${pkgs.nixseparatedebuginfod}/bin/nixseparatedebuginfod -l ${url}" ];
+        Restart = "on-failure";
+        CacheDirectory = "nixseparatedebuginfod";
+        # nix does not like DynamicUsers in allowed-users
+        User = "nixseparatedebuginfod";
+        Group = "nixseparatedebuginfod";
+
+        # hardening
+        # Filesystem stuff
+        ProtectSystem = "strict"; # Prevent writing to most of /
+        ProtectHome = true; # Prevent accessing /home and /root
+        PrivateTmp = true; # Give an own directory under /tmp
+        PrivateDevices = true; # Deny access to most of /dev
+        ProtectKernelTunables = true; # Protect some parts of /sys
+        ProtectControlGroups = true; # Remount cgroups read-only
+        RestrictSUIDSGID = true; # Prevent creating SETUID/SETGID files
+        PrivateMounts = true; # Give an own mount namespace
+        RemoveIPC = true;
+        UMask = "0077";
+
+        # Capabilities
+        CapabilityBoundingSet = ""; # Allow no capabilities at all
+        NoNewPrivileges = true; # Disallow getting more capabilities. This is also implied by other options.
+
+        # Kernel stuff
+        ProtectKernelModules = true; # Prevent loading of kernel modules
+        SystemCallArchitectures = "native"; # Usually no need to disable this
+        ProtectKernelLogs = true; # Prevent access to kernel logs
+        ProtectClock = true; # Prevent setting the RTC
+
+        # Networking
+        RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
+
+        # Misc
+        LockPersonality = true; # Prevent change of the personality
+        ProtectHostname = true; # Give an own UTS namespace
+        RestrictRealtime = true; # Prevent switching to RT scheduling
+        MemoryDenyWriteExecute = true; # Maybe disable this for interpreters like python
+        RestrictNamespaces = true;
+      };
+    };
+
+    users.users.nixseparatedebuginfod = {
+      isSystemUser = true;
+      group = "nixseparatedebuginfod";
+    };
+
+    users.groups.nixseparatedebuginfod = { };
+
+    nix.settings.extra-allowed-users = [ "nixseparatedebuginfod" ];
+
+    environment.variables.DEBUGINFOD_URLS = "http://${url}";
+
+    environment.systemPackages = [
+      # valgrind support requires debuginfod-find on PATH
+      (lib.getBin pkgs.elfutils)
+    ];
+
+    environment.etc."gdb/gdbinit.d/nixseparatedebuginfod.gdb".text = "set debuginfod enabled on";
+
+  };
+}
diff --git a/nixos/modules/services/security/bitwarden-directory-connector-cli.nix b/nixos/modules/services/security/bitwarden-directory-connector-cli.nix
new file mode 100644
index 000000000000..18c02e22fd7e
--- /dev/null
+++ b/nixos/modules/services/security/bitwarden-directory-connector-cli.nix
@@ -0,0 +1,323 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}:
+with lib; let
+  cfg = config.services.bitwarden-directory-connector-cli;
+in {
+  options.services.bitwarden-directory-connector-cli = {
+    enable = mkEnableOption "Bitwarden Directory Connector";
+
+    package = mkPackageOption pkgs "bitwarden-directory-connector-cli" {};
+
+    domain = mkOption {
+      type = types.str;
+      description = lib.mdDoc "The domain the Bitwarden/Vaultwarden is accessible on.";
+      example = "https://vaultwarden.example.com";
+    };
+
+    user = mkOption {
+      type = types.str;
+      description = lib.mdDoc "User to run the program.";
+      default = "bwdc";
+    };
+
+    interval = mkOption {
+      type = types.str;
+      default = "*:0,15,30,45";
+      description = lib.mdDoc "The interval when to run the connector. This uses systemd's OnCalendar syntax.";
+    };
+
+    ldap = mkOption {
+      description = lib.mdDoc ''
+        Options to configure the LDAP connection.
+        If you used the desktop application to test the configuration you can find the settings by searching for `ldap` in `~/.config/Bitwarden\ Directory\ Connector/data.json`.
+      '';
+      default = {};
+      type = types.submodule ({
+        config,
+        options,
+        ...
+      }: {
+        freeformType = types.attrsOf (pkgs.formats.json {}).type;
+
+        config.finalJSON = builtins.toJSON (removeAttrs config (filter (x: x == "finalJSON" || ! options.${x}.isDefined or false) (attrNames options)));
+
+        options = {
+          finalJSON = mkOption {
+            type = (pkgs.formats.json {}).type;
+            internal = true;
+            readOnly = true;
+            visible = false;
+          };
+
+          ssl = mkOption {
+            type = types.bool;
+            default = false;
+            description = lib.mdDoc "Whether to use TLS.";
+          };
+          startTls = mkOption {
+            type = types.bool;
+            default = false;
+            description = lib.mdDoc "Whether to use STARTTLS.";
+          };
+
+          hostname = mkOption {
+            type = types.str;
+            description = lib.mdDoc "The host the LDAP is accessible on.";
+            example = "ldap.example.com";
+          };
+
+          port = mkOption {
+            type = types.port;
+            default = 389;
+            description = lib.mdDoc "Port LDAP is accessible on.";
+          };
+
+          ad = mkOption {
+            type = types.bool;
+            default = false;
+            description = lib.mdDoc "Whether the LDAP Server is an Active Directory.";
+          };
+
+          pagedSearch = mkOption {
+            type = types.bool;
+            default = false;
+            description = lib.mdDoc "Whether the LDAP server paginates search results.";
+          };
+
+          rootPath = mkOption {
+            type = types.str;
+            description = lib.mdDoc "Root path for LDAP.";
+            example = "dc=example,dc=com";
+          };
+
+          username = mkOption {
+            type = types.str;
+            description = lib.mdDoc "The user to authenticate as.";
+            example = "cn=admin,dc=example,dc=com";
+          };
+        };
+      });
+    };
+
+    sync = mkOption {
+      description = lib.mdDoc ''
+        Options to configure what gets synced.
+        If you used the desktop application to test the configuration you can find the settings by searching for `sync` in `~/.config/Bitwarden\ Directory\ Connector/data.json`.
+      '';
+      default = {};
+      type = types.submodule ({
+        config,
+        options,
+        ...
+      }: {
+        freeformType = types.attrsOf (pkgs.formats.json {}).type;
+
+        config.finalJSON = builtins.toJSON (removeAttrs config (filter (x: x == "finalJSON" || ! options.${x}.isDefined or false) (attrNames options)));
+
+        options = {
+          finalJSON = mkOption {
+            type = (pkgs.formats.json {}).type;
+            internal = true;
+            readOnly = true;
+            visible = false;
+          };
+
+          removeDisabled = mkOption {
+            type = types.bool;
+            default = true;
+            description = lib.mdDoc "Remove users from bitwarden groups if no longer in the ldap group.";
+          };
+
+          overwriteExisting = mkOption {
+            type = types.bool;
+            default = false;
+            description =
+              lib.mdDoc "Remove and re-add users/groups, See https://bitwarden.com/help/user-group-filters/#overwriting-syncs for more details.";
+          };
+
+          largeImport = mkOption {
+            type = types.bool;
+            default = false;
+            description = lib.mdDoc "Enable if you are syncing more than 2000 users/groups.";
+          };
+
+          memberAttribute = mkOption {
+            type = types.str;
+            description = lib.mdDoc "Attribute that lists members in a LDAP group.";
+            example = "uniqueMember";
+          };
+
+          creationDateAttribute = mkOption {
+            type = types.str;
+            description = lib.mdDoc "Attribute that lists a user's creation date.";
+            example = "whenCreated";
+          };
+
+          useEmailPrefixSuffix = mkOption {
+            type = types.bool;
+            default = false;
+            description = lib.mdDoc "If a user has no email address, combine a username prefix with a suffix value to form an email.";
+          };
+          emailPrefixAttribute = mkOption {
+            type = types.str;
+            description = lib.mdDoc "The attribute that contains the users username.";
+            example = "accountName";
+          };
+          emailSuffix = mkOption {
+            type = types.str;
+            description = lib.mdDoc "Suffix for the email, normally @example.com.";
+            example = "@example.com";
+          };
+
+          users = mkOption {
+            type = types.bool;
+            default = false;
+            description = lib.mdDoc "Sync users.";
+          };
+          userPath = mkOption {
+            type = types.str;
+            description = lib.mdDoc "User directory, relative to root.";
+            default = "ou=users";
+          };
+          userObjectClass = mkOption {
+            type = types.str;
+            description = lib.mdDoc "Class that users must have.";
+            default = "inetOrgPerson";
+          };
+          userEmailAttribute = mkOption {
+            type = types.str;
+            description = lib.mdDoc "Attribute for a users email.";
+            default = "mail";
+          };
+          userFilter = mkOption {
+            type = types.str;
+            description = lib.mdDoc "LDAP filter for users.";
+            example = "(memberOf=cn=sales,ou=groups,dc=example,dc=com)";
+            default = "";
+          };
+
+          groups = mkOption {
+            type = types.bool;
+            default = false;
+            description = lib.mdDoc "Whether to sync ldap groups into BitWarden.";
+          };
+          groupPath = mkOption {
+            type = types.str;
+            description = lib.mdDoc "Group directory, relative to root.";
+            default = "ou=groups";
+          };
+          groupObjectClass = mkOption {
+            type = types.str;
+            description = lib.mdDoc "A class that groups will have.";
+            default = "groupOfNames";
+          };
+          groupNameAttribute = mkOption {
+            type = types.str;
+            description = lib.mdDoc "Attribute for a name of group.";
+            default = "cn";
+          };
+          groupFilter = mkOption {
+            type = types.str;
+            description = lib.mdDoc "LDAP filter for groups.";
+            example = "(cn=sales)";
+            default = "";
+          };
+        };
+      });
+    };
+
+    secrets = {
+      ldap = mkOption {
+        type = types.str;
+        description = "Path to file that contains LDAP password for user in {option}`ldap.username";
+      };
+
+      bitwarden = {
+        client_path_id = mkOption {
+          type = types.str;
+          description = "Path to file that contains Client ID.";
+        };
+        client_path_secret = mkOption {
+          type = types.str;
+          description = "Path to file that contains Client Secret.";
+        };
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    users.groups."${cfg.user}" = {};
+    users.users."${cfg.user}" = {
+      isSystemUser = true;
+      group = cfg.user;
+    };
+
+    systemd = {
+      timers.bitwarden-directory-connector-cli = {
+        description = "Sync timer for Bitwarden Directory Connector";
+        wantedBy = ["timers.target"];
+        after = ["network-online.target"];
+        timerConfig = {
+          OnCalendar = cfg.interval;
+          Unit = "bitwarden-directory-connector-cli.service";
+          Persistent = true;
+        };
+      };
+
+      services.bitwarden-directory-connector-cli = {
+        description = "Main process for Bitwarden Directory Connector";
+        path = [pkgs.jq];
+
+        environment = {
+          BITWARDENCLI_CONNECTOR_APPDATA_DIR = "/tmp";
+          BITWARDENCLI_CONNECTOR_PLAINTEXT_SECRETS = "true";
+        };
+
+        serviceConfig = {
+          Type = "oneshot";
+          User = "${cfg.user}";
+          PrivateTmp = true;
+          preStart = ''
+            set -eo pipefail
+
+            # create the config file
+            ${lib.getExe cfg.package} data-file
+            touch /tmp/data.json.tmp
+            chmod 600 /tmp/data.json{,.tmp}
+
+            ${lib.getExe cfg.package} config server ${cfg.domain}
+
+            # now login to set credentials
+            export BW_CLIENTID="$(< ${escapeShellArg cfg.secrets.bitwarden.client_path_id})"
+            export BW_CLIENTSECRET="$(< ${escapeShellArg cfg.secrets.bitwarden.client_path_secret})"
+            ${lib.getExe cfg.package} login
+
+            jq '.authenticatedAccounts[0] as $account
+              | .[$account].directoryConfigurations.ldap |= $ldap_data
+              | .[$account].directorySettings.organizationId |= $orgID
+              | .[$account].directorySettings.sync |= $sync_data' \
+              --argjson ldap_data ${escapeShellArg cfg.ldap.finalJSON} \
+              --arg orgID "''${BW_CLIENTID//organization.}" \
+              --argjson sync_data ${escapeShellArg cfg.sync.finalJSON} \
+              /tmp/data.json \
+              > /tmp/data.json.tmp
+
+            mv -f /tmp/data.json.tmp /tmp/data.json
+
+            # final config
+            ${lib.getExe cfg.package} config directory 0
+            ${lib.getExe cfg.package} config ldap.password --secretfile ${cfg.secrets.ldap}
+          '';
+
+          ExecStart = "${lib.getExe cfg.package} sync";
+        };
+      };
+    };
+  };
+
+  meta.maintainers = with maintainers; [Silver-Golden];
+}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index b55e4b9fa71f..4b20a6312437 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -605,6 +605,7 @@ in {
   nixos-rebuild-install-bootloader = handleTestOn ["x86_64-linux"] ./nixos-rebuild-install-bootloader.nix {};
   nixos-rebuild-specialisations = handleTestOn ["x86_64-linux"] ./nixos-rebuild-specialisations.nix {};
   nixpkgs = pkgs.callPackage ../modules/misc/nixpkgs/test.nix { inherit evalMinimalConfig; };
+  nixseparatedebuginfod = handleTest ./nixseparatedebuginfod.nix {};
   node-red = handleTest ./node-red.nix {};
   nomad = handleTest ./nomad.nix {};
   non-default-filesystems = handleTest ./non-default-filesystems.nix {};
diff --git a/nixos/tests/nixseparatedebuginfod.nix b/nixos/tests/nixseparatedebuginfod.nix
new file mode 100644
index 000000000000..7c192a73c706
--- /dev/null
+++ b/nixos/tests/nixseparatedebuginfod.nix
@@ -0,0 +1,80 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+let
+  secret-key = "key-name:/COlMSRbehSh6YSruJWjL+R0JXQUKuPEn96fIb+pLokEJUjcK/2Gv8Ai96D7JGay5gDeUTx5wdpPgNvum9YtwA==";
+  public-key = "key-name:BCVI3Cv9hr/AIveg+yRmsuYA3lE8ecHaT4Db7pvWLcA=";
+in
+{
+  name = "nixseparatedebuginfod";
+  /* A binary cache with debug info and source for nix */
+  nodes.cache = { pkgs, ... }: {
+    services.nix-serve = {
+      enable = true;
+      secretKeyFile = builtins.toFile "secret-key" secret-key;
+      openFirewall = true;
+    };
+    system.extraDependencies = [
+      pkgs.nix.debug
+      pkgs.nix.src
+      pkgs.sl
+    ];
+  };
+  /* the machine where we need the debuginfo */
+  nodes.machine = {
+    imports = [
+      ../modules/installer/cd-dvd/channel.nix
+    ];
+    services.nixseparatedebuginfod.enable = true;
+    nix.settings = {
+      substituters = lib.mkForce [ "http://cache:5000" ];
+      trusted-public-keys = [ public-key ];
+    };
+    environment.systemPackages = [
+      pkgs.valgrind
+      pkgs.gdb
+      (pkgs.writeShellScriptBin "wait_for_indexation" ''
+        set -x
+        while debuginfod-find debuginfo /run/current-system/sw/bin/nix |& grep 'File too large'; do
+          sleep 1;
+        done
+      '')
+    ];
+  };
+  testScript = ''
+    start_all()
+    cache.wait_for_unit("nix-serve.service")
+    cache.wait_for_open_port(5000)
+    machine.wait_for_unit("nixseparatedebuginfod.service")
+    machine.wait_for_open_port(1949)
+
+    with subtest("show the config to debug the test"):
+      machine.succeed("nix --extra-experimental-features nix-command show-config |& logger")
+      machine.succeed("cat /etc/nix/nix.conf |& logger")
+    with subtest("check that the binary cache works"):
+      machine.succeed("nix-store -r ${pkgs.sl}")
+
+    # nixseparatedebuginfod needs .drv to associate executable -> source
+    # on regular systems this would be provided by nixos-rebuild
+    machine.succeed("nix-instantiate '<nixpkgs>' -A nix")
+
+    machine.succeed("timeout 600 wait_for_indexation")
+
+    # test debuginfod-find
+    machine.succeed("debuginfod-find debuginfo /run/current-system/sw/bin/nix")
+
+    # test that gdb can fetch source
+    out = machine.succeed("gdb /run/current-system/sw/bin/nix --batch -x ${builtins.toFile "commands" ''
+    start
+    l
+    ''}")
+    print(out)
+    assert 'int main(' in out
+
+    # test that valgrind can display location information
+    # this relies on the fact that valgrind complains about nix
+    # libgc helps in this regard, and we also ask valgrind to show leak kinds
+    # which are usually false positives.
+    out = machine.succeed("valgrind --leak-check=full --show-leak-kinds=all nix-env --version 2>&1")
+    print(out)
+    assert 'main.cc' in out
+  '';
+})
diff --git a/pkgs/applications/editors/emacs/elisp-packages/manual-packages/wat-mode/default.nix b/pkgs/applications/editors/emacs/elisp-packages/manual-packages/wat-mode/default.nix
index 8b2e05e4a9ec..529acfa09721 100644
--- a/pkgs/applications/editors/emacs/elisp-packages/manual-packages/wat-mode/default.nix
+++ b/pkgs/applications/editors/emacs/elisp-packages/manual-packages/wat-mode/default.nix
@@ -1,10 +1,10 @@
 # Manually packaged until it is upstreamed to melpa
 # See https://github.com/devonsparks/wat-mode/issues/1
-{ lib, trivialBuild, fetchFromGitHub, fetchpatch, emacs }:
+{ lib, melpaBuild, fetchFromGitHub, writeText }:
 
-trivialBuild rec {
+melpaBuild rec {
   pname = "wat-mode";
-  version = "unstable-2022-07-13";
+  version = "20220713.1";
 
   src = fetchFromGitHub {
     owner = "devonsparks";
@@ -13,11 +13,16 @@ trivialBuild rec {
     hash = "sha256-jV5V3TRY+D3cPSz3yFwVWn9yInhGOYIaUTPEhsOBxto=";
   };
 
-  meta = with lib; {
+  commit = "46b4df83e92c585295d659d049560dbf190fe501";
+
+  recipe = writeText "recipe" ''
+    (wat-mode :repo "devonsparks/wat-mode" :fetcher github)
+  '';
+
+  meta = {
     homepage = "https://github.com/devonsparks/wat-mode";
     description = "An Emacs major mode for WebAssembly's text format";
-    license = licenses.gpl3Only;
-    maintainers = with maintainers; [ nagy ];
-    inherit (emacs.meta) platforms;
+    license = lib.licenses.gpl3Only;
+    maintainers = with lib.maintainers; [ nagy ];
   };
 }
diff --git a/pkgs/applications/emulators/citra/default.nix b/pkgs/applications/emulators/citra/default.nix
index 960cefc67871..997aadbfb549 100644
--- a/pkgs/applications/emulators/citra/default.nix
+++ b/pkgs/applications/emulators/citra/default.nix
@@ -15,13 +15,13 @@ let
 in {
   nightly = qt6Packages.callPackage ./generic.nix rec {
     pname = "citra-nightly";
-    version = "2043";
+    version = "2070";
 
     src = fetchFromGitHub {
       owner = "citra-emu";
       repo = "citra-nightly";
       rev = "nightly-${version}";
-      sha256 = "sha256-26M3uzqp4rUMOhr619UooupZT11B03IJfamUPNkceQk=";
+      sha256 = "1rmc7dk7wzmxgkq7xsmx9wscszhcfr3mkvnykwgamrcb9bm8p5rb";
       fetchSubmodules = true;
     };
 
@@ -30,13 +30,13 @@ in {
 
   canary = qt6Packages.callPackage ./generic.nix rec {
     pname = "citra-canary";
-    version = "2695";
+    version = "2740";
 
     src = fetchFromGitHub {
       owner = "citra-emu";
       repo = "citra-canary";
       rev = "canary-${version}";
-      sha256 = "sha256-090er4aUGze8bk3DIFZoa+/6EcJhr4bim3nWgZHs1mo=";
+      sha256 = "0m11xy0ad9sy7zsnwnb7vad3g0g78v747a1abp612ybg0aczwf9l";
       fetchSubmodules = true;
     };
 
diff --git a/pkgs/applications/emulators/citra/generic.nix b/pkgs/applications/emulators/citra/generic.nix
index 21b60bb4056e..c167aef7e774 100644
--- a/pkgs/applications/emulators/citra/generic.nix
+++ b/pkgs/applications/emulators/citra/generic.nix
@@ -15,6 +15,7 @@
 , enet
 , ffmpeg
 , fmt
+, gamemode
 , glslang
 , httplib
 , inih
@@ -108,6 +109,9 @@ stdenv.mkDerivation {
 
     # Add versions
     echo 'set(BUILD_FULLNAME "${branchCaptialized} ${version}")' >> CMakeModules/GenerateBuildInfo.cmake
+
+    # Add gamemode
+    substituteInPlace externals/gamemode/include/gamemode_client.h --replace "libgamemode.so.0" "${lib.getLib gamemode}/lib/libgamemode.so.0"
   '';
 
   postInstall = let
@@ -124,7 +128,7 @@ stdenv.mkDerivation {
   meta = with lib; {
     broken = (stdenv.isLinux && stdenv.isAarch64);
     homepage = "https://citra-emu.org";
-    description = "The ${branch} branch of an open-source emulator for the Ninteno 3DS";
+    description = "The ${branch} branch of an open-source emulator for the Nintendo 3DS";
     longDescription = ''
       A Nintendo 3DS Emulator written in C++
       Using the nightly branch is recommended for general usage.
diff --git a/pkgs/applications/misc/electrum/ltc.nix b/pkgs/applications/misc/electrum/ltc.nix
index ed573d1322d5..83738fd18149 100644
--- a/pkgs/applications/misc/electrum/ltc.nix
+++ b/pkgs/applications/misc/electrum/ltc.nix
@@ -65,7 +65,7 @@ python3.pkgs.buildPythonApplication {
     matplotlib
     pbkdf2
     protobuf
-    py_scrypt
+    py-scrypt
     pysocks
     qrcode
     requests
diff --git a/pkgs/applications/misc/gimoji/default.nix b/pkgs/applications/misc/gimoji/default.nix
index 36c29cd2444c..e16d7312f5df 100644
--- a/pkgs/applications/misc/gimoji/default.nix
+++ b/pkgs/applications/misc/gimoji/default.nix
@@ -7,16 +7,16 @@
 
 rustPlatform.buildRustPackage rec {
   pname = "gimoji";
-  version = "0.7.2";
+  version = "0.7.3";
 
   src = fetchFromGitHub {
     owner = "zeenix";
     repo = "gimoji";
     rev = version;
-    hash = "sha256-PF7vjbmoNSBD9C6JOB1s5NHnBEkv1LD/3RZAB0/HFPc=";
+    hash = "sha256-xQ02jmPuu1IHkQCCJn2FVPcJRbwN+k8FhsZyDX0oHaw=";
   };
 
-  cargoHash = "sha256-iJblgcwn9uCl2X0AjG+dlAwdwwyZ321LRBFjDCZOr/A=";
+  cargoHash = "sha256-DSLIH6swVQXHrqKBxlrhNTG5maRmUi6Ndmuuv0Vo3Ak=";
 
   buildInputs = lib.optionals stdenv.isDarwin [
     darwin.apple_sdk.frameworks.AppKit
diff --git a/pkgs/applications/misc/joplin-desktop/default.nix b/pkgs/applications/misc/joplin-desktop/default.nix
index 376038f46cc9..79a97f050149 100644
--- a/pkgs/applications/misc/joplin-desktop/default.nix
+++ b/pkgs/applications/misc/joplin-desktop/default.nix
@@ -2,7 +2,7 @@
 
 let
   pname = "joplin-desktop";
-  version = "2.13.12";
+  version = "2.13.13";
 
   inherit (stdenv.hostPlatform) system;
   throwSystem = throw "Unsupported system: ${system}";
@@ -16,9 +16,9 @@ let
   src = fetchurl {
     url = "https://github.com/laurent22/joplin/releases/download/v${version}/Joplin-${version}${suffix}";
     sha256 = {
-      x86_64-linux = "sha256-h+aprE7D2bZcKgBoOKwPGgiM2Yo05c3TZaR1elOsp70=";
-      x86_64-darwin = "sha256-4VHipPJ3Tkf7NSy7sytk793ApOQm7cRsl5DNO0xjpIw=";
-      aarch64-darwin = "sha256-LW7myTExWblFDke/o/E7tNBRBrkyNkOvnHiztIT7x3Q=";
+      x86_64-linux = "sha256-Cc9NhYrYimj1NjbwnEueQzqC6yCAZi0YUtmJRorarCk=";
+      x86_64-darwin = "sha256-tUdTcr5CkGqEdTuGwZvBmwMW3oCCXwdWnaXjjATHjQg=";
+      aarch64-darwin = "sha256-Xh54WrLbHcbGMkz9ZN07ZuSwelHdj97sH1eQb0cgAQg=";
     }.${system} or throwSystem;
   };
 
diff --git a/pkgs/applications/misc/kbt/default.nix b/pkgs/applications/misc/kbt/default.nix
index 0876bf6c15ef..3960556f4d8e 100644
--- a/pkgs/applications/misc/kbt/default.nix
+++ b/pkgs/applications/misc/kbt/default.nix
@@ -9,16 +9,16 @@
 
 rustPlatform.buildRustPackage rec {
   pname = "kbt";
-  version = "2.0.6";
+  version = "2.1.0";
 
   src = fetchFromGitHub {
     owner = "bloznelis";
     repo = "kbt";
     rev = version;
-    hash = "sha256-G5/Sb/suTUkpR6OGlOawLVGLTthcrp78Y+5mxlndfA4=";
+    hash = "sha256-ROCZDa5eyGF9yE+zdZ4snzdz8+jk+H6ZnqsnCe8JtJw=";
   };
 
-  cargoHash = "sha256-7P93mttZ9W76lpGPKN33cgr4nEaHRlDQWov+TUbDHkM=";
+  cargoHash = "sha256-6zD9WRPWEt0ubppaMRTOusy0zm3z6SGB/5/kMxcJ/Ag=";
 
   nativeBuildInputs = lib.optionals stdenv.isLinux [
     pkg-config
diff --git a/pkgs/applications/networking/cluster/kubedb-cli/default.nix b/pkgs/applications/networking/cluster/kubedb-cli/default.nix
index bb768763fb93..b138c1928256 100644
--- a/pkgs/applications/networking/cluster/kubedb-cli/default.nix
+++ b/pkgs/applications/networking/cluster/kubedb-cli/default.nix
@@ -2,13 +2,13 @@
 
 buildGoModule rec {
   pname = "kubedb-cli";
-  version = "0.40.0";
+  version = "0.40.1";
 
   src = fetchFromGitHub {
     owner = "kubedb";
     repo = "cli";
     rev = "v${version}";
-    sha256 = "sha256-gMSaJM1qDUUHucVMEiN7VyEm2jWDYBPujy3cQ8SRtHk=";
+    sha256 = "sha256-GGZjqXw0Fi5QdQjVrw//sDVA8oRKADCwHeRY22z7bko=";
   };
 
   vendorHash = null;
diff --git a/pkgs/applications/science/misc/snakemake/default.nix b/pkgs/applications/science/misc/snakemake/default.nix
index 3acd66f79084..d279bd1e2cfd 100644
--- a/pkgs/applications/science/misc/snakemake/default.nix
+++ b/pkgs/applications/science/misc/snakemake/default.nix
@@ -1,20 +1,28 @@
 { lib
 , fetchFromGitHub
 , python3
+, runtimeShell
 }:
 
 python3.pkgs.buildPythonApplication rec {
   pname = "snakemake";
-  version = "7.32.4";
+  version = "8.0.1";
   format = "setuptools";
 
   src = fetchFromGitHub {
     owner = "snakemake";
     repo = pname;
     rev = "refs/tags/v${version}";
-    hash = "sha256-9KuMPqvM8ZCTuomc0R9MBxsK3KIpukDTrlwU6MHysK0=";
+    hash = "sha256-F4c/lgp7J6LLye+f3FpzaXz3zM7R+jXxTziPlVbxFxA=";
   };
 
+  postPatch = ''
+    patchShebangs --build tests/
+    patchShebangs --host snakemake/executors/jobscript.sh
+    substituteInPlace snakemake/shell.py \
+      --replace "/bin/sh" "${runtimeShell}"
+  '';
+
   propagatedBuildInputs = with python3.pkgs; [
     appdirs
     configargparse
@@ -23,6 +31,7 @@ python3.pkgs.buildPythonApplication rec {
     docutils
     gitpython
     humanfriendly
+    immutables
     jinja2
     jsonschema
     nbformat
@@ -32,6 +41,9 @@ python3.pkgs.buildPythonApplication rec {
     requests
     reretry
     smart-open
+    snakemake-interface-executor-plugins
+    snakemake-interface-common
+    snakemake-interface-storage-plugins
     stopit
     tabulate
     throttler
@@ -46,31 +58,29 @@ python3.pkgs.buildPythonApplication rec {
   # setup.
 
   nativeCheckInputs = with python3.pkgs; [
+    numpy
     pandas
     pytestCheckHook
     requests-mock
-    pillow
+    snakemake-executor-plugin-cluster-generic
   ];
 
   disabledTestPaths = [
-    "tests/test_slurm.py"
-    "tests/test_tes.py"
-    "tests/test_tibanna.py"
-    "tests/test_linting.py"
-    "tests/test_google_lifesciences.py"
-    "tests/test_conda_python_script/test_script.py"
+    "tests/test_conda_python_3_7_script/test_script.py"
   ];
 
   disabledTests = [
-    # Tests require network access
-    "test_github_issue1396"
-    "test_github_issue1460"
+    "test_deploy_sources"
   ];
 
   pythonImportsCheck = [
     "snakemake"
   ];
 
+  preCheck = ''
+    export HOME="$(mktemp -d)"
+  '';
+
   meta = with lib; {
     homepage = "https://snakemake.github.io";
     license = licenses.mit;
diff --git a/pkgs/applications/version-management/gogs/default.nix b/pkgs/applications/version-management/gogs/default.nix
index e0f20d1467f6..0f3c106a7e1f 100644
--- a/pkgs/applications/version-management/gogs/default.nix
+++ b/pkgs/applications/version-management/gogs/default.nix
@@ -45,5 +45,12 @@ buildGoModule rec {
     license = licenses.mit;
     maintainers = [ maintainers.schneefux ];
     mainProgram = "gogs";
+    knownVulnerabilities = [ ''
+      Gogs has known unpatched vulnerabilities and upstream maintainers appears to be unresponsive.
+
+      More information can be found in forgejo's blogpost: https://forgejo.org/2023-11-release-v1-20-5-1/
+
+      You might want to consider migrating to Gitea or forgejo.
+    '' ];
   };
 }
diff --git a/pkgs/applications/virtualization/virt-manager/default.nix b/pkgs/applications/virtualization/virt-manager/default.nix
index b32256332894..f0bb04b8304f 100644
--- a/pkgs/applications/virtualization/virt-manager/default.nix
+++ b/pkgs/applications/virtualization/virt-manager/default.nix
@@ -17,6 +17,14 @@ python3.pkgs.buildPythonApplication rec {
     hash = "sha256-UgZ58WLXq0U3EDt4311kv0kayVU17In4kwnQ+QN1E7A=";
   };
 
+  patches = [
+    # refresh Fedora tree URLs in virt-install-osinfo* expected XMLs
+    (fetchpatch {
+      url = "https://github.com/virt-manager/virt-manager/commit/6e5c1db6b4a0af96afeb09a09fb2fc2b73308f01.patch";
+      hash = "sha256-zivVo6nHvfB7aHadOouQZCBXn5rY12nxFjQ4FFwjgZI=";
+    })
+  ];
+
   nativeBuildInputs = [
     intltool file
     gobject-introspection # for setup hook populating GI_TYPELIB_PATH
@@ -77,7 +85,7 @@ python3.pkgs.buildPythonApplication rec {
   ];
 
   preCheck = ''
-    export HOME=.
+    export HOME=$(mktemp -d)
   ''; # <- Required for "tests/test_urldetect.py".
 
   postCheck = ''
diff --git a/pkgs/by-name/bi/bitwarden-directory-connector-cli/package.nix b/pkgs/by-name/bi/bitwarden-directory-connector-cli/package.nix
new file mode 100644
index 000000000000..24376014a120
--- /dev/null
+++ b/pkgs/by-name/bi/bitwarden-directory-connector-cli/package.nix
@@ -0,0 +1,66 @@
+{
+  lib,
+  buildNpmPackage,
+  fetchFromGitHub,
+  buildPackages,
+  python3,
+  pkg-config,
+  libsecret,
+  nodejs_18,
+}:
+buildNpmPackage rec {
+  pname = "bitwarden-directory-connector-cli";
+  version = "2023.10.0";
+  nodejs = nodejs_18;
+
+  src = fetchFromGitHub {
+    owner = "bitwarden";
+    repo = "directory-connector";
+    rev = "v${version}";
+    hash = "sha256-PlOtTh+rpTxAv8ajHBDHZuL7yeeLVpbAfKEDPQlejIg=";
+  };
+
+  postPatch = ''
+    ${lib.getExe buildPackages.jq} 'del(.scripts.preinstall)' package.json > package.json.tmp
+    mv -f package.json{.tmp,}
+  '';
+
+  npmDepsHash = "sha256-jBAWWY12qeX2EDhUvT3TQpnQvYXRsIilRrXGpVzxYvw=";
+
+  env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
+
+  makeCacheWritable = true;
+  npmBuildScript = "build:cli:prod";
+
+  installPhase = ''
+    runHook preInstall
+    mkdir -p $out/libexec/bitwarden-directory-connector
+    cp -R {build-cli,node_modules} $out/libexec/bitwarden-directory-connector
+    runHook postInstall
+  '';
+
+  # needs to be wrapped with nodejs so that it can be executed
+  postInstall = ''
+    chmod +x $out/libexec/bitwarden-directory-connector/build-cli/bwdc.js
+    mkdir -p $out/bin
+    ln -s $out/libexec/bitwarden-directory-connector/build-cli/bwdc.js $out/bin/bitwarden-directory-connector-cli
+  '';
+
+  buildInputs = [
+    libsecret
+  ];
+
+  nativeBuildInputs = [
+    python3
+    pkg-config
+  ];
+
+  meta = with lib; {
+    description = "LDAP connector for Bitwarden";
+    homepage = "https://github.com/bitwarden/directory-connector";
+    license = licenses.gpl3Only;
+    maintainers = with maintainers; [Silver-Golden];
+    platforms = platforms.linux;
+    mainProgram = "bitwarden-directory-connector-cli";
+  };
+}
diff --git a/pkgs/by-name/me/memtree/package.nix b/pkgs/by-name/me/memtree/package.nix
index f69c3f8e95d3..528323624805 100644
--- a/pkgs/by-name/me/memtree/package.nix
+++ b/pkgs/by-name/me/memtree/package.nix
@@ -6,14 +6,14 @@
 
 python3Packages.buildPythonApplication {
   pname = "memtree";
-  version = "unstable-2023-11-22";
+  version = "unstable-2024-01-04";
   pyproject = true;
 
   src = fetchFromGitHub {
     owner = "nbraud";
     repo = "memtree";
-    rev = "edc09d91dcd72f175d6adc1d08b261dd95cc4fbf";
-    hash = "sha256-YLZm0wjkjaTw/lHY5k4cqPXCgINe+49SGPLZq+eRdI4=";
+    rev = "97615952eabdc5e8e1a4bd590dd1f4971f3c5a24";
+    hash = "sha256-Ifp8hwkuyBw57fGer3GbDiJaRjL4TD3hzj+ecGXWqI0=";
   };
 
   nativeBuildInputs = with python3Packages; [
diff --git a/pkgs/by-name/ni/nixseparatedebuginfod/package.nix b/pkgs/by-name/ni/nixseparatedebuginfod/package.nix
new file mode 100644
index 000000000000..faacd2330d3f
--- /dev/null
+++ b/pkgs/by-name/ni/nixseparatedebuginfod/package.nix
@@ -0,0 +1,49 @@
+{ lib
+, fetchFromGitHub
+, rustPlatform
+, libarchive
+, openssl
+, sqlite
+, pkg-config
+, nixosTests
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "nixseparatedebuginfod";
+  version = "0.3.2";
+
+  src = fetchFromGitHub {
+    owner = "symphorien";
+    repo = "nixseparatedebuginfod";
+    rev = "v${version}";
+    hash = "sha256-XSEHNoc3h21foVeR28KgfiBTRHyUh+GJ52LMD2xFHfA=";
+  };
+
+  cargoHash = "sha256-t6W6siHuga/T9kmanA735zH2i9eCOT7vD6v7E5LIp9k=";
+
+  # tests need a working nix install with access to the internet
+  doCheck = false;
+
+  buildInputs = [
+    libarchive
+    openssl
+    sqlite
+  ];
+
+  nativeBuildInputs = [ pkg-config ];
+
+  passthru = {
+    tests = {
+      inherit (nixosTests) nixseparatedebuginfod;
+    };
+  };
+
+  meta = with lib; {
+    description = "Downloads and provides debug symbols and source code for nix derivations to gdb and other debuginfod-capable debuggers as needed";
+    homepage = "https://github.com/symphorien/nixseparatedebuginfod";
+    license = licenses.gpl3Only;
+    maintainers = [ maintainers.symphorien ];
+    platforms = platforms.linux;
+    mainProgram = "nixseparatedebuginfod";
+  };
+}
diff --git a/pkgs/data/misc/osinfo-db/default.nix b/pkgs/data/misc/osinfo-db/default.nix
index e563c2133187..6689902ed56f 100644
--- a/pkgs/data/misc/osinfo-db/default.nix
+++ b/pkgs/data/misc/osinfo-db/default.nix
@@ -8,11 +8,11 @@
 
 stdenv.mkDerivation rec {
   pname = "osinfo-db";
-  version = "20230308";
+  version = "20231215";
 
   src = fetchurl {
     url = "https://releases.pagure.org/libosinfo/${pname}-${version}.tar.xz";
-    sha256 = "sha256-VGugTsxekzui1/PztDM6KYDUrk38UoSYm5xUdY8rkIg=";
+    hash = "sha256-37fFl1zk7//ZKq3QAJSg98WTtBmI/aU5kV9kWfcWRVQ=";
   };
 
   nativeBuildInputs = [
diff --git a/pkgs/data/themes/alacritty-theme/default.nix b/pkgs/data/themes/alacritty-theme/default.nix
index ea5a426f624a..a60f42107ce4 100644
--- a/pkgs/data/themes/alacritty-theme/default.nix
+++ b/pkgs/data/themes/alacritty-theme/default.nix
@@ -22,7 +22,7 @@ stdenvNoCC.mkDerivation (self: {
   sourceRoot = "${self.src.name}/themes";
   installPhase = ''
     runHook preInstall
-    install -Dt $out *.yaml
+    install -Dt $out *.toml
     runHook postInstall
   '';
 
diff --git a/pkgs/development/julia-modules/tests/.gitignore b/pkgs/development/julia-modules/tests/.gitignore
new file mode 100644
index 000000000000..07d2f69d765b
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/.gitignore
@@ -0,0 +1,3 @@
+test_runs/
+.stack-work/
+*~
diff --git a/pkgs/development/julia-modules/tests/README.md b/pkgs/development/julia-modules/tests/README.md
new file mode 100644
index 000000000000..1be3487161e6
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/README.md
@@ -0,0 +1,25 @@
+
+# Testing `julia.withPackages`
+
+This folder contains a test suite for ensuring that the top N most popular Julia packages (as measured by download count) work properly. The key parts are
+
+* `top-julia-packages.nix`: an impure derivation for fetching Julia download data and processing it into a file called `top-julia-packages.yaml`. This YAML file contains an array of objects with fields "name", "uuid", and "count", and is sorted in decreasing order of count.
+* `julia-top-n`: a small Haskell program which reads `top-julia-packages.yaml` and builds a `julia.withPackages` environment for each package, with a nice interactive display and configurable parallelism. It also tests whether evaluating `using <package-name>` works in the resulting environment.
+
+> **Warning:**
+> These tests should only be run on maintainer machines, not Hydra! `julia.withPackages` uses IFD, which is not allowed in Hydra.
+
+## Quick start
+
+``` shell
+# Test the top 100 Julia packages
+./run_tests.sh -n 100
+```
+
+## Options
+
+You can run `./run_tests.sh --help` to see additional options for the test harness. The main ones are
+
+* `-n`/`--top-n`: how many of the top packages to build (default: 100).
+* `-p`/`--parallelism`: how many builds to run at once (default: 10).
+* `-c`/`--count-file`: path to `top-julia-packages.yaml`.
diff --git a/pkgs/development/julia-modules/tests/julia-top-n/app/Main.hs b/pkgs/development/julia-modules/tests/julia-top-n/app/Main.hs
new file mode 100644
index 000000000000..ed9f8d405b12
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/julia-top-n/app/Main.hs
@@ -0,0 +1,89 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE ViewPatterns #-}
+
+module Main (main) where
+
+import Control.Exception
+import Control.Monad
+import Data.Aeson as A hiding (Options, defaultOptions)
+import qualified Data.Aeson.Key             as A
+import qualified Data.Aeson.KeyMap          as HM
+import qualified Data.ByteString.Lazy.Char8 as BL8
+import qualified Data.List as L
+import Data.Text as T
+import qualified Data.Vector as V
+import qualified Data.Yaml as Yaml
+import GHC.Generics
+import Options.Applicative
+import System.Exit
+import System.FilePath
+import Test.Sandwich hiding (info)
+import UnliftIO.MVar
+import UnliftIO.Process
+
+
+data Args = Args {
+  countFilePath :: FilePath
+  , topN :: Int
+  , parallelism :: Int
+  }
+
+argsParser :: Parser Args
+argsParser = Args
+  <$> strOption (long "count-file" <> short 'c' <> help "YAML file containing package names and counts")
+  <*> option auto (long "top-n" <> short 'n' <> help "How many of the top packages to build" <> showDefault <> value 100 <> metavar "INT")
+  <*> option auto (long "parallelism" <> short 'p' <> help "How many builds to run at once" <> showDefault <> value 10 <> metavar "INT")
+
+data NameAndCount = NameAndCount {
+  name :: Text
+  , count :: Int
+  , uuid :: Text
+  } deriving (Show, Eq, Generic, FromJSON)
+
+newtype JuliaPath = JuliaPath FilePath
+  deriving Show
+
+julia :: Label "julia" (MVar (Maybe JuliaPath))
+julia = Label
+
+main :: IO ()
+main = do
+  clo <- parseCommandLineArgs argsParser (return ())
+  let Args {..} = optUserOptions clo
+
+  namesAndCounts :: [NameAndCount] <- Yaml.decodeFileEither countFilePath >>= \case
+    Left err -> throwIO $ userError ("Couldn't decode names and counts YAML file: " <> show err)
+    Right x -> pure x
+
+  runSandwichWithCommandLineArgs' defaultOptions argsParser $
+    describe ("Building environments for top " <> show topN <> " Julia packages") $
+      parallelN parallelism $
+        forM_ (L.take topN namesAndCounts) $ \(NameAndCount {..}) ->
+          introduce' (defaultNodeOptions { nodeOptionsVisibilityThreshold = 0 }) (T.unpack name) julia (newMVar Nothing) (const $ return ()) $ do
+            it "Builds" $ do
+              let cp = proc "nix" ["build", "--impure", "--no-link", "--json", "--expr"
+                                  , "with import ../../../../. {}; julia.withPackages [\"" <> T.unpack name <> "\"]"
+                                  ]
+              output <- readCreateProcessWithLogging cp ""
+              juliaPath <- case A.eitherDecode (BL8.pack output) of
+                Right (A.Array ((V.!? 0) -> Just (A.Object (aesonLookup "outputs" -> Just (A.Object (aesonLookup "out" -> Just (A.String t))))))) -> pure (JuliaPath ((T.unpack t) </> "bin" </> "julia"))
+                x -> expectationFailure ("Couldn't parse output: " <> show x)
+
+              getContext julia >>= flip modifyMVar_ (const $ return (Just juliaPath))
+
+            it "Uses" $ do
+              getContext julia >>= readMVar >>= \case
+                Nothing -> expectationFailure "Build step failed."
+                Just (JuliaPath juliaPath) -> do
+                  let cp = proc juliaPath ["-e", "using " <> T.unpack name]
+                  createProcessWithLogging cp >>= waitForProcess >>= (`shouldBe` ExitSuccess)
+
+aesonLookup :: Text -> HM.KeyMap v -> Maybe v
+aesonLookup = HM.lookup . A.fromText
diff --git a/pkgs/development/julia-modules/tests/julia-top-n/default.nix b/pkgs/development/julia-modules/tests/julia-top-n/default.nix
new file mode 100644
index 000000000000..ab8ed948e1ea
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/julia-top-n/default.nix
@@ -0,0 +1,16 @@
+{ mkDerivation, aeson, base, filepath, lib, optparse-applicative
+, sandwich, text, unliftio, yaml
+}:
+mkDerivation {
+  pname = "julia-top-n";
+  version = "0.1.0.0";
+  src = ./.;
+  isLibrary = false;
+  isExecutable = true;
+  executableHaskellDepends = [
+    aeson base filepath optparse-applicative sandwich text unliftio
+    yaml
+  ];
+  license = lib.licenses.bsd3;
+  mainProgram = "julia-top-n-exe";
+}
diff --git a/pkgs/development/julia-modules/tests/julia-top-n/julia-top-n.cabal b/pkgs/development/julia-modules/tests/julia-top-n/julia-top-n.cabal
new file mode 100644
index 000000000000..834adac33f16
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/julia-top-n/julia-top-n.cabal
@@ -0,0 +1,34 @@
+cabal-version: 2.2
+
+-- This file has been generated from package.yaml by hpack version 0.36.0.
+--
+-- see: https://github.com/sol/hpack
+
+name:           julia-top-n
+version:        0.1.0.0
+author:         Tom McLaughlin
+maintainer:     tom@codedown.io
+license:        BSD-3-Clause
+build-type:     Simple
+
+executable julia-top-n-exe
+  main-is: Main.hs
+  other-modules:
+      Paths_julia_top_n
+  autogen-modules:
+      Paths_julia_top_n
+  hs-source-dirs:
+      app
+  ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      aeson
+    , base >=4.7 && <5
+    , bytestring
+    , filepath
+    , optparse-applicative
+    , sandwich
+    , text
+    , unliftio
+    , vector
+    , yaml
+  default-language: Haskell2010
diff --git a/pkgs/development/julia-modules/tests/julia-top-n/package.yaml b/pkgs/development/julia-modules/tests/julia-top-n/package.yaml
new file mode 100644
index 000000000000..ffb9ab1d12ea
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/julia-top-n/package.yaml
@@ -0,0 +1,37 @@
+name:                julia-top-n
+version:             0.1.0.0
+license:             BSD-3-Clause
+author:              "Tom McLaughlin"
+maintainer:          "tom@codedown.io"
+
+dependencies:
+- aeson
+- base >= 4.7 && < 5
+- bytestring
+- filepath
+- optparse-applicative
+- sandwich
+- text
+- unliftio
+- vector
+- yaml
+
+ghc-options:
+- -Wall
+- -Wcompat
+- -Widentities
+- -Wincomplete-record-updates
+- -Wincomplete-uni-patterns
+- -Wmissing-export-lists
+- -Wmissing-home-modules
+- -Wpartial-fields
+- -Wredundant-constraints
+
+executables:
+  julia-top-n-exe:
+    main:                Main.hs
+    source-dirs:         app
+    ghc-options:
+    - -threaded
+    - -rtsopts
+    - -with-rtsopts=-N
diff --git a/pkgs/development/julia-modules/tests/julia-top-n/stack.yaml b/pkgs/development/julia-modules/tests/julia-top-n/stack.yaml
new file mode 100644
index 000000000000..28bbc5a5f7ef
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/julia-top-n/stack.yaml
@@ -0,0 +1,11 @@
+
+resolver:
+  url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/4.yaml
+
+packages:
+- .
+
+nix:
+  pure: false
+  packages:
+  - zlib
diff --git a/pkgs/development/julia-modules/tests/julia-top-n/stack.yaml.lock b/pkgs/development/julia-modules/tests/julia-top-n/stack.yaml.lock
new file mode 100644
index 000000000000..3e782d80cc43
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/julia-top-n/stack.yaml.lock
@@ -0,0 +1,13 @@
+# This file was autogenerated by Stack.
+# You should not edit this file by hand.
+# For more information, please see the documentation at:
+#   https://docs.haskellstack.org/en/stable/lock_files
+
+packages: []
+snapshots:
+- completed:
+    sha256: 8b211c5a6aad3787e023dfddaf7de7868968e4f240ecedf14ad1c5b2199046ca
+    size: 714097
+    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/4.yaml
+  original:
+    url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/22/4.yaml
diff --git a/pkgs/development/julia-modules/tests/process_top_n.py b/pkgs/development/julia-modules/tests/process_top_n.py
new file mode 100755
index 000000000000..90de70ccec4d
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/process_top_n.py
@@ -0,0 +1,33 @@
+#! /usr/bin/env nix-shell
+#! nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ pyyaml toml ])"
+
+import csv
+from pathlib import Path
+import sys
+import toml
+import yaml
+
+requests_csv_path = Path(sys.argv[1])
+registry_path = Path(sys.argv[2])
+
+# Generate list of tuples (UUID, count)
+rows = []
+with open(requests_csv_path) as f:
+  reader = csv.reader(f)
+  for row in reader:
+    if row[2] == "user":
+      # Get UUID and request_count
+      rows.append((row[0], int(row[4])))
+rows.sort(key=(lambda x: x[1]), reverse=True)
+
+# Build a map from UUID -> name
+registry = toml.load(registry_path / "Registry.toml")
+uuid_to_name = {k: v["name"] for k, v in registry["packages"].items()}
+
+results = []
+for (uuid, count) in rows:
+  name = uuid_to_name.get(uuid)
+  if not name: continue
+  results.append({ "uuid": uuid, "name": uuid_to_name.get(uuid), "count": count })
+
+yaml.dump(results, sys.stdout, default_flow_style=False)
diff --git a/pkgs/development/julia-modules/tests/run_tests.sh b/pkgs/development/julia-modules/tests/run_tests.sh
new file mode 100755
index 000000000000..c7537c801d98
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/run_tests.sh
@@ -0,0 +1,15 @@
+#! /usr/bin/env nix-shell
+#! nix-shell -i bash -p jq
+
+set -eo pipefail
+
+SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $SCRIPTDIR
+
+TOP_N_FILE=$(nix build --impure -f top-julia-packages.nix --no-link --json | jq -r '.[0].outputs.out')
+echo "Got top Julia packages: $TOP_N_FILE"
+
+TESTER_PROGRAM=$(nix build --impure --expr 'with import ../../../../. {}; haskellPackages.callPackage ./julia-top-n {}' --no-link --json | jq -r '.[0].outputs.out')/bin/julia-top-n-exe
+echo "Built tester program: $TESTER_PROGRAM"
+
+"$TESTER_PROGRAM" --tui -c "$TOP_N_FILE" $*
diff --git a/pkgs/development/julia-modules/tests/top-julia-packages.nix b/pkgs/development/julia-modules/tests/top-julia-packages.nix
new file mode 100644
index 000000000000..ca93f42875b3
--- /dev/null
+++ b/pkgs/development/julia-modules/tests/top-julia-packages.nix
@@ -0,0 +1,28 @@
+with import ../../../../. {};
+
+let
+  package-requests = stdenv.mkDerivation {
+    name = "julia-package-requests.csv";
+
+    __impure = true;
+
+    buildInputs = [cacert gzip wget];
+
+    buildCommand = ''
+      wget https://julialang-logs.s3.amazonaws.com/public_outputs/current/package_requests.csv.gz
+      gunzip package_requests.csv.gz
+      ls -lh
+      cp package_requests.csv $out
+    '';
+  };
+
+  registry = callPackage ../registry.nix {};
+
+in
+
+runCommand "top-julia-packages.yaml" {
+  __impure = true;
+  nativeBuildInputs = [(python3.withPackages (ps: with ps; [pyyaml toml]))];
+} ''
+  python ${./process_top_n.py} ${package-requests} ${registry} > $out
+''
diff --git a/pkgs/development/libraries/physics/fastnlo_toolkit/default.nix b/pkgs/development/libraries/physics/fastnlo-toolkit/default.nix
index 049cfcb04d5a..66a3bf5128f5 100644
--- a/pkgs/development/libraries/physics/fastnlo_toolkit/default.nix
+++ b/pkgs/development/libraries/physics/fastnlo-toolkit/default.nix
@@ -14,7 +14,7 @@
 }:
 
 stdenv.mkDerivation rec {
-  pname = "fastnlo_toolkit";
+  pname = "fastnlo-toolkit";
   version = "2.5.0-2826";
 
   src = fetchurl {
diff --git a/pkgs/development/libraries/valhalla/default.nix b/pkgs/development/libraries/valhalla/default.nix
index bfd23747db0a..8ad3bb9c356c 100644
--- a/pkgs/development/libraries/valhalla/default.nix
+++ b/pkgs/development/libraries/valhalla/default.nix
@@ -36,6 +36,14 @@ stdenv.mkDerivation (finalAttrs: {
       url = "https://github.com/valhalla/valhalla/commit/e4845b68e8ef8de9eabb359b23bf34c879e21f2b.patch";
       hash = "sha256-xCufmXHGj1JxaMwm64JT9FPY+o0+x4glfJSYLdvHI8U=";
     })
+
+    # Fix gcc-13 build:
+    #   https://github.com/valhalla/valhalla/pull/4154
+    (fetchpatch {
+      name = "gcc-13.patch";
+      url = "https://github.com/valhalla/valhalla/commit/ed93f30272377cc6803533a1bb94fe81d14af81c.patch";
+      hash = "sha256-w4pnOqk/Jj3unVuesE64QSecrUIVSqwK69t9xNVc4GA=";
+    })
   ];
 
   postPatch = ''
diff --git a/pkgs/development/python-modules/py_scrypt/default.nix b/pkgs/development/python-modules/py-scrypt/default.nix
index 5ecedd0d4c5c..5525c62b4e16 100644
--- a/pkgs/development/python-modules/py_scrypt/default.nix
+++ b/pkgs/development/python-modules/py-scrypt/default.nix
@@ -5,11 +5,12 @@
 }:
 
 buildPythonPackage rec {
-  pname = "scrypt";
+  pname = "py-scrypt";
   version = "0.8.20";
 
   src = fetchPypi {
-    inherit pname version;
+    pname = "scrypt";
+    inherit version;
     hash = "sha256-DSJsHGdE+y4wizkUEGabHfXP6CY3/8te1Im/grLS63g=";
   };
 
diff --git a/pkgs/development/python-modules/snakemake-executor-plugin-cluster-generic/default.nix b/pkgs/development/python-modules/snakemake-executor-plugin-cluster-generic/default.nix
new file mode 100644
index 000000000000..17b0aeed0bae
--- /dev/null
+++ b/pkgs/development/python-modules/snakemake-executor-plugin-cluster-generic/default.nix
@@ -0,0 +1,38 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, poetry-core
+, snakemake-interface-executor-plugins
+, snakemake-interface-common
+}:
+
+buildPythonPackage rec {
+  pname = "snakemake-executor-plugin-cluster-generic";
+  version = "1.0.7";
+  format = "pyproject";
+
+  src = fetchFromGitHub {
+    owner = "snakemake";
+    repo = pname;
+    rev = "refs/tags/v${version}";
+    hash = "sha256-1W/8jf+R1798cu3sWI0LTSyVawtmFfwlAqRHwfmIAzU=";
+  };
+
+  nativeBuildInputs = [
+    poetry-core
+  ];
+
+  propagatedBuildInputs = [
+    snakemake-interface-executor-plugins
+    snakemake-interface-common
+  ];
+
+  pythonImportsCheck = [ "snakemake_executor_plugin_cluster_generic" ];
+
+  meta = with lib; {
+    description = "Generic cluster executor for Snakemake";
+    homepage = "https://github.com/snakemake/snakemake-executor-plugin-cluster-generic/tags";
+    license = licenses.mit;
+    maintainers = with maintainers; [ veprbl ];
+  };
+}
diff --git a/pkgs/development/python-modules/snakemake-interface-common/default.nix b/pkgs/development/python-modules/snakemake-interface-common/default.nix
new file mode 100644
index 000000000000..d8a326112c33
--- /dev/null
+++ b/pkgs/development/python-modules/snakemake-interface-common/default.nix
@@ -0,0 +1,38 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, poetry-core
+, argparse-dataclass
+, ConfigArgParse
+}:
+
+buildPythonPackage rec {
+  pname = "snakemake-interface-common";
+  version = "1.15.0";
+  format = "pyproject";
+
+  src = fetchFromGitHub {
+    owner = "snakemake";
+    repo = pname;
+    rev = "refs/tags/v${version}";
+    hash = "sha256-Rf2eMkRvkTCR2swB53ekjv8U8DzTPgjhIkBVrn6gTTI=";
+  };
+
+  nativeBuildInputs = [
+    poetry-core
+  ];
+
+  propagatedBuildInputs = [
+    argparse-dataclass
+    ConfigArgParse
+  ];
+
+  pythonImportsCheck = [ "snakemake_interface_common" ];
+
+  meta = with lib; {
+    description = "Common functions and classes for Snakemake and its plugins";
+    homepage = "https://github.com/snakemake/snakemake-interface-common";
+    license = licenses.mit;
+    maintainers = with maintainers; [ veprbl ];
+  };
+}
diff --git a/pkgs/development/python-modules/snakemake-interface-executor-plugins/default.nix b/pkgs/development/python-modules/snakemake-interface-executor-plugins/default.nix
new file mode 100644
index 000000000000..358fdd614163
--- /dev/null
+++ b/pkgs/development/python-modules/snakemake-interface-executor-plugins/default.nix
@@ -0,0 +1,40 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, poetry-core
+, argparse-dataclass
+, throttler
+, snakemake-interface-common
+}:
+
+buildPythonPackage rec {
+  pname = "snakemake-interface-executor-plugins";
+  version = "8.1.3";
+  format = "pyproject";
+
+  src = fetchFromGitHub {
+    owner = "snakemake";
+    repo = pname;
+    rev = "refs/tags/v${version}";
+    hash = "sha256-QBLdqhR6WrO/zT0Ux5xcUtr5HbrDy91qiWuSjAA5c3E=";
+  };
+
+  nativeBuildInputs = [
+    poetry-core
+  ];
+
+  propagatedBuildInputs = [
+    argparse-dataclass
+    throttler
+    snakemake-interface-common
+  ];
+
+  pythonImportsCheck = [ "snakemake_interface_executor_plugins" ];
+
+  meta = with lib; {
+    description = "This package provides a stable interface for interactions between Snakemake and its executor plugins";
+    homepage = "https://github.com/snakemake/snakemake-interface-executor-plugins";
+    license = licenses.mit;
+    maintainers = with maintainers; [ veprbl ];
+  };
+}
diff --git a/pkgs/development/python-modules/snakemake-interface-storage-plugins/default.nix b/pkgs/development/python-modules/snakemake-interface-storage-plugins/default.nix
new file mode 100644
index 000000000000..3d37ec8471ec
--- /dev/null
+++ b/pkgs/development/python-modules/snakemake-interface-storage-plugins/default.nix
@@ -0,0 +1,43 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, poetry-core
+, reretry
+, snakemake-interface-common
+, throttler
+, wrapt
+, snakemake
+}:
+
+buildPythonPackage rec {
+  pname = "snakemake-interface-storage-plugins";
+  version = "3.0.0";
+  format = "pyproject";
+
+  src = fetchFromGitHub {
+    owner = "snakemake";
+    repo = pname;
+    rev = "refs/tags/v${version}";
+    hash = "sha256-MinqSMpBlp3pCgQxorkMdrJuO0GExJsO02kg2/mGsFw=";
+  };
+
+  nativeBuildInputs = [
+    poetry-core
+  ];
+
+  propagatedBuildInputs = [
+    reretry
+    snakemake-interface-common
+    throttler
+    wrapt
+  ];
+
+  pythonImportsCheck = [ "snakemake_interface_storage_plugins" ];
+
+  meta = with lib; {
+    description = "This package provides a stable interface for interactions between Snakemake and its storage plugins";
+    homepage = "https://github.com/snakemake/snakemake-interface-storage-plugins";
+    license = licenses.mit;
+    maintainers = with maintainers; [ veprbl ];
+  };
+}
diff --git a/pkgs/development/python-modules/thumborpexif/default.nix b/pkgs/development/python-modules/thumborpexif/default.nix
deleted file mode 100644
index 28b2e5a9f93c..000000000000
--- a/pkgs/development/python-modules/thumborpexif/default.nix
+++ /dev/null
@@ -1,23 +0,0 @@
-{ lib
-, buildPythonPackage
-, fetchPypi
-, isPy27
-}:
-
-buildPythonPackage rec {
-  pname = "thumbor-pexif";
-  version = "0.14.1";
-  disabled = ! isPy27;
-
-  src = fetchPypi {
-    inherit pname version;
-    sha256 = "96dcc03ea6066d9546baf54f6841f4048b0b24a291eed65d098b3348c8872d99";
-  };
-
-  meta = with lib; {
-    description = "Module to parse and edit the EXIF data tags in a JPEG image";
-    homepage = "http://www.benno.id.au/code/pexif/";
-    license = licenses.mit;
-  };
-
-}
diff --git a/pkgs/development/tools/micronaut/default.nix b/pkgs/development/tools/micronaut/default.nix
index 2cda52135e97..92db12ce89ac 100644
--- a/pkgs/development/tools/micronaut/default.nix
+++ b/pkgs/development/tools/micronaut/default.nix
@@ -2,11 +2,11 @@
 
 stdenv.mkDerivation rec {
   pname = "micronaut";
-  version = "4.2.2";
+  version = "4.2.3";
 
   src = fetchzip {
     url = "https://github.com/micronaut-projects/micronaut-starter/releases/download/v${version}/micronaut-cli-${version}.zip";
-    sha256 = "sha256-3YKKFWJvTwe/g/+9yAYHTU6chE48zdXpKXDpwLlM7eU=";
+    sha256 = "sha256-+03wjNxIZr8vhvK3zfvFBwXC5WmEs5A6mydGXsmGuCI=";
   };
 
   nativeBuildInputs = [ makeWrapper installShellFiles ];
diff --git a/pkgs/misc/drivers/epkowa/default.nix b/pkgs/misc/drivers/epkowa/default.nix
index cf54b048f591..460ebb8a3af0 100644
--- a/pkgs/misc/drivers/epkowa/default.nix
+++ b/pkgs/misc/drivers/epkowa/default.nix
@@ -287,6 +287,38 @@ let plugins = {
     };
     meta = common_meta // { description = "iscan GT-X750 for " + passthru.hw; };
   };
+  gt1500 = stdenv.mkDerivation rec {
+    name = "iscan-gt-1500-bundle";
+    version = "2.30.4";
+
+    src = fetchurl {
+      urls = [
+        "https://download2.ebz.epson.net/iscan/plugin/gt-1500/rpm/x64/iscan-gt-1500-bundle-${version}.x64.rpm.tar.gz"
+        "https://web.archive.org/web/https://download2.ebz.epson.net/iscan/plugin/gt-1500/rpm/x64/iscan-gt-1500-bundle-${version}.x64.rpm.tar.gz"
+      ];
+      sha256 = "sha256-1rVsbBsb+QtCOT1FsyhgvCbZIN6IeQH7rZXNmsD7cl8=";
+    };
+
+    nativeBuildInputs = [ autoPatchelfHook rpm ];
+
+    installPhase = ''
+      cd plugins
+      ${rpm}/bin/rpm2cpio iscan-plugin-gt-1500-*.x86_64.rpm | ${cpio}/bin/cpio -idmv
+      mkdir $out
+      cp -r usr/share $out
+      cp -r usr/lib64 $out/lib
+      mv $out/share/iscan $out/share/esci
+      mv $out/lib/iscan $out/lib/esci
+    '';
+
+    passthru = {
+      registrationCommand = ''
+        $registry --add interpreter usb 0x04b8 0x0133 "$plugin/lib/esci/libesint86 $plugin/share/esci/esfw86.bin"
+      '';
+      hw = "GT-1500";
+    };
+    meta = common_meta // { description = "iscan GT-1500 for " + passthru.hw; };
+  };
   network = stdenv.mkDerivation rec {
     pname = "iscan-nt-bundle";
     # for the version, look for the driver of XP-750 in the search page
diff --git a/pkgs/os-specific/linux/kernel/zen-kernels.nix b/pkgs/os-specific/linux/kernel/zen-kernels.nix
index ab5b7c04e9f6..526533e44222 100644
--- a/pkgs/os-specific/linux/kernel/zen-kernels.nix
+++ b/pkgs/os-specific/linux/kernel/zen-kernels.nix
@@ -4,16 +4,16 @@ let
   # comments with variant added for update script
   # ./update-zen.py zen
   zenVariant = {
-    version = "6.6.9"; #zen
+    version = "6.6.10"; #zen
     suffix = "zen1"; #zen
-    sha256 = "09vrkwyx4ri6ba48jfv8j4ssj0h0w2wgzqwwb8ribif1rkb59mw0"; #zen
+    sha256 = "1hhy5jp1s65vpvrw9xylx3xl7mmagzmm5r9bq81hvvr7bhf754ny"; #zen
     isLqx = false;
   };
   # ./update-zen.py lqx
   lqxVariant = {
-    version = "6.6.9"; #lqx
+    version = "6.6.10"; #lqx
     suffix = "lqx1"; #lqx
-    sha256 = "1ivf4iwxjp28xmfk8y3wxs64jqrjzgn6xwxkpad3mxc9n18yl8hz"; #lqx
+    sha256 = "1rfia3cbs81gjvr8r1w4kgi3ghr3plqyzaiglifbdr1zkxjias44"; #lqx
     isLqx = true;
   };
   zenKernelsFor = { version, suffix, sha256, isLqx }: buildLinux (args // {
diff --git a/pkgs/os-specific/linux/qmk-udev-rules/default.nix b/pkgs/os-specific/linux/qmk-udev-rules/default.nix
index 5b627ea9033b..bd322bfa100e 100644
--- a/pkgs/os-specific/linux/qmk-udev-rules/default.nix
+++ b/pkgs/os-specific/linux/qmk-udev-rules/default.nix
@@ -1,18 +1,17 @@
 { lib, stdenv, fetchFromGitHub }:
 
 ## Usage
-# In NixOS, simply add this package to services.udev.packages:
-#   services.udev.packages = [ pkgs.qmk-udev-rules ];
+# In NixOS, set hardware.keyboard.qmk.enable = true;
 
 stdenv.mkDerivation rec {
   pname = "qmk-udev-rules";
-  version = "0.22.3";
+  version = "0.23.3";
 
   src = fetchFromGitHub {
     owner = "qmk";
     repo = "qmk_firmware";
     rev = version;
-    hash = "sha256-HLQxmBlzTdsOAMqfc4taoMM+V2G5novMsbc1drZlNGg=";
+    hash = "sha256-dFc6S9x7sBYZAQn0coZJpmGz66Fx0l4rrexjyB4k0zA=";
   };
 
   dontBuild = true;
diff --git a/pkgs/servers/monitoring/plugins/default.nix b/pkgs/servers/monitoring/plugins/default.nix
index 6f3d8c5ffd89..ae0db59d0b32 100644
--- a/pkgs/servers/monitoring/plugins/default.nix
+++ b/pkgs/servers/monitoring/plugins/default.nix
@@ -1,7 +1,7 @@
 { lib
 , stdenv
 , fetchFromGitHub
-, writeShellScript
+, fetchpatch
 , autoreconfHook
 , pkg-config
 , runCommand
@@ -40,25 +40,33 @@ let
     mkdir -p $out/bin
     ln -s /run/wrappers/bin/sendmail $out/bin/mailq
   '';
-
-  # For unknown reasons the installer tries executing $out/share and fails so
-  # we create it and remove it again later.
-  share = writeShellScript "share" ''
-    exit 0
-  '';
-
 in
 stdenv.mkDerivation rec {
   pname = "monitoring-plugins";
-  version = "2.3.0";
+  version = "2.3.5";
 
   src = fetchFromGitHub {
     owner = "monitoring-plugins";
     repo = "monitoring-plugins";
-    rev = "v" + lib.versions.majorMinor version;
-    sha256 = "sha256-yLhHOSrPFRjW701aOL8LPe4OnuJxL6f+dTxNqm0evIg=";
+    rev = "v${version}";
+    sha256 = "sha256-J9fzlxIpujoG7diSRscFhmEV9HpBOxFTJSmGGFjAzcM=";
   };
 
+  patches = [
+    # fix build (makefile cannot produce -lcrypto)
+    # remove on next release
+    (fetchpatch {
+      url = "https://github.com/monitoring-plugins/monitoring-plugins/commit/bad156676894a2755c8b76519a11cdd2037e5cd6.patch";
+      hash = "sha256-aI/sX04KXe968SwdS8ZamNtgdNbHtho5cDsDaA+cjZY=";
+    })
+    # fix check_smtp with --starttls https://github.com/monitoring-plugins/monitoring-plugins/pull/1952
+    # remove on next release
+    (fetchpatch {
+      url = "https://github.com/monitoring-plugins/monitoring-plugins/commit/2eea6bb2a04bbfb169bac5f0f7c319f998e8ab87.patch";
+      hash = "sha256-CyVD340+zOxuxRRPmtowD3DFFRB1Q7+AANzul9HqwBI=";
+    })
+  ];
+
   # TODO: Awful hack. Grrr...
   # Anyway the check that configure performs to figure out the ping
   # syntax is totally impure, because it runs an actual ping to
@@ -78,8 +86,6 @@ stdenv.mkDerivation rec {
       --with-ping-command='${lib.getBin unixtools.ping}/bin/ping -4 -n -U -w %d -c %d %s'
       --with-ping6-command='${lib.getBin unixtools.ping}/bin/ping -6 -n -U -w %d -c %d %s'
     )
-
-    install -Dm555 ${share} $out/share
   '';
 
   configureFlags = [
@@ -107,10 +113,6 @@ stdenv.mkDerivation rec {
 
   enableParallelBuilding = true;
 
-  postInstall = ''
-    rm $out/share
-  '';
-
   meta = with lib; {
     description = "Official monitoring plugins for Nagios/Icinga/Sensu and others";
     homepage = "https://www.monitoring-plugins.org";
diff --git a/pkgs/tools/admin/wander/default.nix b/pkgs/tools/admin/wander/default.nix
index 43d3400ccf55..c3b086806ca1 100644
--- a/pkgs/tools/admin/wander/default.nix
+++ b/pkgs/tools/admin/wander/default.nix
@@ -2,13 +2,13 @@
 
 buildGoModule rec {
   pname = "wander";
-  version = "0.14.1";
+  version = "1.0.0";
 
   src = fetchFromGitHub {
     owner = "robinovitch61";
     repo = pname;
     rev = "v${version}";
-    sha256 = "sha256-ULttOJcP3LHQAlyJKGEKT3B3PqYOP5+IxDej673020M=";
+    sha256 = "sha256-zz9DqRrylCbUCSBl4wspb8BYfmCyQhMmmYwdsbTExbo=";
   };
 
   vendorHash = "sha256-0S8tzP5yNUrH6fp+v7nbUPTMWzYXyGw+ZNcXkSN+tWY=";
diff --git a/pkgs/tools/graphics/maskromtool/default.nix b/pkgs/tools/graphics/maskromtool/default.nix
index ca4381e78a03..77a4d9e268bb 100644
--- a/pkgs/tools/graphics/maskromtool/default.nix
+++ b/pkgs/tools/graphics/maskromtool/default.nix
@@ -9,13 +9,13 @@
 
 stdenv.mkDerivation rec {
   pname = "maskromtool";
-  version = "2023-12-07";
+  version = "2024-01-1";
 
   src = fetchFromGitHub {
     owner = "travisgoodspeed";
     repo = "maskromtool";
     rev = "v${version}";
-    hash = "sha256-2bwgvdXPbSiG2BE2vkT2ThjdkrWgt3v8U729sBMuymg=";
+    hash = "sha256-iKzq0hH45uHtWr2QZsVSPUZjmU6rXUGqVQ8SlIhOuJ0=";
   };
 
   buildInputs = [
diff --git a/pkgs/tools/misc/killport/default.nix b/pkgs/tools/misc/killport/default.nix
index fa906506fff1..d043385f2069 100644
--- a/pkgs/tools/misc/killport/default.nix
+++ b/pkgs/tools/misc/killport/default.nix
@@ -5,14 +5,14 @@
 
 rustPlatform.buildRustPackage rec {
   pname = "killport";
-  version = "0.9.1";
+  version = "0.9.2";
 
   src = fetchCrate {
     inherit pname version;
-    hash = "sha256-aaKvrWJGZ26wyqoblAcUkGUPkbt8XNx9Z4xT+qI2B3o=";
+    hash = "sha256-eyRI4ZVp9HPMvpzyV9sQdh2r966pCdyUPnEhxGkzH3Q=";
   };
 
-  cargoHash = "sha256-4CUMt5aDHq943uU5PAY1TJtmCqlBvgOruGQ69OG5fB4=";
+  cargoHash = "sha256-QQ43dT9BTu7qCzpnTGKzlVL6jKDXofXStYWYNLHSuVs=";
 
   nativeBuildInputs = [ rustPlatform.bindgenHook ];
 
diff --git a/pkgs/tools/security/kubernetes-polaris/default.nix b/pkgs/tools/security/kubernetes-polaris/default.nix
index 25a1d869dd34..885106528483 100644
--- a/pkgs/tools/security/kubernetes-polaris/default.nix
+++ b/pkgs/tools/security/kubernetes-polaris/default.nix
@@ -2,13 +2,13 @@
 
 buildGoModule rec {
   pname = "kubernetes-polaris";
-  version = "8.5.3";
+  version = "8.5.4";
 
   src = fetchFromGitHub {
     owner = "FairwindsOps";
     repo = "polaris";
     rev = version;
-    sha256 = "sha256-dDB1afMtuK4SySa5HX6LhOnPUXlKSzpJDJ+/1SCcB/0=";
+    sha256 = "sha256-Ip8SJi77QjNF2ez2NU48NKi+suOhViecuQyXSY6hLkI=";
   };
 
   vendorHash = "sha256-ZWetW+Xar4BXXlR0iG+O/NRqYk41x+PPVCGis2W2Nkk=";
diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix
index e40ba0c78328..ccbeaced8a6a 100644
--- a/pkgs/top-level/aliases.nix
+++ b/pkgs/top-level/aliases.nix
@@ -264,7 +264,8 @@ mapAliases ({
   ### F ###
 
   faustStk = faustPhysicalModeling; # Added 2023-05-16
-  fastnlo = fastnlo_toolkit; # Added 2021-04-24
+  fastnlo = fastnlo-toolkit; # Added 2021-04-24
+  fastnlo_toolkit = fastnlo-toolkit; # Added 2024-01-03
   inherit (luaPackages) fennel; # Added 2022-09-24
   fetchFromGithub = throw "You meant fetchFromGitHub, with a capital H"; # preserve
   findimagedupes = throw "findimagedupes has been removed because the perl bindings are no longer compatible"; # Added 2023-07-10
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 4be6b2ead562..09fd4a7f9909 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -40016,7 +40016,7 @@ with pkgs;
 
   fastjet-contrib = callPackage ../development/libraries/physics/fastjet-contrib { };
 
-  fastnlo_toolkit = callPackage ../development/libraries/physics/fastnlo_toolkit { };
+  fastnlo-toolkit = callPackage ../development/libraries/physics/fastnlo-toolkit { };
 
   geant4 = libsForQt5.callPackage ../development/libraries/physics/geant4 { };
 
diff --git a/pkgs/top-level/python-aliases.nix b/pkgs/top-level/python-aliases.nix
index 7237cf689402..5a6be8b4b8f9 100644
--- a/pkgs/top-level/python-aliases.nix
+++ b/pkgs/top-level/python-aliases.nix
@@ -145,6 +145,7 @@ mapAliases ({
   face_recognition_models = face-recognition-models; # added 2022-10-15
   factory_boy = factory-boy; # added 2023-10-08
   fake_factory = throw "fake_factory has been removed because it is unused and deprecated by upstream since 2016."; # added 2022-05-30
+  fastnlo_toolkit = fastnlo-toolkit; # added 2024-01-03
   faulthandler = throw "faulthandler is built into ${python.executable}"; # added 2021-07-12
   inherit (super.pkgs) fetchPypi; # added 2023-05-25
   filebrowser_safe = filebrowser-safe; # added 2024-01-03
@@ -359,6 +360,7 @@ mapAliases ({
   Pyro5 = pyro5; # added 2023-02-19
   PyRSS2Gen = pyrss2gen; # added 2023-02-19
   pyruckus = throw "pyruckus has been removed, it was deprecrated in favor of aioruckus."; # added 2023-09-07
+  py_scrypt = py-scrypt; # added 2024-01-07
   pysha3 = throw "pysha3 has been removed, use safe-pysha3 instead"; # added 2023-05-20
   pysmart-smartx = pysmart; # added 2021-10-22
   pySmartDL = pysmartdl; # added 2023-10-11
@@ -467,6 +469,7 @@ mapAliases ({
   Theano = theano; # added 2023-02-19
   TheanoWithCuda = theanoWithCuda; # added 2023-02-19
   TheanoWithoutCuda = theanoWithoutCuda; # added 2023-02-19
+  thumborPexif = throw "thumborPexif has been removed, because it was unused."; # added 2024-01-07
   torrent_parser = torrent-parser; # added 2023-11-04
   transip = throw "transip has been removed because it is no longer maintained. TransIP SOAP V5 API was marked as deprecated"; # added 2023-02-27
   tumpa = throw "tumpa was promoted to a top-level attribute"; # added 2022-11-19
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index 39c76601dd20..4bd67bc7b97e 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -3928,7 +3928,7 @@ self: super: with self; {
 
   fastjsonschema = callPackage ../development/python-modules/fastjsonschema { };
 
-  fastnlo_toolkit = toPythonModule (pkgs.fastnlo_toolkit.override {
+  fastnlo-toolkit = toPythonModule (pkgs.fastnlo-toolkit.override {
     withPython = true;
     inherit (self) python;
   });
@@ -11155,7 +11155,7 @@ self: super: with self; {
 
   pyscreeze = callPackage ../development/python-modules/pyscreeze { };
 
-  py_scrypt = callPackage ../development/python-modules/py_scrypt { };
+  py-scrypt = callPackage ../development/python-modules/py-scrypt { };
 
   pyscrypt = callPackage ../development/python-modules/pyscrypt { };
 
@@ -13328,6 +13328,14 @@ self: super: with self; {
     inherit (self) python;
   });
 
+  snakemake-executor-plugin-cluster-generic = callPackage ../development/python-modules/snakemake-executor-plugin-cluster-generic { };
+
+  snakemake-interface-common = callPackage ../development/python-modules/snakemake-interface-common { };
+
+  snakemake-interface-executor-plugins = callPackage ../development/python-modules/snakemake-interface-executor-plugins { };
+
+  snakemake-interface-storage-plugins = callPackage ../development/python-modules/snakemake-interface-storage-plugins { };
+
   snakebite = callPackage ../development/python-modules/snakebite { };
 
   snakeviz = callPackage ../development/python-modules/snakeviz { };
@@ -14278,8 +14286,6 @@ self: super: with self; {
 
   throttler = callPackage ../development/python-modules/throttler { };
 
-  thumborPexif = callPackage ../development/python-modules/thumborpexif { };
-
   tkinter = callPackage ../development/python-modules/tkinter {
     py = python.override { x11Support=true; };
   };