about summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xnixos/lib/test-driver/test-driver.py72
-rw-r--r--nixos/lib/testing-python.nix4
-rw-r--r--nixos/tests/all-tests.nix2
-rw-r--r--nixos/tests/common/wayland-cage.nix14
-rw-r--r--nixos/tests/vscodium.nix92
-rw-r--r--pkgs/development/libraries/grpc/default.nix3
-rw-r--r--pkgs/development/libraries/libfprint-tod/default.nix4
-rw-r--r--pkgs/development/mobile/androidenv/ndk-bundle/default.nix1
-rw-r--r--pkgs/development/python-modules/aiohwenergy/default.nix40
-rw-r--r--pkgs/development/python-modules/apache-airflow/default.nix20
-rw-r--r--pkgs/development/python-modules/elementpath/default.nix9
-rw-r--r--pkgs/development/python-modules/faraday-plugins/default.nix4
-rw-r--r--pkgs/development/python-modules/identify/default.nix8
-rw-r--r--pkgs/development/python-modules/luxtronik/default.nix36
-rw-r--r--pkgs/development/python-modules/millheater/default.nix6
-rw-r--r--pkgs/development/python-modules/pyatmo/default.nix9
-rw-r--r--pkgs/development/python-modules/pyebus/default.nix43
-rw-r--r--pkgs/development/python-modules/pyupgrade/default.nix18
-rw-r--r--pkgs/development/python-modules/related/default.nix60
-rw-r--r--pkgs/development/python-modules/roombapy/default.nix26
-rw-r--r--pkgs/development/python-modules/tweepy/default.nix4
-rw-r--r--pkgs/development/python-modules/ukkonen/default.nix41
-rw-r--r--pkgs/development/python-modules/uonet-request-signer-hebe/default.nix37
-rw-r--r--pkgs/development/python-modules/vulcan-api/default.nix57
-rw-r--r--pkgs/development/python-modules/xmlschema/default.nix4
-rw-r--r--pkgs/development/tools/analysis/checkov/default.nix4
-rw-r--r--pkgs/tools/admin/trivy/default.nix15
-rw-r--r--pkgs/tools/filesystems/nilfs-utils/default.nix5
-rw-r--r--pkgs/tools/security/masscan/default.nix5
-rw-r--r--pkgs/top-level/python-packages.nix14
30 files changed, 541 insertions, 116 deletions
diff --git a/nixos/lib/test-driver/test-driver.py b/nixos/lib/test-driver/test-driver.py
index a7c0484060f2f..643446f313e3a 100755
--- a/nixos/lib/test-driver/test-driver.py
+++ b/nixos/lib/test-driver/test-driver.py
@@ -4,6 +4,7 @@ from queue import Queue, Empty
 from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List, Iterable
 from xml.sax.saxutils import XMLGenerator
 from colorama import Style
+from pathlib import Path
 import queue
 import io
 import threading
@@ -11,7 +12,6 @@ import argparse
 import base64
 import codecs
 import os
-import pathlib
 import ptpython.repl
 import pty
 import re
@@ -239,8 +239,8 @@ class StartCommand:
 
     def cmd(
         self,
-        monitor_socket_path: pathlib.Path,
-        shell_socket_path: pathlib.Path,
+        monitor_socket_path: Path,
+        shell_socket_path: Path,
         allow_reboot: bool = False,  # TODO: unused, legacy?
     ) -> str:
         display_opts = ""
@@ -272,8 +272,8 @@ class StartCommand:
 
     @staticmethod
     def build_environment(
-        state_dir: pathlib.Path,
-        shared_dir: pathlib.Path,
+        state_dir: Path,
+        shared_dir: Path,
     ) -> dict:
         # We make a copy to not update the current environment
         env = dict(os.environ)
@@ -288,10 +288,10 @@ class StartCommand:
 
     def run(
         self,
-        state_dir: pathlib.Path,
-        shared_dir: pathlib.Path,
-        monitor_socket_path: pathlib.Path,
-        shell_socket_path: pathlib.Path,
+        state_dir: Path,
+        shared_dir: Path,
+        monitor_socket_path: Path,
+        shell_socket_path: Path,
     ) -> subprocess.Popen:
         return subprocess.Popen(
             self.cmd(monitor_socket_path, shell_socket_path),
@@ -334,7 +334,7 @@ class LegacyStartCommand(StartCommand):
         self,
         netBackendArgs: Optional[str] = None,
         netFrontendArgs: Optional[str] = None,
-        hda: Optional[Tuple[pathlib.Path, str]] = None,
+        hda: Optional[Tuple[Path, str]] = None,
         cdrom: Optional[str] = None,
         usb: Optional[str] = None,
         bios: Optional[str] = None,
@@ -394,11 +394,11 @@ class Machine:
     the machine lifecycle with the help of a start script / command."""
 
     name: str
-    tmp_dir: pathlib.Path
-    shared_dir: pathlib.Path
-    state_dir: pathlib.Path
-    monitor_path: pathlib.Path
-    shell_path: pathlib.Path
+    tmp_dir: Path
+    shared_dir: Path
+    state_dir: Path
+    monitor_path: Path
+    shell_path: Path
 
     start_command: StartCommand
     keep_vm_state: bool
@@ -421,7 +421,7 @@ class Machine:
 
     def __init__(
         self,
-        tmp_dir: pathlib.Path,
+        tmp_dir: Path,
         start_command: StartCommand,
         name: str = "machine",
         keep_vm_state: bool = False,
@@ -463,7 +463,7 @@ class Machine:
         hda = None
         if args.get("hda"):
             hda_arg: str = args.get("hda", "")
-            hda_arg_path: pathlib.Path = pathlib.Path(hda_arg)
+            hda_arg_path: Path = Path(hda_arg)
             hda = (hda_arg_path, args.get("hdaInterface", ""))
         return LegacyStartCommand(
             netBackendArgs=args.get("netBackendArgs"),
@@ -814,12 +814,12 @@ class Machine:
         """Copy a file from the host into the guest via the `shared_dir` shared
         among all the VMs (using a temporary directory).
         """
-        host_src = pathlib.Path(source)
-        vm_target = pathlib.Path(target)
+        host_src = Path(source)
+        vm_target = Path(target)
         with tempfile.TemporaryDirectory(dir=self.shared_dir) as shared_td:
-            shared_temp = pathlib.Path(shared_td)
+            shared_temp = Path(shared_td)
             host_intermediate = shared_temp / host_src.name
-            vm_shared_temp = pathlib.Path("/tmp/shared") / shared_temp.name
+            vm_shared_temp = Path("/tmp/shared") / shared_temp.name
             vm_intermediate = vm_shared_temp / host_src.name
 
             self.succeed(make_command(["mkdir", "-p", vm_shared_temp]))
@@ -836,11 +836,11 @@ class Machine:
         all the VMs (using a temporary directory).
         """
         # Compute the source, target, and intermediate shared file names
-        out_dir = pathlib.Path(os.environ.get("out", os.getcwd()))
-        vm_src = pathlib.Path(source)
+        out_dir = Path(os.environ.get("out", os.getcwd()))
+        vm_src = Path(source)
         with tempfile.TemporaryDirectory(dir=self.shared_dir) as shared_td:
-            shared_temp = pathlib.Path(shared_td)
-            vm_shared_temp = pathlib.Path("/tmp/shared") / shared_temp.name
+            shared_temp = Path(shared_td)
+            vm_shared_temp = Path("/tmp/shared") / shared_temp.name
             vm_intermediate = vm_shared_temp / vm_src.name
             intermediate = shared_temp / vm_src.name
             # Copy the file to the shared directory inside VM
@@ -911,12 +911,12 @@ class Machine:
 
         self.log("starting vm")
 
-        def clear(path: pathlib.Path) -> pathlib.Path:
+        def clear(path: Path) -> Path:
             if path.exists():
                 path.unlink()
             return path
 
-        def create_socket(path: pathlib.Path) -> socket.socket:
+        def create_socket(path: Path) -> socket.socket:
             s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM)
             s.bind(str(path))
             s.listen(1)
