How to create files in the `/etc/udev/rules.d/` directory?

There is a software that needs to check whether the specified file in this directory exists. I know that you can use services.udev.extraRules to add new rule content, but it can’t generate the file I need, so it can’t achieve the goal.

Try to use environment.etc."udev/rules.d/99-steelseries-rival.rules".text = ... to generate this file, but it still fails. This method will cause permission problems: ln: failed to create symbolic link'/nix/store/10snfh4rgdifz7jzda7j33q24jri743s-etc/etc/udev/rules.d/99-steelseries-rival.rules': Permission denied.

Note: I used sudo to run the nixos-rebuild switch command.

1 Like

okay, I had a play with this, and your right, it seems that udev files cannot be added in this way. :-(. This looks like it’s by design

However i see in nixpkgs/blob/nixos-20.09/nixos/modules/services/hardware/udev.nix

a bit of bash


      # Add the udev rules from other packages.
      for i in $packages; do
        echo "Adding rules for package $i"
        for j in $i/{etc,lib}/udev/rules.d/*; do
          echo "Copying $j to $out/$(basename $j)"
          cat $j > $out/$(basename $j)
        done
      done

which i think is wired to

services.udev.packges
    services.udev = {

      packages = mkOption {
        type = types.listOf types.path;
        default = [];
        description = ''
          List of packages containing <command>udev</command> rules.
          All files found in
          <filename><replaceable>pkg</replaceable>/etc/udev/rules.d</filename> and
          <filename><replaceable>pkg</replaceable>/lib/udev/rules.d</filename>
          will be included.
        '';
        apply = map getBin;
      };

this seens to copy udev rules from nix/OS packages.

This has a down side that you will need to create a package, which contains your udev file then
do

sevices.udev.package = [ mypackage ];

this examples may help

  services.udev.packages = with pkgs; [
    ledger-udev-rules
  ];

if you check out

pkgs/os-specific/linux/ledger-udev-rules/default.nix

you can see

which you may be able to adapt to your own package.

If you get stuck i can probably hacksome thing together for you if i have time… !

There maybe an easier way to do this…

1 Like

You can create single file packages using trivial builders. For example:

writeTextFile {
  name = "my-udev-package";
  text = ''
    …
  '';
  destination = "/lib/udev/rules.d/20-ledger.rules";
}
2 Likes

very nice!!!