NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
16.48k stars 12.98k forks source link

`interception-tools` service no longer working #126681

Open bnjmnt4n opened 3 years ago

bnjmnt4n commented 3 years ago

Describe the bug I've added services.interception-tools.enable = true to my configuration. Since the latest nixos-unstable channel commit (https://github.com/NixOS/nixpkgs/commit/432fc2d9a67f92e05438dff5fdc2b39d33f77997), the caps2esc module which was previously enabled by default no longer works.

To Reproduce Steps to reproduce the behavior:

  1. Add services.interception-tools.enable = true to your configuration
  2. Use nixpkgs commit https://github.com/NixOS/nixpkgs/commit/432fc2d9a67f92e05438dff5fdc2b39d33f77997 (latest unstable channel)

Expected behavior The module should be enabled, ie. pressing CapsLock should map to escape, except when holding down the CapsLock button and pressing alongside another key, which should map to Ctrl + other key.

Additional context Here's the output of systemctl status interception-tools.service:

● interception-tools.service - Interception tools
     Loaded: loaded (/nix/store/ww8jjn911x7zx2q6xqw8z3wg6b0y69hb-unit-interception-tools.service/interception-tools.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2021-06-12 23:18:00 +08; 19min ago
   Main PID: 824 (udevmon)
         IP: 0B in, 0B out
         IO: 2.8M read, 0B written
      Tasks: 1 (limit: 9226)
     Memory: 3.5M
        CPU: 39ms
     CGroup: /system.slice/interception-tools.service
             └─824 /nix/store/r4dw5nhkaqa3bd5x03aj5zlhwxvw4lpr-interception-tools-0.6.6/bin/udevmon -c /nix/store/1d442lnl74qs3chdw1x51zybrkad0aby-udevmon.yaml

Jun 12 23:18:00 gastropod systemd[1]: Started Interception tools.
Jun 12 23:18:03 gastropod udevmon[938]: sh: intercept: command not found
Jun 12 23:18:03 gastropod udevmon[939]: sh: caps2esc: command not found
Jun 12 23:18:03 gastropod udevmon[940]: sh: uinput: command not found
Jun 12 23:18:03 gastropod udevmon[942]: sh: intercept: command not found
Jun 12 23:18:03 gastropod udevmon[943]: sh: caps2esc: command not found
Jun 12 23:18:03 gastropod udevmon[944]: sh: uinput: command not found

Notify maintainers

Metadata

 - system: `"x86_64-linux"`
 - host os: `Linux 5.12.9, NixOS, 21.11.20210610.432fc2d (Porcupine)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.4pre20210601_5985b8b`
 - channels(bnjmnt4n): `""`
 - channels(root): `"nixos-21.03pre269343.758b29b5a28"`
 - nixpkgs: `/nix/store/v13yb14bkddyc1rxlrna5j3441pyh0r8-source`

Maintainer information:

# a list of nixpkgs attributes affected by the problem
attribute:
# a list of nixos modules affected by the problem
module: interception-tools
bnjmnt4n commented 3 years ago

Here's the output of the generated configuration file:

$ cat /nix/store/1d442lnl74qs3chdw1x51zybrkad0aby-udevmon.yaml
- JOB: "intercept -g $DEVNODE | caps2esc | uinput -d $DEVNODE"
  DEVICE:
    EVENTS:
      EV_KEY: [KEY_CAPSLOCK, KEY_ESC]

It seems like the PATH is wrong and the binaries are not being detected from their location in the nix store:

$ ls /nix/store/r4dw5nhkaqa3bd5x03aj5zlhwxvw4lpr-interception-tools-0.6.6/bin/
intercept  mux  udevmon  uinput

Additionally, it seems like the caps2esc binary is not there? It seems like the caps2esc plugin was always in a separate derivation.

For now I've switched to manually specifying the binaries path like below:

# Map CapsLock to Esc on single press and Ctrl on when used with multiple keys.
services.interception-tools = {
  enable = true;
  plugins = [ pkgs.interception-tools-plugins.caps2esc ];
  udevmonConfig = ''
    - JOB: "${pkgs.interception-tools}/bin/intercept -g $DEVNODE | ${pkgs.interception-tools-plugins.caps2esc}/bin/caps2esc | ${pkgs.interception-tools}/bin/uinput -d $DEVNODE"
      DEVICE:
        EVENTS:
          EV_KEY: [KEY_CAPSLOCK, KEY_ESC]
  '';
};
FireyFly commented 3 years ago

I came across this as well when updating my system today... to be honest, I think the proper fix here is to require explicit paths in the udevmon config (as in what you're doing for now), so that there's clear references to the dependencies as well. The current config doesn't strike me as very NixOS-y.

I think moving to explicit full paths to binaries would also let us get rid of the plugins config option, since it's only used for putting things in the PATH of udevmon. However, it would break backwards compatibility somewhat, in particular it'd make it pointless to handle the case of passing a path to a YAML file for the udevmonConfig option, and it'd also break the module for people setting plugins + relying on referencing binaries by name in the yaml config.

On the upside... I think this is a good opportunity to switch the interception-tools module over to an RFC 42-style settings option with structured configuration that gets serialized to YAML, especially if we somewhat break backwards compatibility either way. Thoughts?

stale[bot] commented 2 years ago

I marked this as stale due to inactivity. → More info

jfly commented 2 years ago

I dug into this a bit. It turns out that udevmon is actually clearing the PATH before it uses sh to invoke the jobs it has been given. I filed https://gitlab.com/interception/linux/tools/-/issues/58 to track this.

That all said, @FireyFly's suggestion to get rid of the plugins directories in favor of explicit full paths sounds great to me!

nixos-discourse commented 1 year ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/troubleshooting-help-services-interception-tools/20389/5

lheckemann commented 1 year ago

I quite like the plugins+PATH approach, it makes the config a lot easier to read and doesn't prevent use of explicit paths if you prefer those.

I've started RFC42-ising this and will submit a PR along with a patch fixing the PATH issue, soon :)