@@ -1061,7 +1061,7 @@ class VLan:
     """
 
     nr: int
-    socket_dir: pathlib.Path
+    socket_dir: Path
 
     process: subprocess.Popen
     pid: int
@@ -1070,7 +1070,7 @@ class VLan:
     def __repr__(self) -> str:
         return f"<Vlan Nr. {self.nr}>"
 
-    def __init__(self, nr: int, tmp_dir: pathlib.Path):
+    def __init__(self, nr: int, tmp_dir: Path):
         self.nr = nr
         self.socket_dir = tmp_dir / f"vde{self.nr}.ctl"
 
@@ -1123,7 +1123,7 @@ class Driver:
     ):
         self.tests = tests
 
-        tmp_dir = pathlib.Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
+        tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
         tmp_dir.mkdir(mode=0o700, exist_ok=True)
 
         with rootlog.nested("start all VLans"):
@@ -1183,9 +1183,11 @@ class Driver:
             serial_stdout_on=self.serial_stdout_on,
             Machine=Machine,  # for typing
         )
-        machine_symbols = {
-            m.name: self.machines[idx] for idx, m in enumerate(self.machines)
-        }
+        machine_symbols = {m.name: m for m in self.machines}
+        # If there's exactly one machine, make it available under the name
+        # "machine", even if it's not called that.
+        if len(self.machines) == 1:
+            (machine_symbols["machine"],) = self.machines
         vlan_symbols = {
             f"vlan{v.nr}": self.vlans[idx] for idx, v in enumerate(self.vlans)
         }
@@ -1230,7 +1232,7 @@ class Driver:
             "Using legacy create_machine(), please instantiate the"
             "Machine class directly, instead"
         )
-        tmp_dir = pathlib.Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
+        tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
         tmp_dir.mkdir(mode=0o700, exist_ok=True)
 
         if args.get("startCommand"):
@@ -1316,7 +1318,7 @@ if __name__ == "__main__":
         action=EnvDefault,
         envvar="testScript",
         help="the test script to run",
-        type=pathlib.Path,
+        type=Path,
     )
 
     args = arg_parser.parse_args()
diff --git a/nixos/lib/testing-python.nix b/nixos/lib/testing-python.nix
index cce017a6441db..4306d102b2d64 100644
--- a/nixos/lib/testing-python.nix
+++ b/nixos/lib/testing-python.nix
@@ -134,7 +134,9 @@ rec {
       vlans = map (m: m.config.virtualisation.vlans) (lib.attrValues nodes);
       vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
 
-      nodeHostNames = map (c: c.config.system.name) (lib.attrValues nodes);
+      nodeHostNames = let
+        nodesList = map (c: c.config.system.name) (lib.attrValues nodes);
+      in nodesList ++ lib.optional (lib.length nodesList == 1) "machine";
 
       # TODO: This is an implementation error and needs fixing
       # the testing famework cannot legitimately restrict hostnames further
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index cd13183ed0a32..b8219416dc42a 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -489,7 +489,7 @@ in
   victoriametrics = handleTest ./victoriametrics.nix {};
   vikunja = handleTest ./vikunja.nix {};
   virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {};
-  vscodium = handleTest ./vscodium.nix {};
+  vscodium = discoverTests (import ./vscodium.nix);
   wasabibackend = handleTest ./wasabibackend.nix {};
   wiki-js = handleTest ./wiki-js.nix {};
   wireguard = handleTest ./wireguard {};
diff --git a/nixos/tests/common/wayland-cage.nix b/nixos/tests/common/wayland-cage.nix
new file mode 100644
index 0000000000000..55aeb858d7a42
--- /dev/null
+++ b/nixos/tests/common/wayland-cage.nix
@@ -0,0 +1,14 @@
+{ ... }:
+
+{
+  imports = [ ./user-account.nix ];
+  services.cage = {
+    enable = true;
+    user = "alice";
+  };
+
+  virtualisation = {
+    memorySize = 1024;
+    qemu.options = [ "-vga virtio" ];
+  };
+}
diff --git a/nixos/tests/vscodium.nix b/nixos/tests/vscodium.nix
index 033090aa0e3d1..43a0d61c856f5 100644
--- a/nixos/tests/vscodium.nix
+++ b/nixos/tests/vscodium.nix
@@ -1,47 +1,69 @@
-import ./make-test-python.nix ({ pkgs, ...} :
+let
+  tests = {
+    wayland = { pkgs, ... }: {
+      imports = [ ./common/wayland-cage.nix ];
 
-{
-  name = "vscodium";
-  meta = with pkgs.lib.maintainers; {
-    maintainers = [ turion ];
+      services.cage.program = ''
+        ${pkgs.vscodium}/bin/codium \
+          --enable-features=UseOzonePlatform \
+          --ozone-platform=wayland
+      '';
+
+      fonts.fonts = with pkgs; [ dejavu_fonts ];
+    };
+    xorg = { pkgs, ... }: {
+      imports = [ ./common/user-account.nix ./common/x11.nix ];
+
+      virtualisation.memorySize = 2047;
+      services.xserver.enable = true;
+      services.xserver.displayManager.sessionCommands = ''
+        ${pkgs.vscodium}/bin/codium
+      '';
+      test-support.displayManager.auto.user = "alice";
+    };
   };
 
-  machine = { ... }:
+  mkTest = name: machine:
+    import ./make-test-python.nix ({ pkgs, ... }: {
+      inherit name;
 
-  {
-    imports = [
-      ./common/user-account.nix
-      ./common/x11.nix
-    ];
+      nodes = { "${name}" = machine; };
 
-    virtualisation.memorySize = 2047;
-    services.xserver.enable = true;
-    test-support.displayManager.auto.user = "alice";
-    environment.systemPackages = with pkgs; [
-      vscodium
-    ];
-  };
+      meta = with pkgs.lib.maintainers; {
+        maintainers = [ synthetica turion ];
+      };
+      enableOCR = true;
+      testScript = ''
+        start_all()
+
+        machine.wait_for_unit('graphical.target')
+        machine.wait_until_succeeds('pgrep -x codium')
 
-  enableOCR = true;
+        # Wait until vscodium is visible. "File" is in the menu bar.
+        machine.wait_for_text('File')
+        machine.screenshot('start_screen')
 
-  testScript = { nodes, ... }: ''
-    # Start up X
-    start_all()
-    machine.wait_for_x()
+        test_string = 'testfile'
 
-    # Start VSCodium with a file that doesn't exist yet
-    machine.fail("ls /home/alice/foo.txt")
-    machine.succeed("su - alice -c 'codium foo.txt' >&2 &")
+        # Create a new file
+        machine.send_key('ctrl-n')
+        machine.wait_for_text('Untitled')
+        machine.screenshot('empty_editor')
 
-    # Wait for the window to appear
-    machine.wait_for_text("VSCodium")
+        # Type a string
+        machine.send_chars(test_string)
+        machine.wait_for_text(test_string)
+        machine.screenshot('editor')
 
-    # Save file
-    machine.send_key("ctrl-s")
+        # Save the file
+        machine.send_key('ctrl-s')
+        machine.wait_for_text('Save')
+        machine.screenshot('save_window')
+        machine.send_key('ret')
 
-    # Wait until the file has been saved
-    machine.wait_for_file("/home/alice/foo.txt")
+        # (the default filename is the first line of the file)
+        machine.wait_for_file(f'/home/alice/{test_string}')
+      '';
+    });
 
-    machine.screenshot("VSCodium")
-  '';
-})
+in builtins.mapAttrs (k: v: mkTest k v { }) tests
diff --git a/pkgs/development/libraries/grpc/default.nix b/pkgs/development/libraries/grpc/default.nix
index c00e5a4e0d309..ae49974fefe11 100644
--- a/pkgs/development/libraries/grpc/default.nix
+++ b/pkgs/development/libraries/grpc/default.nix
@@ -81,7 +81,8 @@ stdenv.mkDerivation rec {
     export LD_LIBRARY_PATH=$(pwd)''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH
   '';
 
-  NIX_CFLAGS_COMPILE = lib.optionalString stdenv.cc.isClang "-Wno-error=unknown-warning-option";
+  NIX_CFLAGS_COMPILE = lib.optionalString stdenv.cc.isClang "-Wno-error=unknown-warning-option"
+    + lib.optionalString stdenv.isAarch64 "-Wno-error=format-security";
 
   enableParallelBuilds = true;
 
diff --git a/pkgs/development/libraries/libfprint-tod/default.nix b/pkgs/development/libraries/libfprint-tod/default.nix
index a7705792cd8c9..8d7df57896d4c 100644
--- a/pkgs/development/libraries/libfprint-tod/default.nix
+++ b/pkgs/development/libraries/libfprint-tod/default.nix
@@ -6,7 +6,7 @@
 # for the curious, "tod" means "Touch OEM Drivers" meaning it can load
 # external .so's.
 libfprint.overrideAttrs ({ postPatch ? "", mesonFlags ? [], ... }: let
-  version = "1.94.1+tod1";
+  version = "1.90.7+git20210222+tod1";
 in  {
   pname = "libfprint-tod";
   inherit version;
@@ -16,7 +16,7 @@ in  {
     owner = "3v1n0";
     repo = "libfprint";
     rev = "v${version}";
-    sha256 = "sha256-IVeTQlZjea4xgbG/N7OTHAj6RT4WutfvQhV8qFEvkKo=";
+    sha256 = "0cj7iy5799pchyzqqncpkhibkq012g3bdpn18pfb19nm43svhn4j";
   };
 
   mesonFlags = mesonFlags ++ [
diff --git a/pkgs/development/mobile/androidenv/ndk-bundle/default.nix b/pkgs/development/mobile/androidenv/ndk-bundle/default.nix
index 26d6a847b4d0a..a854069e75a52 100644
--- a/pkgs/development/mobile/androidenv/ndk-bundle/default.nix
+++ b/pkgs/development/mobile/androidenv/ndk-bundle/default.nix
@@ -10,6 +10,7 @@ in
 deployAndroidPackage {
   inherit package os;
   nativeBuildInputs = [ autoPatchelfHook makeWrapper ];
+  autoPatchelfIgnoreMissingDeps = true;
   buildInputs = lib.optional (os == "linux") [ pkgs.glibc pkgs.stdenv.cc.cc pkgs.python2 pkgs.ncurses5 pkgs.zlib pkgs.libcxx.out pkgs.libxml2 ];
   patchInstructions = lib.optionalString (os == "linux") (''
     patchShebangs .
diff --git a/pkgs/development/python-modules/aiohwenergy/default.nix b/pkgs/development/python-modules/aiohwenergy/default.nix
new file mode 100644
index 0000000000000..b9b2801f750db
--- /dev/null
+++ b/pkgs/development/python-modules/aiohwenergy/default.nix
@@ -0,0 +1,40 @@
+{ lib
+, aiohttp
+, buildPythonPackage
+, fetchFromGitHub
+, pytestCheckHook
+, pythonOlder
+}:
+
+buildPythonPackage rec {
+  pname = "aiohwenergy";
+  version = "0.4.0";
+  format = "setuptools";
+
+  disabled = pythonOlder "3.7";
+
+  src = fetchFromGitHub {
+    owner = "DCSBL";
+    repo = pname;
+    rev = version;
+    sha256 = "Rs7kD+jN/z0j4KmkitquB+cm2UcYG87YHczZR0A4axI=";
+  };
+
+  propagatedBuildInputs = [
+    aiohttp
+  ];
+
+  # Project has no tests
+  doCheck = false;
+
+  pythonImportsCheck = [
+    "aiohwenergy"
+  ];
+
+  meta = with lib; {
+    description = "Python library to interact with the HomeWizard Energy devices API";
+    homepage = "https://github.com/DCSBL/aiohwenergy";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/apache-airflow/default.nix b/pkgs/development/python-modules/apache-airflow/default.nix
index 2ffe0b137528c..22a1772bf162e 100644
--- a/pkgs/development/python-modules/apache-airflow/default.nix
+++ b/pkgs/development/python-modules/apache-airflow/default.nix
@@ -58,7 +58,7 @@
 , termcolor
 , unicodecsv
 , werkzeug
-, pytest
+, pytestCheckHook
 , freezegun
 , mkYarnPackage
 }:
@@ -171,7 +171,7 @@ buildPythonPackage rec {
 
   checkInputs = [
     freezegun
-    pytest
+    pytestCheckHook
   ];
 
   INSTALL_PROVIDERS_FROM_SOURCES = "true";
@@ -199,12 +199,16 @@ buildPythonPackage rec {
 
     substituteInPlace tests/core/test_core.py \
       --replace "/bin/bash" "${stdenv.shell}"
+  '' + lib.optionalString stdenv.isDarwin ''
+    # Fix failing test on Hydra
+    substituteInPlace airflow/utils/db.py \
+      --replace "/tmp/sqlite_default.db" "$TMPDIR/sqlite_default.db"
   '';
 
   # allow for gunicorn processes to have access to python packages
   makeWrapperArgs = [ "--prefix PYTHONPATH : $PYTHONPATH" ];
 
-  checkPhase = ''
+  preCheck = ''
    export HOME=$(mktemp -d)
    export AIRFLOW_HOME=$HOME
    export AIRFLOW__CORE__UNIT_TEST_MODE=True
@@ -214,10 +218,16 @@ buildPythonPackage rec {
    airflow version
    airflow db init
    airflow db reset -y
-
-   pytest tests/core/test_core.py
   '';
 
+  pytestFlagsArray = [
+    "tests/core/test_core.py"
+  ];
+
+  disabledTests = lib.optionals stdenv.isDarwin [
+    "bash_operator_kill"  # psutil.AccessDenied
+  ];
+
   postInstall = ''
     cp -rv ${airflow-frontend}/static/dist $out/lib/${python.libPrefix}/site-packages/airflow/www/static
   '';
diff --git a/pkgs/development/python-modules/elementpath/default.nix b/pkgs/development/python-modules/elementpath/default.nix
index 810b5dfedd01a..4dc34f92365e3 100644
--- a/pkgs/development/python-modules/elementpath/default.nix
+++ b/pkgs/development/python-modules/elementpath/default.nix
@@ -5,8 +5,9 @@
 }:
 
 buildPythonPackage rec {
-  version = "2.3.2";
   pname = "elementpath";
+  version = "2.4.0";
+  format = "setuptools";
 
   disabled = pythonOlder "3.6";
 
@@ -14,13 +15,15 @@ buildPythonPackage rec {
     owner = "sissaschool";
     repo = "elementpath";
     rev = "v${version}";
-    sha256 = "01h68v077xbcnqn9v52i8d6s6i7ds3zycn3ddn11hc074m4gg3af";
+    sha256 = "1f3w5zyvrkl4gab81i5z9b41ybs54b37znj5r7hrcf25x8hrqgvv";
   };
 
   # avoid circular dependency with xmlschema which directly depends on this
   doCheck = false;
 
-  pythonImportsCheck = [ "elementpath" ];
+  pythonImportsCheck = [
+    "elementpath"
+  ];
 
   meta = with lib; {
     description = "XPath 1.0/2.0 parsers and selectors for ElementTree and lxml";
diff --git a/pkgs/development/python-modules/faraday-plugins/default.nix b/pkgs/development/python-modules/faraday-plugins/default.nix
index 4701e481b31a8..3aae84e2a2452 100644
--- a/pkgs/development/python-modules/faraday-plugins/default.nix
+++ b/pkgs/development/python-modules/faraday-plugins/default.nix
@@ -16,14 +16,14 @@
 
 buildPythonPackage rec {
   pname = "faraday-plugins";
-  version = "1.5.6";
+  version = "1.5.7";
   format = "setuptools";
 
   src = fetchFromGitHub {
     owner = "infobyte";
     repo = "faraday_plugins";
     rev = "v${version}";
-    sha256 = "sha256-RTHhCSOqtdPsgZgeziAYm+9NoR72Jfm+42fyyKqjFpA=";
+    sha256 = "sha256-EW9p5r7RwWohNGwbITtDrEd1FYLtOwWXhVWFgPCG+Po=";
   };
 
   propagatedBuildInputs = [
diff --git a/pkgs/development/python-modules/identify/default.nix b/pkgs/development/python-modules/identify/default.nix
index 37e5f5bcb8a52..fed8ddd419c02 100644
--- a/pkgs/development/python-modules/identify/default.nix
+++ b/pkgs/development/python-modules/identify/default.nix
@@ -1,14 +1,15 @@
 { lib
 , buildPythonPackage
+, editdistance-s
 , fetchFromGitHub
 , pytestCheckHook
-, editdistance-s
 , pythonOlder
+, ukkonen
 }:
 
 buildPythonPackage rec {
   pname = "identify";
-  version = "2.3.7";
+  version = "2.4.0";
   format = "setuptools";
 
   disabled = pythonOlder "3.7";
@@ -17,12 +18,13 @@ buildPythonPackage rec {
     owner = "pre-commit";
     repo = pname;
     rev = "v${version}";
-    sha256 = "sha256-L71Zi0SWFh7K4BRwF57prdrIdxLp8Igs0k/gc6k1+Mo=";
+    sha256 = "sha256-0J3P3RawafVAfOUhK9qSz5K8y0goMqTjMh5PL60sqME=";
   };
 
   checkInputs = [
     editdistance-s
     pytestCheckHook
+    ukkonen
   ];
 
   pythonImportsCheck = [
diff --git a/pkgs/development/python-modules/luxtronik/default.nix b/pkgs/development/python-modules/luxtronik/default.nix
new file mode 100644
index 0000000000000..9aab07b016653
--- /dev/null
+++ b/pkgs/development/python-modules/luxtronik/default.nix
@@ -0,0 +1,36 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, pytestCheckHook
+, poetry-core
+, pythonOlder
+}:
+
+buildPythonPackage rec {
+  pname = "luxtronik";
+  version = "0.3.9";
+  format = "setuptools";
+
+  disabled = pythonOlder "3.7";
+
+  src = fetchFromGitHub {
+    owner = "Bouni";
+    repo = "python-luxtronik";
+    rev = version;
+    sha256 = "mScdTQ82tV5fyy1S0YDDOz1UC4VB0OmSXD5gHp53WsE=";
+  };
+
+  # Project has no tests
+  doCheck = false;
+
+  pythonImportsCheck = [
+    "luxtronik"
+  ];
+
+  meta = with lib; {
+    description = "Python library to interact with Luxtronik heatpump controllers";
+    homepage = "https://github.com/Bouni/python-luxtronik";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/millheater/default.nix b/pkgs/development/python-modules/millheater/default.nix
index 0ff22033f6442..3968e8bf8088e 100644
--- a/pkgs/development/python-modules/millheater/default.nix
+++ b/pkgs/development/python-modules/millheater/default.nix
@@ -9,14 +9,16 @@
 
 buildPythonPackage rec {
   pname = "millheater";
-  version = "0.8.1";
+  version = "0.9.0";
+  format = "setuptools";
+
   disabled = pythonOlder "3.6";
 
   src = fetchFromGitHub {
     owner = "Danielhiversen";
     repo = "pymill";
     rev = version;
-    sha256 = "0269lhb6y4c13n6krsl2b66ldvzkd26jlax7bbnkvag2iv7g6hzj";
+    sha256 = "sha256-ocPp9tRghlOb0vZrpELDkwOq8ue+JBCRf2uB0Q7CPF8=";
   };
 
   propagatedBuildInputs = [
diff --git a/pkgs/development/python-modules/pyatmo/default.nix b/pkgs/development/python-modules/pyatmo/default.nix
index bff5a9b6d14cd..c039ff16b80ee 100644
--- a/pkgs/development/python-modules/pyatmo/default.nix
+++ b/pkgs/development/python-modules/pyatmo/default.nix
@@ -16,7 +16,8 @@
 
 buildPythonPackage rec {
   pname = "pyatmo";
-  version = "6.1.0";
+  version = "6.2.0";
+  format = "setuptools";
 
   disabled = pythonOlder "3.8";
 
@@ -24,7 +25,7 @@ buildPythonPackage rec {
     owner = "jabesq";
     repo = "pyatmo";
     rev = "v${version}";
-    sha256 = "sha256-Iscnv3hfYa8QFiXMUN334Muo0oGqnnK11RPNxQJggG0=";
+    sha256 = "sha256-VBc2avJiIFQW1LYXQEvIZ/wZKMFJsCF9DDrxwL8dDnk=";
   };
 
   SETUPTOOLS_SCM_PRETEND_VERSION = version;
@@ -54,7 +55,9 @@ buildPythonPackage rec {
       --replace "requests~=2.24" "requests"
   '';
 
-  pythonImportsCheck = [ "pyatmo" ];
+  pythonImportsCheck = [
+    "pyatmo"
+  ];
 
   meta = with lib; {
     description = "Simple API to access Netatmo weather station data";
diff --git a/pkgs/development/python-modules/pyebus/default.nix b/pkgs/development/python-modules/pyebus/default.nix
new file mode 100644
index 0000000000000..d4c8658673a04
--- /dev/null
+++ b/pkgs/development/python-modules/pyebus/default.nix
@@ -0,0 +1,43 @@
+{ lib
+, anytree
+, buildPythonPackage
+, fetchPypi
+, pytestCheckHook
+, poetry-core
+, pythonOlder
+}:
+
+buildPythonPackage rec {
+  pname = "pyebus";
+  version = "1.2.4";
+  format = "pyproject";
+
+  disabled = pythonOlder "3.7";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "i+p40s9SXey1lfXWW+PiXsA1kUF4o6Rk7QLmQ2ljN6g=";
+  };
+
+  nativeBuildInputs = [
+    poetry-core
+  ];
+
+  propagatedBuildInputs = [
+    anytree
+  ];
+
+  # https://github.com/c0fec0de/pyebus/issues/3
+  doCheck = false;
+
+  pythonImportsCheck = [
+    "pyebus"
+  ];
+
+  meta = with lib; {
+    description = "Pythonic Interface to EBUS Daemon (ebusd)";
+    homepage = "https://github.com/c0fec0de/pyebus";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/pyupgrade/default.nix b/pkgs/development/python-modules/pyupgrade/default.nix
index 8e355699258dc..324f0a934a5a5 100644
--- a/pkgs/development/python-modules/pyupgrade/default.nix
+++ b/pkgs/development/python-modules/pyupgrade/default.nix
@@ -8,21 +8,29 @@
 
 buildPythonPackage rec {
   pname = "pyupgrade";
-  version = "2.29.0";
+  version = "2.29.1";
+  format = "setuptools";
+
   disabled = pythonOlder "3.6";
 
   src = fetchFromGitHub {
     owner = "asottile";
     repo = pname;
     rev = "v${version}";
-    sha256 = "sha256-Hq58DJe8ZLZSJdhqSxfTaZPnWae2aQFCe7lH+6Y6ABg=";
+    sha256 = "sha256-fN0+4/EeoMD2c16OgepjDWuUhowMxzM7nB3mkL3iDjc=";
   };
 
-  checkInputs = [ pytestCheckHook ];
+  checkInputs = [
+    pytestCheckHook
+  ];
 
-  propagatedBuildInputs = [ tokenize-rt ];
+  propagatedBuildInputs = [
+    tokenize-rt
+  ];
 
-  pythonImportsCheck = [ "pyupgrade" ];
+  pythonImportsCheck = [
+    "pyupgrade"
+  ];
 
   meta = with lib; {
     description = "Tool to automatically upgrade syntax for newer versions of the language";
diff --git a/pkgs/development/python-modules/related/default.nix b/pkgs/development/python-modules/related/default.nix
new file mode 100644
index 0000000000000..ddcedc4eae6df
--- /dev/null
+++ b/pkgs/development/python-modules/related/default.nix
@@ -0,0 +1,60 @@
+{ lib
+, attrs
+, buildPythonPackage
+, fetchPypi
+, future
+, pytestCheckHook
+, python-dateutil
+, pythonOlder
+, pyyaml
+}:
+
+buildPythonPackage rec {
+  pname = "related";
+  version = "0.7.2";
+  format = "setuptools";
+
+  disabled = pythonOlder "3.7";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "w0XmNWh1xF08qitH22lQgTRNqO6qyYrYd2dc6x3Fop0=";
+  };
+
+  propagatedBuildInputs = [
+    attrs
+    future
+    python-dateutil
+    pyyaml
+  ];
+
+  checkInputs = [
+    pytestCheckHook
+  ];
+
+  postPatch = ''
+    # Remove outdated setup.cfg
+    rm setup.cfg
+    substituteInPlace setup.py \
+      --replace "'pytest-runner'," ""
+  '';
+
+  disabledTests = [
+    # Source tarball doesn't contains all needed files
+    "test_compose_from_yml"
+    "test_yaml_roundtrip_with_empty_values"
+    "test_compose_from_yml"
+    "test_store_data_from_json"
+  ];
+
+  pythonImportsCheck = [
+    "related"
+  ];
+
+  meta = with lib; {
+    description = "Nested Object Models in Python";
+    homepage = "https://github.com/genomoncology/related";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/roombapy/default.nix b/pkgs/development/python-modules/roombapy/default.nix
index 459037d6191e9..cc73e58fc7b80 100644
--- a/pkgs/development/python-modules/roombapy/default.nix
+++ b/pkgs/development/python-modules/roombapy/default.nix
@@ -11,20 +11,25 @@
 
 buildPythonPackage rec {
   pname = "roombapy";
-  version = "1.6.3";
+  version = "1.6.4";
   format = "pyproject";
+
   disabled = pythonOlder "3.7";
 
   src = fetchFromGitHub {
     owner = "pschmitt";
     repo = "roombapy";
     rev = version;
-    sha256 = "sha256-GkDfIC2jx4Mpguk/Wu45pZw0czhabJwTz58WYSLCOV8=";
+    sha256 = "sha256-EN+em+lULAUplXlhcU409ZVPk9BfMmD2oNwO0ETuqoA=";
   };
 
-  nativeBuildInputs = [ poetry-core ];
+  nativeBuildInputs = [
+    poetry-core
+  ];
 
-  propagatedBuildInputs = [ paho-mqtt ];
+  propagatedBuildInputs = [
+    paho-mqtt
+  ];
 
   checkInputs = [
     amqtt
@@ -37,12 +42,19 @@ buildPythonPackage rec {
     "tests/test_discovery.py"
   ];
 
-  pythonImportsCheck = [ "roombapy" ];
+  disabledTests = [
+    # Test want to connect to a local MQTT broker
+    "test_roomba_connect"
+  ];
+
+  pythonImportsCheck = [
+    "roombapy"
+  ];
 
   meta = with lib; {
-    homepage = "https://github.com/pschmitt/roombapy";
     description = "Python program and library to control Wi-Fi enabled iRobot Roombas";
-    maintainers = with maintainers; [ justinas ];
+    homepage = "https://github.com/pschmitt/roombapy";
     license = licenses.mit;
+    maintainers = with maintainers; [ justinas ];
   };
 }
diff --git a/pkgs/development/python-modules/tweepy/default.nix b/pkgs/development/python-modules/tweepy/default.nix
index 7892975a45d9c..a98911da58d5a 100644
--- a/pkgs/development/python-modules/tweepy/default.nix
+++ b/pkgs/development/python-modules/tweepy/default.nix
@@ -12,7 +12,7 @@
 
 buildPythonPackage rec {
   pname = "tweepy";
-  version = "4.3.0";
+  version = "4.4.0";
   format = "setuptools";
 
   disabled = pythonOlder "3.6";
@@ -21,7 +21,7 @@ buildPythonPackage rec {
     owner = pname;
     repo = pname;
     rev = "v${version}";
-    sha256 = "sha256-lS/98DRpJH1UGGNzwqVVUJOeul+BX+I3e+ysmC0oL3I=";
+    sha256 = "sha256-GUo8uvShyIOWWcO5T1JvV7DMC1W70YILx/hvHIGQg0o=";
   };
 
   propagatedBuildInputs = [
diff --git a/pkgs/development/python-modules/ukkonen/default.nix b/pkgs/development/python-modules/ukkonen/default.nix
new file mode 100644
index 0000000000000..dfdcf3515220c
--- /dev/null
+++ b/pkgs/development/python-modules/ukkonen/default.nix
@@ -0,0 +1,41 @@
+{ lib
+, buildPythonPackage
+, fetchFromGitHub
+, cffi
+, pytestCheckHook
+, pythonOlder
+}:
+
+buildPythonPackage rec {
+  pname = "ukkonen";
+  version = "1.0.1";
+  format = "setuptools";
+
+  disabled = pythonOlder "3.6";
+
+  src = fetchFromGitHub {
+    owner = "asottile";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "jG6VP/P5sadrdrmneH36/ExSld9blyMAAG963QS9+p0=";
+  };
+
+  nativeBuildInputs = [
+    cffi
+  ];
+
+  checkInputs = [
+    pytestCheckHook
+  ];
+
+  pythonImportsCheck = [
+    "ukkonen"
+  ];
+
+  meta = with lib; {
+    description = "Python implementation of bounded Levenshtein distance (Ukkonen)";
+    homepage = "https://github.com/asottile/ukkonen";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/uonet-request-signer-hebe/default.nix b/pkgs/development/python-modules/uonet-request-signer-hebe/default.nix
new file mode 100644
index 0000000000000..19d4bba0b9745
--- /dev/null
+++ b/pkgs/development/python-modules/uonet-request-signer-hebe/default.nix
@@ -0,0 +1,37 @@
+{ lib
+, buildPythonPackage
+, fetchPypi
+, pythonOlder
+, pyopenssl
+}:
+
+buildPythonPackage rec {
+  pname = "uonet-request-signer-hebe";
+  version = "0.1.1";
+  format = "setuptools";
+
+  disabled = pythonOlder "3.6";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "fidopnpAt5CXPsLbx+V8wrJCQQ/WIO6AqxpsYLDv8qM=";
+  };
+
+  propagatedBuildInputs = [
+    pyopenssl
+  ];
+
+  # Source is not tagged
+  doCheck = false;
+
+  pythonImportsCheck = [
+    "uonet_request_signer_hebe"
+  ];
+
+  meta = with lib; {
+    description = "UONET+ (hebe) request signer for Python";
+    homepage = "https://github.com/wulkanowy/uonet-request-signer";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/vulcan-api/default.nix b/pkgs/development/python-modules/vulcan-api/default.nix
new file mode 100644
index 0000000000000..6355e37bd64da
--- /dev/null
+++ b/pkgs/development/python-modules/vulcan-api/default.nix
@@ -0,0 +1,57 @@
+{ lib
+, aenum
+, aiodns
+, aiohttp
+, buildPythonPackage
+, cchardet
+, fetchFromGitHub
+, pyopenssl
+, pythonOlder
+, pytz
+, related
+, requests
+, uonet-request-signer-hebe
+, yarl
+}:
+
+buildPythonPackage rec {
+  pname = "vulcan-api";
+  version = "2.0.3";
+  format = "setuptools";
+
+  disabled = pythonOlder "3.6";
+
+  src = fetchFromGitHub {
+    owner = "kapi2289";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "YLt9yufOBlWRyo+le7HcaFD/s7V5WpvhMUrHJqyC3pY=";
+  };
+
+  propagatedBuildInputs = [
+    aenum
+    aiodns
+    aiohttp
+    cchardet
+    pyopenssl
+    pytz
+    related
+    requests
+    uonet-request-signer-hebe
+    yarl
+  ];
+
+  # Project has no tests
+  doCheck = false;
+
+  pythonImportsCheck = [
+    "vulcan"
+  ];
+
+  meta = with lib; {
+    description = "Python library for UONET+ e-register API";
+    homepage = "https://vulcan-api.readthedocs.io/";
+    license = licenses.mit;
+    maintainers = with maintainers; [ fab ];
+  };
+}
diff --git a/pkgs/development/python-modules/xmlschema/default.nix b/pkgs/development/python-modules/xmlschema/default.nix
index 19667d833faad..3ddcfee9dfb51 100644
--- a/pkgs/development/python-modules/xmlschema/default.nix
+++ b/pkgs/development/python-modules/xmlschema/default.nix
@@ -8,7 +8,7 @@
 }:
 
 buildPythonPackage rec {
-  version = "1.8.1";
+  version = "1.8.2";
   pname = "xmlschema";
 
   disabled = pythonOlder "3.6";
@@ -17,7 +17,7 @@ buildPythonPackage rec {
     owner = "sissaschool";
     repo = "xmlschema";
     rev = "v${version}";
-    sha256 = "0vs4d9bnms4krxvplzf2p69g673pdw31z8p5alzj3pqnaw83rg1z";
+    sha256 = "sha256-d7f19T17aAwdtNDjCrsXXY39u0aRgQo4vFPnxFNs2PQ=";
   };
 
   propagatedBuildInputs = [
diff --git a/pkgs/development/tools/analysis/checkov/default.nix b/pkgs/development/tools/analysis/checkov/default.nix
index e4123a8f105e8..a2fc83bc2b213 100644
--- a/pkgs/development/tools/analysis/checkov/default.nix
+++ b/pkgs/development/tools/analysis/checkov/default.nix
@@ -56,13 +56,13 @@ with py.pkgs;
 
 buildPythonApplication rec {
   pname = "checkov";
-  version = "2.0.587";
+  version = "2.0.591";
 
   src = fetchFromGitHub {
     owner = "bridgecrewio";
     repo = pname;
     rev = version;
-    sha256 = "sha256-uLH3g3UeWdIZsMsUwCYpTehgxDKGraPBlENdTz+QYLI=";
+    sha256 = "sha256-p8pEw3vH3W62MmlZsSqWoUKf7QjEQhlV5bSjYr1Wwm0=";
   };
 
   nativeBuildInputs = with py.pkgs; [
diff --git a/pkgs/tools/admin/trivy/default.nix b/pkgs/tools/admin/trivy/default.nix
index 60bf80653a4c8..4330e11bce618 100644
--- a/pkgs/tools/admin/trivy/default.nix
+++ b/pkgs/tools/admin/trivy/default.nix
@@ -1,22 +1,27 @@
-{ lib, buildGoModule, fetchFromGitHub }:
+{ lib
+, buildGoModule
+, fetchFromGitHub
+}:
 
 buildGoModule rec {
   pname = "trivy";
-  version = "0.20.2";
+  version = "0.21.0";
 
   src = fetchFromGitHub {
     owner = "aquasecurity";
     repo = pname;
     rev = "v${version}";
-    sha256 = "sha256-ittOVWsM+1IaILCLCJNOeLxRbRHiiMN4qgLTS9gxV0w=";
+    sha256 = "sha256-weLzW1pyv9q9VKvFxno+f/L29wlpvxlVUZJUwx6Gn2A=";
   };
 
-  vendorSha256 = "sha256-HrDj09gUJtkZhQ3nYfoj0K8+T62ib0CWAhhcuvg8cyc=";
+  vendorSha256 = "sha256-1kQ2m8gFBHKznbjNPtYN0BVrRbxyCs2H1f7+XZqgVvc=";
 
   excludedPackages = "misc";
 
   ldflags = [
-    "-s" "-w" "-X main.version=v${version}"
+    "-s"
+    "-w"
+    "-X main.version=v${version}"
   ];
 
   doInstallCheck = true;
diff --git a/pkgs/tools/filesystems/nilfs-utils/default.nix b/pkgs/tools/filesystems/nilfs-utils/default.nix
index ec227c95573fb..07c2c5292dcf8 100644
--- a/pkgs/tools/filesystems/nilfs-utils/default.nix
+++ b/pkgs/tools/filesystems/nilfs-utils/default.nix
@@ -15,6 +15,11 @@ stdenv.mkDerivation rec {
 
   buildInputs = [ libuuid libselinux ];
 
+  # According to upstream, libmount should be detected automatically but the
+  # build system fails to do this. This is likely a bug with their build system
+  # hence it is explicitly enabled here.
+  configureFlags = [ "--with-libmount" ];
+
   installFlags = [
     "sysconfdir=${placeholder "out"}/etc"
     "root_sbindir=${placeholder "out"}/sbin"
diff --git a/pkgs/tools/security/masscan/default.nix b/pkgs/tools/security/masscan/default.nix
index 46bae3c20c51a..b7924936d6caf 100644
--- a/pkgs/tools/security/masscan/default.nix
+++ b/pkgs/tools/security/masscan/default.nix
@@ -17,6 +17,11 @@ stdenv.mkDerivation rec {
     sha256 = "sha256-mnGC/moQANloR5ODwRjzJzBa55OEZ9QU+9WpAHxQE/g=";
   };
 
+  postPatch = lib.optionalString stdenv.isDarwin ''
+    # Fix broken install command
+    substituteInPlace Makefile --replace "-pm755" "-pDm755"
+  '';
+
   nativeBuildInputs = [ makeWrapper installShellFiles ];
 
   makeFlags = [
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index 36622143b74b6..9229deff1af92 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -315,6 +315,8 @@ in {
 
   aiohue = callPackage ../development/python-modules/aiohue { };
 
+  aiohwenergy = callPackage ../development/python-modules/aiohwenergy { };
+
   aioimaplib = callPackage ../development/python-modules/aioimaplib { };
 
   aioinflux = callPackage ../development/python-modules/aioinflux { };
@@ -4539,6 +4541,8 @@ in {
 
   luftdaten = callPackage ../development/python-modules/luftdaten { };
 
+  luxtronik = callPackage ../development/python-modules/luxtronik { };
+
   lupa = callPackage ../development/python-modules/lupa { };
 
   lupupy = callPackage ../development/python-modules/lupupy { };
@@ -6372,6 +6376,8 @@ in {
 
   pydyf = callPackage ../development/python-modules/pydyf { };
 
+  pyebus = callPackage ../development/python-modules/pyebus { };
+
   pyechonest = callPackage ../development/python-modules/pyechonest { };
 
   pyeclib = callPackage ../development/python-modules/pyeclib { };
@@ -8092,6 +8098,8 @@ in {
 
   reikna = callPackage ../development/python-modules/reikna { };
 
+  related = callPackage ../development/python-modules/related { };
+
   relatorio = callPackage ../development/python-modules/relatorio { };
 
   remarshal = callPackage ../development/python-modules/remarshal { };
@@ -9584,6 +9592,8 @@ in {
 
   ujson = callPackage ../development/python-modules/ujson { };
 
+  ukkonen = callPackage ../development/python-modules/ukkonen { };
+
   ukpostcodeparser = callPackage ../development/python-modules/ukpostcodeparser { };
 
   umalqurra = callPackage ../development/python-modules/umalqurra { };
@@ -9638,6 +9648,8 @@ in {
 
   untokenize = callPackage ../development/python-modules/untokenize { };
 
+  uonet-request-signer-hebe = callPackage ../development/python-modules/uonet-request-signer-hebe { };
+
   upass = callPackage ../development/python-modules/upass { };
 
   upb-lib = callPackage ../development/python-modules/upb-lib { };
@@ -9809,6 +9821,8 @@ in {
     enablePython = true;
   });
 
+  vulcan-api = callPackage ../development/python-modules/vulcan-api { };
+
   vultr = callPackage ../development/python-modules/vultr { };
 
   vulture = callPackage ../development/python-modules/vulture { };