about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2022-03-11 06:01:28 +0000
committerGitHub <noreply@github.com>2022-03-11 06:01:28 +0000
commitcb2a59dda7b112020c8bbe78f63a7bcd706cdbe4 (patch)
tree6c1ac74c7d35a481f8586446949e7582e98b23ee
parenta4c1084dad00ee05b8b8c5a654e784ac22daeb17 (diff)
parent267148d196cb0742fa38e11e67a60a47022f492c (diff)
downloadnixlib-cb2a59dda7b112020c8bbe78f63a7bcd706cdbe4.tar
nixlib-cb2a59dda7b112020c8bbe78f63a7bcd706cdbe4.tar.gz
nixlib-cb2a59dda7b112020c8bbe78f63a7bcd706cdbe4.tar.bz2
nixlib-cb2a59dda7b112020c8bbe78f63a7bcd706cdbe4.tar.lz
nixlib-cb2a59dda7b112020c8bbe78f63a7bcd706cdbe4.tar.xz
nixlib-cb2a59dda7b112020c8bbe78f63a7bcd706cdbe4.tar.zst
nixlib-cb2a59dda7b112020c8bbe78f63a7bcd706cdbe4.zip
Merge master into staging-next
-rwxr-xr-xlib/tests/modules.sh3
-rw-r--r--lib/tests/modules/adhoc-freeformType-survives-type-merge.nix14
-rw-r--r--lib/types.nix4
-rw-r--r--maintainers/maintainer-list.nix6
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2205.section.xml7
-rw-r--r--nixos/doc/manual/release-notes/rl-2205.section.md2
-rw-r--r--nixos/modules/module-list.nix2
-rw-r--r--nixos/modules/programs/nbd.nix19
-rw-r--r--nixos/modules/services/networking/nbd.nix146
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/nbd.nix87
-rw-r--r--pkgs/applications/audio/puddletag/default.nix54
-rw-r--r--pkgs/applications/misc/obsidian/default.nix159
-rw-r--r--pkgs/applications/networking/instant-messengers/nheko/default.nix6
-rw-r--r--pkgs/development/libraries/mtxclient/default.nix4
-rw-r--r--pkgs/development/python-modules/chromaprint/default.nix32
-rw-r--r--pkgs/development/python-modules/deep-translator/default.nix4
-rw-r--r--pkgs/development/python-modules/glean-parser/default.nix4
-rw-r--r--pkgs/os-specific/linux/iwd/default.nix8
-rw-r--r--pkgs/os-specific/linux/zfs/default.nix18
-rw-r--r--pkgs/tools/networking/nbd/default.nix6
-rw-r--r--pkgs/top-level/python-packages.nix2
22 files changed, 488 insertions, 100 deletions
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh
index e4bb7ad21900..350fe85e7487 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -311,6 +311,9 @@ checkConfigOutput '^"hello"$' config.theOption.str ./optionTypeMerging.nix
 # Test that types.optionType correctly annotates option locations
 checkConfigError 'The option .theOption.nested. in .other.nix. is already declared in .optionTypeFile.nix.' config.theOption.nested ./optionTypeFile.nix
 
+# Test that types.optionType leaves types untouched as long as they don't need to be merged
+checkConfigOutput 'ok' config.freeformItems.foo.bar ./adhoc-freeformType-survives-type-merge.nix
+
 cat <<EOF
 ====== module tests ======
 $pass Pass
