Troubles overriding a package used in a service

Hi,

I’m having trouble overriding a package used by a service. The system (and package) seem to build successfully, but my new/modified package is not used by the service.

I’ve tried using an overlay:

  nixpkgs.overlays = [
    (self: super: {
      zigbee2mqtt = super.zigbee2mqtt.overrideAttrs (old: rec {
        version = "1.21.0";
        src = super.fetchFromGitHub {
          owner = "Koenkk";
          repo = "zigbee2mqtt";
          rev = version;
          sha256 = "064qn970pqw07gdwy0jmhjgwi3qn1wiv81313zrcrpnprirkicd9";
        };
      });
    })
  ];

  services.zigbee2mqtt = {
    enable = true;
    package = pkgs.zigbee2mqtt;
    settings = {
      homeassistant = config.services.home-assistant.enable;
      serial = {
        adapter = "deconz";
      };
      advanced = {
        log_level = "debug";
      };
    };
  };

I have also tried overriding the package directly within the service definition, as it supports a package attribute, as follows:

  services.zigbee2mqtt = {
    enable = true;
    package = pkgs.zigbee2mqtt.overrideAttrs (old: rec {
        version = "1.21.0";
        src = pkgs.fetchFromGitHub {
          owner = "Koenkk";
          repo = "zigbee2mqtt";
          rev = version;
          sha256 = "064qn970pqw07gdwy0jmhjgwi3qn1wiv81313zrcrpnprirkicd9";
        };
    });
    settings = {
      homeassistant = config.services.home-assistant.enable;
      serial = {
        adapter = "deconz";
      };
      advanced = {
        log_level = "debug";
      };
    };
  };

In both cases, the old/regular version of the package seems to be in use, as opposed to my overridden version:


$ systemctl status zigbee2mqtt
● zigbee2mqtt.service - Zigbee2mqtt Service
     Loaded: loaded (/nix/store/9blyzvqa13iclgp66pwcpgrid99a9pwg-unit-zigbee2mqtt.service/zigbee2mqtt.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2021-08-19 17:37:16 UTC; 14min ago
    Process: 706 ExecStartPre=/nix/store/x1blm7sgv322nybaprxqd0cb6rabj8lf-unit-script-zigbee2mqtt-pre-start/bin/zigbee2mqtt-pre-start (code=exited, status=0/SUCCESS)
   Main PID: 720 (zigbee2mqtt)
         IP: 1.1K in, 2.8K out
         IO: 39.1M read, 20.0K written
      Tasks: 11 (limit: 4014)
     Memory: 107.5M
        CPU: 7.526s
     CGroup: /system.slice/zigbee2mqtt.service
             └─720 /nix/store/rqqs607h0ckfzzax44xki9wqv0fd5k5f-nodejs-12.22.4/bin/node /nix/store/y29lwx2gdxq4gn6863r48b3kydzf8ing-node_zigbee2mqtt-1.16.2/bin/zigbee2mqtt

I assume you ran sudo nixos-rebuild switch to apply the changes, in which case, you may need to do sudo systemctl reload-or-restart zigbee2mqtt, as not all services will reload when changed.

To have it automatically reload on change, you can add:

systemd.services.zigbee2mqtt.reloadIfChanged = true;

I’m assuming this wasn’t done because zigbee should optimise for uptime, and reloading or restarting a service could cause issues in production.

Apologies for the delay; Seems I missed the reply notification.

I’m not sure this is a service start/top issue: The service is already restarted by the rebuild, and the problem is present even after a full reboot, with the nix store path in use by zigbee2mqtt.service being /nix/store/rqqs607h0ckfzzax44xki9wqv0fd5k5f-nodejs-12.22.4/bin/node /nix/store/y29lwx2gdxq4gn6863r48b3kydzf8ing-node_zigbee2mqtt-1.16.2/bin/zigbee2mqtt (and 1.16.2 being the old version)

If you try to evaluate your custom derivation with nix repl

nix-repl> zigbee2mqtt.overrideAttrs (old: rec {
  version = "1.21.0";
  src = fetchFromGitHub {
    owner = "Koenkk";
    repo = "zigbee2mqtt";
    rev = version;
    sha256 = "064qn970pqw07gdwy0jmhjgwi3qn1wiv81313zrcrpnprirkicd9";
  };
})
«derivation /nix/store/9dmbg67j457nbw2jss3s7qfhiyys2ylc-node_zigbee2mqtt-1.16.2.drv»

You will see that the version is still 1.16.2. This is probably because the original derivation forces that version in here.

You can do something like this to possibly circumvent that:

let
  package = (import "${<nixpkgs>}/pkgs/servers/zigbee2mqtt/node.nix" {}).package;
  custom-zigbee2mqtt =  package.override rec {
    version = "1.21.0";
    src = fetchFromGitHub {
      owner = "Koenkk";
      repo = "zigbee2mqtt";
      rev = version;
      sha256 = "064qn970pqw07gdwy0jmhjgwi3qn1wiv81313zrcrpnprirkicd9";
    };
  };
in
custom-zigbee2mqtt

But I am not saying this is a good idea or that it will work or even be built.

You need to use override instead of overrideAttrs because we need to override these parameters. The latter only modifies the values passed to mkDerivation.