I am using Fusuma for controlling swipe on touchpad. As NixOS doesn’t provide a configuration for it, I currently handle its initialization from services.xserver.displayManager.sessionCommands.
As I am a newbie to NixOS, I wonder if this is correct. Is there a better option?
proper thing would probably create an actual systemd service, or create a module, then set it true.
Something like
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.services.fusuma;
in {
options.services.fusuma = {
enable = mkEnableOption "Enable fusuma service";
package = mkOption {
type = types.package;
default = pkgs.fusuma;
defaultText = "pkgs.fusuma";
description = "Set version of fusuma package to use.";
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ]; # if user should have the command available as well
services.dbus.packages = [ cfg.package ]; # if the package has dbus related configuration
systemd.services.fusuma = {
description = "Fusuma server daemon.";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ]; # if networking is needed
restartIfChanged = true; # set to false, if restarting is problematic
serviceConfig = {
DynamicUser = true;
ExecStart = "${cfg.package}/bin/fusuma";
Restart = "always";
};
};
};
meta.maintainers = with lib.maintainers; [ ];
}
This is really awesome, thank you! I will look into it.
I guess I can use these code by simply import back into configuration.nix. If I want to make a PR and contribute to github, is there anymore thing that I need to handle?
After some research and using your code as a reference, I am able to come up with this:
{ pkgs, lib, config, ... }:
with lib;
let cfg = config.services.fusuma;
in {
options.services.fusuma = {
enable = mkEnableOption "Enable fusuma service";
package = mkOption {
type = types.package;
default = pkgs.fusuma;
defaultText = "pkgs.fusuma";
description = "Set the version of fusuma";
};
configFile = mkOption {
type = types.str;
description = "Path for fusuma's configuration file";
default = "~/.config/fusuma/config.yaml";
};
};
config = mkIf cfg.enable {
systemd.services.fusuma = {
description = "Start fusuma to handle swipe";
wantedBy = [ "multi-user.target" ];
after = [ "graphical-session.target" ];
restartIfChanged = true;
serviceConfig = {
Restart = "always";
DynamicUser = true;
ExecStart = ''sudo ${cfg.package}/bin/fusuma --config=${cfg.configFile}'';
};
};
};
meta.maintainers = with lib.maintainers; [ ];
}
But how can I use sudo with ExecStart? Without sudo, fusuma is unable to track the touchpad. But right now as I have added sudo onto it, the process doesn’t start. If taking the sudo out, I will be able to ps aux | grep fusuma.
sudo executes the command as the root user. If you want to run a service as the root user, you should start it as the root user in the first place
Normally system-wide systemd services are run as root, but the option DynamicUser turns off running services as root. So simply remove that line from your service to do that.
I looked at fusuma more closely; it expects to be run as the user who is using the X instance (i.e., whoever logged in).
This means it shouldn’t work as root or a DynamicUser.
Instead, it would be best to run it with systemd.user.services, which are executed as the user who starts the unit.
You may then also need to set systemd.user.units..wantedBy to graphical.target, so that it is run after the X server is started and available for fusuma to pick up.
It is really weird, as I tried to debug by running the command manually, I got the following error:
❯ /nix/store/81gmv3nnn6j50rwn5frdz5v8qlva5b9k-fusuma-1.3.0/bin/.fusuma-wrapped --config=/home/hugosum/.config/fusuma/config.yaml
I, [2021-07-12T21:40:09.767415 #4427] INFO -- : reload config : /nix/store/krdk46sfsxfj6z679xr7ilbgxi0xp3di-ruby2.7.4-fusuma-1.3.0/lib/ruby/gems/2.7.0/gems/fusuma-1.3.0/lib/fusuma/config.yml
I, [2021-07-12T21:40:09.767571 #4427] INFO -- : reload config : /home/hugosum/.config/fusuma/config.yaml
I, [2021-07-12T21:40:09.781336 #4427] INFO -- : ---------------------------------------------
I, [2021-07-12T21:40:09.781369 #4427] INFO -- : Fusuma: 1.3.0
E, [2021-07-12T21:40:09.781458 #4427] ERROR -- : install libinput-tools
But if I run fusuma in the nix-shell with the same flag, it is running correctly (so the package is bundled correctly???)
~
❮ nix-shell -p fusuma
[nix-shell:~]$ fusuma --config=/home/hugosum/.config/fusuma/config.yaml
I, [2021-07-12T21:44:16.143536 #5014] INFO -- : reload config : /nix/store/krdk46sfsxfj6z679xr7ilbgxi0xp3di-ruby2.7.4-fusuma-1.3.0/lib/ruby/gems/2.7.0/gems/fusuma-1.3.0/lib/fusuma/config.yml
I, [2021-07-12T21:44:16.143718 #5014] INFO -- : reload config : /home/hugosum/.config/fusuma/config.yaml
I, [2021-07-12T21:44:16.156867 #5014] INFO -- : ---------------------------------------------
I, [2021-07-12T21:44:16.156900 #5014] INFO -- : Fusuma: 1.3.0
I, [2021-07-12T21:44:16.158616 #5014] INFO -- : libinput: 1.16.4
I, [2021-07-12T21:44:16.160462 #5014] INFO -- : OS: Linux 5.10.48 #1-NixOS SMP Wed Jul 7 12:27:50 UTC 2021
I, [2021-07-12T21:44:16.161440 #5014] INFO -- : Distribution:
<<< Welcome to NixOS 21.05.1408.9376bf7b342 (\m) - \l >>>
Run 'nixos-help' for the NixOS manual.
I, [2021-07-12T21:44:16.164673 #5014] INFO -- : Desktop session: none+leftwm
I, [2021-07-12T21:44:16.164759 #5014] INFO -- : ---------------------------------------------
I, [2021-07-12T21:44:16.164791 #5014] INFO -- : ---------------------------------------------
I, [2021-07-12T21:44:16.164819 #5014] INFO -- : Enabled Plugins:
I, [2021-07-12T21:44:16.165124 #5014] INFO -- : Fusuma::Plugin::Buffers::GestureBuffer
I, [2021-07-12T21:44:16.165220 #5014] INFO -- : Fusuma::Plugin::Detectors::PinchDetector
I, [2021-07-12T21:44:16.165268 #5014] INFO -- : Fusuma::Plugin::Detectors::RotateDetector
I, [2021-07-12T21:44:16.165313 #5014] INFO -- : Fusuma::Plugin::Detectors::SwipeDetector
I, [2021-07-12T21:44:16.165351 #5014] INFO -- : Fusuma::Plugin::Events::Records::GestureRecord
I, [2021-07-12T21:44:16.165461 #5014] INFO -- : Fusuma::Plugin::Events::Records::IndexRecord
I, [2021-07-12T21:44:16.165526 #5014] INFO -- : Fusuma::Plugin::Events::Records::TextRecord
I, [2021-07-12T21:44:16.165571 #5014] INFO -- : Fusuma::Plugin::Executors::CommandExecutor
I, [2021-07-12T21:44:16.165616 #5014] INFO -- : Fusuma::Plugin::Filters::LibinputDeviceFilter
I, [2021-07-12T21:44:16.165671 #5014] INFO -- : Fusuma::Plugin::Inputs::LibinputCommandInput
I, [2021-07-12T21:44:16.165733 #5014] INFO -- : Fusuma::Plugin::Parsers::LibinputGestureParser
I, [2021-07-12T21:44:16.165821 #5014] INFO -- : ---------------------------------------------
Nix will transparently set up LD_LIBRARY_PATH (and similar for other languages, e.g. PYTHONPATH) to point your binaries at the version of the library they need to run with.
This enables running multiple versions of the same libraries without patching the binary, as well as lots of other nice things, like ensuring that package builds don’t take in libraries they shouldn’t (though this is handled by containers now aiui), and general clean isolation between packages. Where the binary does need patching, nix packages will usually actually do so to ensure reproducibility.
The binaries in /nix/store shouldn’t generally be expected to run, even if they often do. I think this will generally fail for scripting languages like ruby, at least if they depend on system libraries.
Hence, the best way to debug is nix-shell, or maybe running the systemd service directly.
The fusuma file is a script that sets up some variables and then runs .fusuma-wrapped. ps lists the running processes, and since the script uses exec it will no longer be running.
Hence you see the wrapped version.
What is the error? Are you looking at journalctl's output or assuming that your manual run produces the same result as the unit?
For reference, to see the logs of a systemd service, you would run: journalctl -xe --unit <service name>. I think the name would be fusuma.service here. Add a --user after -xe if you’re working on a user unit.
but unfortunately it doesn’t work. After a home-manager switch I get
...
The user systemd session is degraded:
UNIT LOAD ACTIVE SUB DESCRIPTION
● fusuma.service loaded failed failed Fusuma multitouch gesture recognizer
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
1 loaded units listed.
Attempting to reload services anyway...
and systemctl --user status fusuma.service returns
● fusuma.service - Fusuma multitouch gesture recognizer
Loaded: loaded (/nix/store/rpgqxlnj467mmj62g2kj8gby59d5zkac-home-manager-files/.config/systemd/user/fusuma.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2021-07-17 15:17:23 CEST; 10min ago
Main PID: 16649 (code=exited, status=1/FAILURE)
CPU: 133ms
Jul 17 15:17:23 blade fusuma[16649]: I, [2021-07-17T15:17:23.934614 #16649] INFO -- : libinput: 1.16.4
Jul 17 15:17:23 blade fusuma[16649]: /nix/store/wmpvdlhvsw5bbfar933kz1l6gj86iq6g-ruby2.7.3-fusuma-1.3.0/lib/ruby/gems/2.7.0/gems/fusuma-1.3.0/lib/fusuma.rb:50:in ``': No such file or directory - uname (Errno::ENOENT)
Jul 17 15:17:23 blade fusuma[16649]: from /nix/store/wmpvdlhvsw5bbfar933kz1l6gj86iq6g-ruby2.7.3-fusuma-1.3.0/lib/ruby/gems/2.7.0/gems/fusuma-1.3.0/lib/fusuma.rb:50:in `print_version'
Jul 17 15:17:23 blade fusuma[16649]: from /nix/store/wmpvdlhvsw5bbfar933kz1l6gj86iq6g-ruby2.7.3-fusuma-1.3.0/lib/ruby/gems/2.7.0/gems/fusuma-1.3.0/lib/fusuma.rb:36:in `read_options'
Jul 17 15:17:23 blade fusuma[16649]: from /nix/store/wmpvdlhvsw5bbfar933kz1l6gj86iq6g-ruby2.7.3-fusuma-1.3.0/lib/ruby/gems/2.7.0/gems/fusuma-1.3.0/lib/fusuma.rb:16:in `run'
Jul 17 15:17:23 blade fusuma[16649]: from /nix/store/viq59dff95j7zzs6kxh6zx1mdbh1lkk1-fusuma-1.3.0/lib/ruby/gems/2.7.0/gems/fusuma-1.3.0/exe/fusuma:41:in `<top (required)>'
Jul 17 15:17:23 blade fusuma[16649]: from /nix/store/viq59dff95j7zzs6kxh6zx1mdbh1lkk1-fusuma-1.3.0/bin/.fusuma-wrapped:20:in `load'
Jul 17 15:17:23 blade fusuma[16649]: from /nix/store/viq59dff95j7zzs6kxh6zx1mdbh1lkk1-fusuma-1.3.0/bin/.fusuma-wrapped:20:in `<main>'
Jul 17 15:17:23 blade systemd[1591]: fusuma.service: Main process exited, code=exited, status=1/FAILURE
Jul 17 15:17:23 blade systemd[1591]: fusuma.service: Failed with result 'exit-code'.
For what it’s worth, to resolve that error you might need to add a package containing uname to the PATH variable for that unit; this seems suspicious though.
I don’t know enough about fusuma or how it’s packaged, this may just be a misconfigured home-manager.
@noib3 I am able to make it work like this. For me it has to be run by the root in order to get the input from touchpad. This is not optimize for home-manager’s format tho.
Thank you! Not sure how did I missed that. Just tried the input group, and now fusuma runs ok without sudo. However xdotool is still not working. Going to dig deeper into it later.
Hm I have switched the service from a system service to user service, which based on arch linux wiki should have injected DISPLAY and XAUTHORITY. Still xdotool is not working yet.
Do I need to make sure the service has these variables, or the shell used by fusuma, or both?