diff --git a/lib/tests/modules/adhoc-freeformType-survives-type-merge.nix b/lib/tests/modules/adhoc-freeformType-survives-type-merge.nix
new file mode 100644
index 000000000000..3cefb543c256
--- /dev/null
+++ b/lib/tests/modules/adhoc-freeformType-survives-type-merge.nix
@@ -0,0 +1,14 @@
+{ lib, ... }: {
+  options.dummy = lib.mkOption { type = lib.types.anything; default = {}; };
+  freeformType =
+    let
+      a = lib.types.attrsOf (lib.types.submodule { options.bar = lib.mkOption { }; });
+    in
+    # modifying types like this breaks type merging.
+    # This test makes sure that type merging is not performed when only a single declaration exists.
+    # Don't modify types in practice!
+    a // {
+      merge = loc: defs: { freeformItems = a.merge loc defs; };
+    };
+  config.foo.bar = "ok";
+}
diff --git a/lib/types.nix b/lib/types.nix
index 3fcac9c31b31..2e7261f7553c 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -535,7 +535,9 @@ rec {
       description = "optionType";
       check = value: value._type or null == "option-type";
       merge = loc: defs:
-        let
+        if length defs == 1
+        then (head defs).value
+        else let
           # Prepares the type definitions for mergeOptionDecls, which
           # annotates submodules types with file locations
           optionModules = map ({ value, file }:
diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix
index 57d5157bd689..077381e8d30b 100644
--- a/maintainers/maintainer-list.nix
+++ b/maintainers/maintainer-list.nix
@@ -9260,6 +9260,12 @@
     githubId = 23431373;
     name = "Christoph Neidahl";
   };
+  opeik = {
+    email = "sandro@stikic.com";
+    github = "opeik";
+    githubId = 11566773;
+    name = "Sandro Stikić";
+  };
   orbekk = {
     email = "kjetil.orbekk@gmail.com";
     github = "orbekk";
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
index 664fa1b03690..9cf27e56827a 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
@@ -258,6 +258,13 @@
       </listitem>
       <listitem>
         <para>
+          <link xlink:href="https://nbd.sourceforge.io/">nbd</link>, a
+          Network Block Device server. Available as
+          <link xlink:href="options.html#opt-services.nbd.server.enable">services.nbd</link>.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
           <link xlink:href="https://timetagger.app">timetagger</link>,
           an open source time-tracker with an intuitive user experience
           and powerful reporting.
diff --git a/nixos/doc/manual/release-notes/rl-2205.section.md b/nixos/doc/manual/release-notes/rl-2205.section.md
index c65428ea7e7d..58a1b23d17bf 100644
--- a/nixos/doc/manual/release-notes/rl-2205.section.md
+++ b/nixos/doc/manual/release-notes/rl-2205.section.md
@@ -75,6 +75,8 @@ In addition to numerous new and upgraded packages, this release has the followin
 - [ethercalc](https://github.com/audreyt/ethercalc), an online collaborative
   spreadsheet. Available as [services.ethercalc](options.html#opt-services.ethercalc.enable).
 
+- [nbd](https://nbd.sourceforge.io/), a Network Block Device server. Available as [services.nbd](options.html#opt-services.nbd.server.enable).
+
 - [timetagger](https://timetagger.app), an open source time-tracker with an intuitive user experience and powerful reporting. [services.timetagger](options.html#opt-services.timetagger.enable).
 
 - [rstudio-server](https://www.rstudio.com/products/rstudio/#rstudio-server), a browser-based version of the RStudio IDE for the R programming language. Available as [services.rstudio-server](options.html#opt-services.rstudio-server.enable).
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 6430993d5c63..ff95d6500b9c 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -180,6 +180,7 @@
   ./programs/msmtp.nix
   ./programs/mtr.nix
   ./programs/nano.nix
+  ./programs/nbd.nix
   ./programs/neovim.nix
   ./programs/nm-applet.nix
   ./programs/npm.nix
@@ -819,6 +820,7 @@
   ./services/networking/nar-serve.nix
   ./services/networking/nat.nix
   ./services/networking/nats.nix
+  ./services/networking/nbd.nix
   ./services/networking/ndppd.nix
   ./services/networking/nebula.nix
   ./services/networking/networkmanager.nix
diff --git a/nixos/modules/programs/nbd.nix b/nixos/modules/programs/nbd.nix
new file mode 100644
index 000000000000..fea9bc1ff71a
--- /dev/null
+++ b/nixos/modules/programs/nbd.nix
@@ -0,0 +1,19 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.programs.nbd;
+in
+{
+  options = {
+    programs.nbd = {
+      enable = mkEnableOption "Network Block Device (nbd) support";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = with pkgs; [ nbd ];
+    boot.kernelModules = [ "nbd" ];
+  };
+}
diff --git a/nixos/modules/services/networking/nbd.nix b/nixos/modules/services/networking/nbd.nix
new file mode 100644
index 000000000000..87f8c41a8e5c
--- /dev/null
+++ b/nixos/modules/services/networking/nbd.nix
@@ -0,0 +1,146 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.nbd;
+  configFormat = pkgs.formats.ini { };
+  iniFields = with types; attrsOf (oneOf [ bool int float str ]);
+  serverConfig = configFormat.generate "nbd-server-config"
+    ({
+      generic =
+        (cfg.server.extraOptions // {
+          user = "root";
+          group = "root";
+          port = cfg.server.listenPort;
+        } // (optionalAttrs (cfg.server.listenAddress != null) {
+          listenaddr = cfg.server.listenAddress;
+        }));
+    }
+    // (mapAttrs
+      (_: { path, allowAddresses, extraOptions }:
+        extraOptions // {
+          exportname = path;
+        } // (optionalAttrs (allowAddresses != null) {
+          authfile = pkgs.writeText "authfile" (concatStringsSep "\n" allowAddresses);
+        }))
+      cfg.server.exports)
+    );
+  splitLists =
+    partition
+      (path: hasPrefix "/dev/" path)
+      (mapAttrsToList (_: { path, ... }: path) cfg.server.exports);
+  allowedDevices = splitLists.right;
+  boundPaths = splitLists.wrong;
+in
+{
+  options = {
+    services.nbd = {
+      server = {
+        enable = mkEnableOption "the Network Block Device (nbd) server";
+
+        listenPort = mkOption {
+          type = types.port;
+          default = 10809;
+          description = "Port to listen on. The port is NOT automatically opened in the firewall.";
+        };
+
+        extraOptions = mkOption {
+          type = iniFields;
+          default = {
+            allowlist = false;
+          };
+          description = ''
+            Extra options for the server. See
+            <citerefentry><refentrytitle>nbd-server</refentrytitle>
+            <manvolnum>5</manvolnum></citerefentry>.
+          '';
+        };
+
+        exports = mkOption {
+          description = "Files or block devices to make available over the network.";
+          default = { };
+          type = with types; attrsOf
+            (submodule {
+              options = {
+                path = mkOption {
+                  type = str;
+                  description = "File or block device to export.";
+                  example = "/dev/sdb1";
+                };
+
+                allowAddresses = mkOption {
+                  type = nullOr (listOf str);
+                  default = null;
+                  example = [ "10.10.0.0/24" "127.0.0.1" ];
+                  description = "IPs and subnets that are authorized to connect for this device. If not specified, the server will allow all connections.";
+                };
+
+                extraOptions = mkOption {
+                  type = iniFields;
+                  default = {
+                    flush = true;
+                    fua = true;
+                  };
+                  description = ''
+                    Extra options for this export. See
+                    <citerefentry><refentrytitle>nbd-server</refentrytitle>
+                    <manvolnum>5</manvolnum></citerefentry>.
+                  '';
+                };
+              };
+            });
+        };
+
+        listenAddress = mkOption {
+          type = with types; nullOr str;
+          description = "Address to listen on. If not specified, the server will listen on all interfaces.";
+          default = null;
+          example = "10.10.0.1";
+        };
+      };
+    };
+  };
+
+  config = mkIf cfg.server.enable {
+    boot.kernelModules = [ "nbd" ];
+
+    systemd.services.nbd-server = {
+      after = [ "network-online.target" ];
+      before = [ "multi-user.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        ExecStart = "${pkgs.nbd}/bin/nbd-server -C ${serverConfig}";
+        Type = "forking";
+
+        DeviceAllow = map (path: "${path} rw") allowedDevices;
+        BindPaths = boundPaths;
+
+        CapabilityBoundingSet = "";
+        DevicePolicy = "closed";
+        LockPersonality = true;
+        MemoryDenyWriteExecute = true;
+        NoNewPrivileges = true;
+        PrivateDevices = false;
+        PrivateMounts = true;
+        PrivateTmp = true;
+        PrivateUsers = true;
+        ProcSubset = "pid";
+        ProtectClock = true;
+        ProtectControlGroups = true;
+        ProtectHome = true;
+        ProtectHostname = true;
+        ProtectKernelLogs = true;
+        ProtectKernelModules = true;
+        ProtectKernelTunables = true;
+        ProtectProc = "noaccess";
+        ProtectSystem = "strict";
+        RestrictAddressFamilies = "AF_INET AF_INET6";
+        RestrictNamespaces = true;
+        RestrictRealtime = true;
+        RestrictSUIDSGID = true;
+        UMask = "0077";
+      };
+    };
+  };
+}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 15b54cd9fe1d..043d8a56d0c6 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -329,6 +329,7 @@ in
   nat.standalone = handleTest ./nat.nix { withFirewall = false; };
   nats = handleTest ./nats.nix {};
   navidrome = handleTest ./navidrome.nix {};
+  nbd = handleTest ./nbd.nix {};
   ncdns = handleTest ./ncdns.nix {};
   ndppd = handleTest ./ndppd.nix {};
   nebula = handleTest ./nebula.nix {};
diff --git a/nixos/tests/nbd.nix b/nixos/tests/nbd.nix
new file mode 100644
index 000000000000..16255e68e8a1
--- /dev/null
+++ b/nixos/tests/nbd.nix
@@ -0,0 +1,87 @@
+import ./make-test-python.nix ({ pkgs, ... }:
+  let
+    listenPort = 30123;
+    testString = "It works!";
+    mkCreateSmallFileService = { path, loop ? false }: {
+      script = ''
+        ${pkgs.coreutils}/bin/dd if=/dev/zero of=${path} bs=1K count=100
+        ${pkgs.lib.optionalString loop
+          "${pkgs.util-linux}/bin/losetup --find ${path}"}
+      '';
+      serviceConfig = {
+        Type = "oneshot";
+      };
+      wantedBy = [ "multi-user.target" ];
+      before = [ "nbd-server.service" ];
+    };
+  in
+  {
+    name = "nbd";
+
+    nodes = {
+      server = { config, pkgs, ... }: {
+        # Create some small files of zeros to use as the ndb disks
+        ## `vault-pub.disk` is accessible from any IP
+        systemd.services.create-pub-file =
+          mkCreateSmallFileService { path = "/vault-pub.disk"; };
+        ## `vault-priv.disk` is accessible only from localhost.
+        ## It's also a loopback device to test exporting /dev/...
+        systemd.services.create-priv-file =
+          mkCreateSmallFileService { path = "/vault-priv.disk"; loop = true; };
+
+        # Needed only for nbd-client used in the tests.
+        environment.systemPackages = [ pkgs.nbd ];
+
+        # Open the nbd port in the firewall
+        networking.firewall.allowedTCPPorts = [ listenPort ];
+
+        # Run the nbd server and expose the small file created above
+        services.nbd.server = {
+          enable = true;
+          exports = {
+            vault-pub = {
+              path = "/vault-pub.disk";
+            };
+            vault-priv = {
+              path = "/dev/loop0";
+              allowAddresses = [ "127.0.0.1" "::1" ];
+            };
+          };
+          listenAddress = "0.0.0.0";
+          listenPort = listenPort;
+        };
+      };
+
+      client = { config, pkgs, ... }: {
+        programs.nbd.enable = true;
+      };
+    };
+
+    testScript = ''
+      testString = "${testString}"
+
+      start_all()
+      server.wait_for_open_port(${toString listenPort})
+
+      # Client: Connect to the server, write a small string to the nbd disk, and cleanly disconnect
+      client.succeed("nbd-client server ${toString listenPort} /dev/nbd0 -name vault-pub -persist")
+      client.succeed(f"echo '{testString}' | dd of=/dev/nbd0 conv=notrunc")
+      client.succeed("nbd-client -d /dev/nbd0")
+
+      # Server: Check that the string written by the client is indeed in the file
+      foundString = server.succeed(f"dd status=none if=/vault-pub.disk count={len(testString)}")[:len(testString)]
+      if foundString != testString:
+         raise Exception(f"Read the wrong string from nbd disk. Expected: '{testString}'. Found: '{foundString}'")
+
+      # Client: Fail to connect to the private disk
+      client.fail("nbd-client server ${toString listenPort} /dev/nbd0 -name vault-priv -persist")
+
+      # Server: Successfully connect to the private disk
+      server.succeed("nbd-client localhost ${toString listenPort} /dev/nbd0 -name vault-priv -persist")
+      server.succeed(f"echo '{testString}' | dd of=/dev/nbd0 conv=notrunc")
+      foundString = server.succeed(f"dd status=none if=/dev/loop0 count={len(testString)}")[:len(testString)]
+      if foundString != testString:
+         raise Exception(f"Read the wrong string from nbd disk. Expected: '{testString}'. Found: '{foundString}'")
+      server.succeed("nbd-client -d /dev/nbd0")
+    '';
+  })
diff --git a/pkgs/applications/audio/puddletag/default.nix b/pkgs/applications/audio/puddletag/default.nix
index efa1d9436100..701e6fffbbb8 100644
--- a/pkgs/applications/audio/puddletag/default.nix
+++ b/pkgs/applications/audio/puddletag/default.nix
@@ -1,26 +1,62 @@
-{ lib, fetchFromGitHub, python3Packages, wrapQtAppsHook, chromaprint }:
+{ lib, fetchFromGitHub, python3Packages, wrapQtAppsHook }:
 
+# As of 2.1, puddletag has started pinning versions of all dependencies that it
+# was built against which is an issue as the chances of us having the exact same
+# versions in nixpkgs are slim to none.
+#
+# There is a difference between explicit and implicit version requirements and
+# we should be able to safely ignore the latter. Therefore use requirements.in
+# which contains just the explicit version dependencies instead of
+# requirements.txt.
+#
+# Additionally, we do need to override some of the explicit requirements through
+# `overrideVersions`. While we technically run the risk of breaking something by
+# ignoring the pinned versions, it's just something we will have to accept
+# unless we want to vendor those versions.
+
+let
+  # NOTE: check if we can drop any of these overrides when bumping the version
+  overrideVersions = [
+    "pyparsing"
+    "pyqt5"
+  ];
+
+in
 python3Packages.buildPythonApplication rec {
   pname = "puddletag";
-  version = "2.0.1";
+  version = "2.1.1";
 
   src = fetchFromGitHub {
-    owner = "keithgg";
+    owner = "puddletag";
     repo = "puddletag";
     rev = version;
-    sha256 = "sha256-9l8Pc77MX5zFkOqU00HFS8//3Bzd2OMnVV1brmWsNAQ=";
+    hash = "sha256-eilETaFvvPMopIbccV1uLbpD55kHX9KGTCcGVXaHPgM=";
   };
 
-  sourceRoot = "source/source";
+  postPatch = ''
+    substituteInPlace setup.py \
+      --replace share/pixmaps share/icons
+
+    cp requirements.in requirements.txt
+  '' + lib.concatMapStringsSep "\n"
+    (e: ''
+      sed -i requirements.txt -e 's/^${e}.*/${e}/'
+    '')
+    overrideVersions;
 
   nativeBuildInputs = [ wrapQtAppsHook ];
 
-  propagatedBuildInputs = [ chromaprint ] ++ (with python3Packages; [
+  propagatedBuildInputs = with python3Packages; [
+    pyacoustid
+    chromaprint
     configobj
+    levenshtein
+    lxml
     mutagen
     pyparsing
     pyqt5
-  ]);
+    rapidfuzz
+  ];
 
   preFixup = ''
     makeWrapperArgs+=("''${qtWrapperArgs[@]}")
@@ -33,8 +69,8 @@ python3Packages.buildPythonApplication rec {
   meta = with lib; {
     description = "An audio tag editor similar to the Windows program, Mp3tag";
     homepage = "https://docs.puddletag.net";
-    license = licenses.gpl3;
-    maintainers = with maintainers; [ peterhoeg ];
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ peterhoeg dschrempf ];
     platforms = platforms.linux;
   };
 }
diff --git a/pkgs/applications/misc/obsidian/default.nix b/pkgs/applications/misc/obsidian/default.nix
index 607d02a484ec..67a0939ddab9 100644
--- a/pkgs/applications/misc/obsidian/default.nix
+++ b/pkgs/applications/misc/obsidian/default.nix
@@ -1,76 +1,99 @@
-{ stdenv, fetchurl, lib, makeWrapper, electron_16, makeDesktopItem, graphicsmagick
-, writeScript }:
-
+{ stdenv
+, fetchurl
+, lib
+, makeWrapper
+, electron_16
+, makeDesktopItem
+, graphicsmagick
+, writeScript
+, undmg
+, unzip
+}:
 let
-  electron = electron_16;
-  icon = fetchurl {
-    url =
-      "https://forum.obsidian.md/uploads/default/original/1X/bf119bd48f748f4fd2d65f2d1bb05d3c806883b5.png";
-    sha256 = "18ylnbvxr6k4x44c4i1d55wxy2dq4fdppp43a4wl6h6zar0sc9s2";
-  };
-
-  desktopItem = makeDesktopItem {
-    name = "obsidian";
-    desktopName = "Obsidian";
-    comment = "Knowledge base";
-    icon = "obsidian";
-    exec = "obsidian";
-    categories = [ "Office" ];
-  };
-
-  updateScript = writeScript "obsidian-updater" ''
-    #!/usr/bin/env nix-shell
-    #!nix-shell -i bash -p curl jq common-updater-scripts
-
-    set -eu -o pipefail
-
-    latestVersion="$(curl -sS https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/desktop-releases.json | jq -r '.latestVersion')"
-
-    update-source-version obsidian "$latestVersion"
-  '';
-
-in stdenv.mkDerivation rec {
+  inherit (stdenv.hostPlatform) system;
   pname = "obsidian";
-  version = "0.13.30";
+  version = "0.13.31";
+  meta = with lib; {
+    description = "A powerful knowledge base that works on top of a local folder of plain text Markdown files";
+    homepage = "https://obsidian.md";
+    downloadPage = "https://github.com/obsidianmd/obsidian-releases/releases";
+    license = licenses.obsidian;
+    maintainers = with maintainers; [ conradmearns zaninime opeik ];
+  };
 
   src = fetchurl {
-    url = "https://github.com/obsidianmd/obsidian-releases/releases/download/v${version}/obsidian-${version}.tar.gz";
-    sha256 = "ymdqdDD7WWfol/jLBsz8tEzcN7Ed1HSIrkuA51cvKKw=";
+    url = "https://github.com/obsidianmd/obsidian-releases/releases/download/v${version}/obsidian-${version}${extension}";
+    inherit sha256;
   };
 
-  nativeBuildInputs = [ makeWrapper graphicsmagick ];
-
-  installPhase = ''
-    runHook preInstall
-
-    mkdir -p $out/bin
-
-    makeWrapper ${electron}/bin/electron $out/bin/obsidian \
-      --add-flags $out/share/obsidian/app.asar
-
-    install -m 444 -D resources/app.asar $out/share/obsidian/app.asar
-    install -m 444 -D resources/obsidian.asar $out/share/obsidian/obsidian.asar
-
-    install -m 444 -D "${desktopItem}/share/applications/"* \
-      -t $out/share/applications/
-
-    for size in 16 24 32 48 64 128 256 512; do
-      mkdir -p $out/share/icons/hicolor/"$size"x"$size"/apps
-      gm convert -resize "$size"x"$size" ${icon} $out/share/icons/hicolor/"$size"x"$size"/apps/obsidian.png
-    done
-
-    runHook postInstall
-  '';
-
-  passthru.updateScript = updateScript;
+  sha256 = rec {
+    x86_64-linux = "v3Zm5y8V1KyWDQeJxhryBojz56OTT7gfT+pLGDUD4zs=";
+    x86_64-darwin = "m/81uuDhMJJ1tHTUPww+xNdwsaYCOmeNtbjdwMAwhBU=";
+    aarch64-darwin = x86_64-darwin;
+  }.${system};
+
+  extension = rec {
+    x86_64-linux = ".tar.gz";
+    x86_64-darwin = "-universal.dmg";
+    aarch64-darwin = x86_64-darwin;
+  }.${system};
+
+  linux = stdenv.mkDerivation rec {
+    icon = fetchurl {
+      url = "https://forum.obsidian.md/uploads/default/original/1X/bf119bd48f748f4fd2d65f2d1bb05d3c806883b5.png";
+      sha256 = "18ylnbvxr6k4x44c4i1d55wxy2dq4fdppp43a4wl6h6zar0sc9s2";
+    };
+
+    desktopItem = makeDesktopItem {
+      name = "obsidian";
+      desktopName = "Obsidian";
+      comment = "Knowledge base";
+      icon = "obsidian";
+      exec = "obsidian";
+      categories = [ "Office" ];
+    };
+
+    inherit pname version src;
+    meta.platforms = [ "x86_64-linux" ];
+    nativeBuildInputs = [ makeWrapper graphicsmagick ];
+    installPhase = ''
+      runHook preInstall
+      mkdir -p $out/bin
+      makeWrapper ${electron_16}/bin/electron $out/bin/obsidian \
+        --add-flags $out/share/obsidian/app.asar
+      install -m 444 -D resources/app.asar $out/share/obsidian/app.asar
+      install -m 444 -D resources/obsidian.asar $out/share/obsidian/obsidian.asar
+      install -m 444 -D "${desktopItem}/share/applications/"* \
+        -t $out/share/applications/
+      for size in 16 24 32 48 64 128 256 512; do
+        mkdir -p $out/share/icons/hicolor/"$size"x"$size"/apps
+        gm convert -resize "$size"x"$size" ${icon} $out/share/icons/hicolor/"$size"x"$size"/apps/obsidian.png
+      done
+      runHook postInstall
+    '';
+
+    passthru.updateScript = writeScript "updater" ''
+      #!/usr/bin/env nix-shell
+      #!nix-shell -i bash -p curl jq common-updater-scripts
+      set -eu -o pipefail
+      latestVersion="$(curl -sS https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/desktop-releases.json | jq -r '.latestVersion')"
+      update-source-version obsidian "$latestVersion"
+    '';
+  };
 
-  meta = with lib; {
-    description =
-      "A powerful knowledge base that works on top of a local folder of plain text Markdown files";
-    homepage = "https://obsidian.md";
-    downloadPage = "https://github.com/obsidianmd/obsidian-releases/releases";
-    license = licenses.obsidian;
-    maintainers = with maintainers; [ conradmearns zaninime ];
-    platforms = [ "x86_64-linux" ];
+  darwin = stdenv.mkDerivation rec {
+    appname = "Obsidian";
+    inherit pname version src;
+    meta.platforms = [ "x86_64-darwin" "aarch64-darwin" ];
+    sourceRoot = "${appname}.app";
+    nativeBuildInputs = [ makeWrapper undmg unzip ];
+    installPhase = ''
+      runHook preInstall
+      mkdir -p $out/{Applications/${appname}.app,bin}
+      cp -R . $out/Applications/${appname}.app
+      makeWrapper $out/Applications/${appname}.app/Contents/MacOS/${appname} $out/bin/${pname}
+      runHook postInstall
+    '';
   };
-}
+in
+if stdenv.isDarwin then darwin else linux
diff --git a/pkgs/applications/networking/instant-messengers/nheko/default.nix b/pkgs/applications/networking/instant-messengers/nheko/default.nix
index bee1f7cf2891..080ceda94b4a 100644
--- a/pkgs/applications/networking/instant-messengers/nheko/default.nix
+++ b/pkgs/applications/networking/instant-messengers/nheko/default.nix
@@ -3,6 +3,7 @@
 , fetchFromGitHub
 , fetchpatch
 , cmake
+, asciidoc
 , cmark
 , lmdb
 , lmdbxx
@@ -32,19 +33,20 @@
 
 mkDerivation rec {
   pname = "nheko";
-  version = "0.9.1";
+  version = "0.9.2";
 
   src = fetchFromGitHub {
     owner = "Nheko-Reborn";
     repo = "nheko";
     rev = "v${version}";
-    sha256 = "sha256-KnWZ1DSTg8vtNSlpG5LGUG8YDHt25s9pMLpLuj0WLnM=";
+    sha256 = "sha256-roC1OIq0Vmj5rABNtH4IOMHX9aSlOMFC7ZHueuj/PmE=";
   };
 
   nativeBuildInputs = [
     lmdbxx
     cmake
     pkg-config
+    asciidoc
   ];
 
   buildInputs = [
diff --git a/pkgs/development/libraries/mtxclient/default.nix b/pkgs/development/libraries/mtxclient/default.nix
index 92285501748a..619ed721dff2 100644
--- a/pkgs/development/libraries/mtxclient/default.nix
+++ b/pkgs/development/libraries/mtxclient/default.nix
@@ -14,13 +14,13 @@
 
 stdenv.mkDerivation rec {
   pname = "mtxclient";
-  version = "0.6.2";
+  version = "0.7.0";
 
   src = fetchFromGitHub {
     owner = "Nheko-Reborn";
     repo = "mtxclient";
     rev = "v${version}";
-    sha256 = "sha256-TsGoSVewQJlr0zj8qYEd+UU8DlncZDCqfrqTv89LEYU=";
+    sha256 = "sha256-iGw+qdw7heL5q7G0dwtl4PX2UA0Kka0FUmH610dM/00=";
   };
 
   postPatch = ''
diff --git a/pkgs/development/python-modules/chromaprint/default.nix b/pkgs/development/python-modules/chromaprint/default.nix
new file mode 100644
index 000000000000..2a07a4eb6dce
--- /dev/null
+++ b/pkgs/development/python-modules/chromaprint/default.nix
@@ -0,0 +1,32 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, isPy27
+, m2r
+}:
+
+buildPythonPackage rec {
+  pname = "chromaprint";
+  version = "0.5";
+
+  disabled = isPy27;
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "sha256-d4M+ieNQpIXcnEH1WyIWnTYZe3P+Y58W0uz1uYPwLQE=";
+  };
+
+  buildInputs = [ m2r ];
+
+  # no tests
+  doCheck = false;
+
+  pythonImportsCheck = [ "chromaprint" ];
+
+  meta = with lib; {
+    description = "Facilitate effortless color terminal output";
+    homepage = "https://pypi.org/project/${pname}/";
+    license = licenses.mit;
+    maintainers = with maintainers; [ dschrempf peterhoeg ];
+  };
+}
diff --git a/pkgs/development/python-modules/deep-translator/default.nix b/pkgs/development/python-modules/deep-translator/default.nix
index 0f67b2ae3529..fd6d4d478f46 100644
--- a/pkgs/development/python-modules/deep-translator/default.nix
+++ b/pkgs/development/python-modules/deep-translator/default.nix
@@ -2,11 +2,11 @@
 
 buildPythonPackage rec {
   pname = "deep-translator";
-  version = "1.7.0";
+  version = "1.8.0";
 
   src = fetchPypi {
     inherit pname version;
-    sha256 = "sha256-k4RhUZN/aC9D1NKkmCGZGZNU9In577RobBnDagMYHbo=";
+    sha256 = "sha256-2u4ZmLUEOwbN2sbPgLu9R1VdNevXBP4lBFuGw2aiRMg=";
   };
 
   propagatedBuildInputs = [
diff --git a/pkgs/development/python-modules/glean-parser/default.nix b/pkgs/development/python-modules/glean-parser/default.nix
index 52fdf6745c9f..30d4db0d2613 100644
--- a/pkgs/development/python-modules/glean-parser/default.nix
+++ b/pkgs/development/python-modules/glean-parser/default.nix
@@ -16,13 +16,13 @@
 
 buildPythonPackage rec {
   pname = "glean_parser";
-  version = "5.0.1";
+  version = "5.1.0";
 
   disabled = pythonOlder "3.6";
 
   src = fetchPypi {
     inherit pname version;
-    sha256 = "sha256-MJ827VXy8e2CRyq4sY4d0B7etxBgRk4/hZybYOOLh9Q=";
+    sha256 = "sha256-8oMbaGsW5Lkw9OluNsXXe2IBNbjeoIb9vDjVOt+uHR0=";
   };
 
   postPatch = ''
diff --git a/pkgs/os-specific/linux/iwd/default.nix b/pkgs/os-specific/linux/iwd/default.nix
index 3f725e3e5b26..72ecaffe5f50 100644
--- a/pkgs/os-specific/linux/iwd/default.nix
+++ b/pkgs/os-specific/linux/iwd/default.nix
@@ -20,7 +20,7 @@ stdenv.mkDerivation rec {
     sha256 = "sha256-GcqmMqrZSgvSrsY8FJbPynNWTzSi5A6kmyq+xJ+2i3Y=";
   };
 
-  outputs = [ "out" "man" ]
+  outputs = [ "out" "man" "doc" ]
     ++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform) "test";
 
   nativeBuildInputs = [
@@ -65,9 +65,9 @@ stdenv.mkDerivation rec {
   doCheck = true;
 
   postInstall = ''
-    mkdir -p $out/share
-    cp -a doc $out/share/
-    cp -a README AUTHORS TODO $out/share/doc/
+    mkdir -p $doc/share/doc
+    cp -a doc $doc/share/doc/iwd
+    cp -a README AUTHORS TODO $doc/share/doc/iwd
   '' + lib.optionalString (stdenv.hostPlatform == stdenv.buildPlatform) ''
     mkdir -p $test/bin
     cp -a test/* $test/bin/
diff --git a/pkgs/os-specific/linux/zfs/default.nix b/pkgs/os-specific/linux/zfs/default.nix
index 7341240f95af..e3a856c12a4c 100644
--- a/pkgs/os-specific/linux/zfs/default.nix
+++ b/pkgs/os-specific/linux/zfs/default.nix
@@ -16,7 +16,7 @@
 , enablePython ? true
 
 # for determining the latest compatible linuxPackages
-, linuxPackages_5_15 ? pkgs.linuxKernel.packages.linux_5_15
+, linuxPackages_5_16 ? pkgs.linuxKernel.packages.linux_5_16
 }:
 
 with lib;
@@ -215,28 +215,28 @@ in {
   # to be adapted
   zfsStable = common {
     # check the release notes for compatible kernels
-    kernelCompatible = kernel.kernelAtLeast "3.10" && kernel.kernelOlder "5.16";
-    latestCompatibleLinuxPackages = linuxPackages_5_15;
+    kernelCompatible = kernel.kernelAtLeast "3.10" && kernel.kernelOlder "5.17";
+    latestCompatibleLinuxPackages = linuxPackages_5_16;
 
     # this package should point to the latest release.
-    version = "2.1.2";
+    version = "2.1.3";
 
-    sha256 = "sha256-7oSFZlmjCr+egImIVf429GrFOKn3L3r4SMnK3LHHmL8=";
+    sha256 = "10p9s835wj5msspqwnqbfbnh8jmcazzd2v0gj4hn7vvni4p48gfl";
   };
 
   zfsUnstable = common {
     # check the release notes for compatible kernels
-    kernelCompatible = kernel.kernelAtLeast "3.10" && kernel.kernelOlder "5.16";
-    latestCompatibleLinuxPackages = linuxPackages_5_15;
+    kernelCompatible = kernel.kernelAtLeast "3.10" && kernel.kernelOlder "5.17";
+    latestCompatibleLinuxPackages = linuxPackages_5_16;
 
     # this package should point to a version / git revision compatible with the latest kernel release
     # IMPORTANT: Always use a tagged release candidate or commits from the
     # zfs-<version>-staging branch, because this is tested by the OpenZFS
     # maintainers.
-    version = "2.1.2";
+    version = "2.1.3";
     # rev = "0000000000000000000000000000000000000000";
 
-    sha256 = "sha256-7oSFZlmjCr+egImIVf429GrFOKn3L3r4SMnK3LHHmL8=";
+    sha256 = "10p9s835wj5msspqwnqbfbnh8jmcazzd2v0gj4hn7vvni4p48gfl";
 
     isUnstable = true;
   };
diff --git a/pkgs/tools/networking/nbd/default.nix b/pkgs/tools/networking/nbd/default.nix
index 95c2f970999a..131793894841 100644
--- a/pkgs/tools/networking/nbd/default.nix
+++ b/pkgs/tools/networking/nbd/default.nix
@@ -1,4 +1,4 @@
-{ lib, stdenv, fetchurl, pkg-config, glib, which }:
+{ lib, stdenv, fetchurl, pkg-config, glib, which, nixosTests }:
 
 stdenv.mkDerivation rec {
   pname = "nbd";
@@ -21,6 +21,10 @@ stdenv.mkDerivation rec {
 
   doCheck = true;
 
+  passthru.tests = {
+    test = nixosTests.nbd;
+  };
+
   # Glib calls `clock_gettime', which is in librt. Linking that library
   # here ensures that a proper rpath is added to the executable so that
   # it can be loaded at run-time.
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index 9f2cd1edf8c1..9d5ecb43497d 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -1599,6 +1599,8 @@ in {
 
   chispa = callPackage ../development/python-modules/chispa { };
 
+  chromaprint = callPackage ../development/python-modules/chromaprint { };
+
   ci-info = callPackage ../development/python-modules/ci-info { };
 
   ci-py = callPackage ../development/python-modules/ci-py { };