home-manager icon indicating copy to clipboard operation
home-manager copied to clipboard

bug: swayidle command not generating correctly

Open muni-corn opened this issue 3 years ago • 11 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Issue description

Based on the source code for escapeShellArg and the swayidle module, I'm expecting my timeout commands to be wrapped in single quotes.

However, the module is producing this instead:

/nix/store/6slnlma1imvpk2ih91xp54n7hpgff0qa-swayidle-1.7.1/bin/swayidle -w timeout 570 notify-send -u low -t 29500 -- 'Are you still there?' 'Your system will lock itself soon.' timeout 600 $HOME/.config/sway/scripts/lock.fish --bg-color 002b36 --fg-color 93a1a1 --primary-color 2aa198 --warning-color ffaa00 --error-color ff0000 timeout 630 swaymsg 'output * dpms off' resume swaymsg 'output * dpms on' before-sleep $HOME/.config/sway/scripts/lock.fish --bg-color 002b36 --fg-color 93a1a1 --primary-color 2aa198 --warning-color ffaa00 --error-color ff0000

which gives me this error in the systemd unit, systemctl --user status swayidle.service:

Feb 22 13:38:49 ponytower systemd[3002]: Started Idle manager for Wayland.
Feb 22 13:38:49 ponytower swayidle[64891]: 2022-02-22 13:38:49 - [Line 880] Unsupported command '630'
Feb 22 13:38:49 ponytower systemd[3002]: swayidle.service: Main process exited, code=exited, status=255/EXCEPTION
Feb 22 13:38:49 ponytower systemd[3002]: swayidle.service: Failed with result 'exit-code'.

Link to swayidle commands in my config

Maintainer CC

@c0deaddict

System information

- system: `"x86_64-linux"`
 - host os: `Linux 5.10.101, NixOS, 22.05 (Quokka)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.7.0pre20220127_558c4ee`
 - channels(root): `"nixos-22.05pre353535.48d63e924a2"`
 - channels(harrison): `"home-manager, nixos-21.11pre301985.23cd13167a1"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

muni-corn avatar Feb 22 '22 20:02 muni-corn

Very strange that the escapeShellArg is not working. I've been using this module for over a year now, and the escaping still works on my machine. Could it be that the escapeShellArg function is somehow overriden in your config?

Tested your command, and the single quotes get correctly escaped on my machine:

# systemctl --user cat swayidle.service
[Service]
ExecStart=/nix/store/6slnlma1imvpk2ih91xp54n7hpgff0qa-swayidle-1.7.1/bin/swayidle -w timeout 170 '/nix/store/fh1fck4mwizic96v620xqj20yv2p40z6-libnotify-0.7.9/bin/notify-send -u low -t 29500 -- '\''Are you still there?'\'' '\''Your system will lock itself soon.'\''' timeout 180 '/nix/store/hmwqmhsjs7zmn33nx53hxgqmfqs8hqxc-swaylock-1.5/bin/swaylock -f -F -c 000000' timeout 300 '/nix/store/hb5g19sidg4zrq091m1jz6kcfiz1h75h-sway-1.7/bin/swaymsg "output * dpms off"' resume '/nix/store/hb5g19sidg4zrq091m1jz6kcfiz1h75h-sway-1.7/bin/swaymsg "output * dpms on"' before-sleep '/nix/store/hmwqmhsjs7zmn33nx53hxgqmfqs8hqxc-swaylock-1.5/bin/swaylock -f -F -c 000000' lock '/nix/store/hmwqmhsjs7zmn33nx53hxgqmfqs8hqxc-swaylock-1.5/bin/swaylock -f -F -c 000000'

c0deaddict avatar Mar 13 '22 20:03 c0deaddict

Perhaps you can verify that escapeShellArg is correctly working with nix repl:

❯ nix repl '<nixpkgs>'                                                                                                                              [21:29:44]
Welcome to Nix 2.6.1. Type :? for help.

Loading '<nixpkgs>'...
Added 16014 variables.

nix-repl> lib.escapeShellArg "'hello'"
"''\\''hello'\\'''"

c0deaddict avatar Mar 13 '22 20:03 c0deaddict

Perhaps you can verify that escapeShellArg is correctly working with nix repl:

❯ nix repl '<nixpkgs>'
Welcome to Nix 2.7.0pre20220127_558c4ee. Type :? for help.

Loading '<nixpkgs>'...
Added 15465 variables.

nix-repl> lib.escapeShellArg "'hello'"
"''\\''hello'\\'''"

Seems to work as expected :) I will check my swayidle config again :thinking:

muni-corn avatar Mar 15 '22 00:03 muni-corn

Okay so this is strange. systemctl --user cat swayidle.service gives the expected command:

# /home/harrison/.config/systemd/user/swayidle.service
[Install]
WantedBy=sway-session.target

[Service]
ExecStart=/nix/store/6slnlma1imvpk2ih91xp54n7hpgff0qa-swayidle-1.7.1/bin/swayidle -w timeout 570 'notify-send -u low -t 29500 -- '\''Are you still there?'\'' '\''Your system will lock itself soon.'\''' timeout 600 '$HOME/.config/sway/scripts/lock.fish --bg-color 002b36 --fg-color 93a1a1 --primary-color 2aa198 --warning-color ffaa00 --error-color ff0000' timeout 630 'swaymsg '\''output * dpms off'\''' resume 'swaymsg '\''output * dpms on'\''' before-sleep '$HOME/.config/sway/scripts/lock.fish --bg-color 002b36 --fg-color 93a1a1 --primary-color 2aa198 --warning-color ffaa00 --error-color ff0000'
Type=simple

[Unit]
Description=Idle manager for Wayland
Documentation=man:swayidle(1)
PartOf=graphical-session.target

But systemctl --user status swayidle.service shows that swayidle has failed because it's executing without the single quotes:

× swayidle.service - Idle manager for Wayland
     Loaded: loaded (/home/harrison/.config/systemd/user/swayidle.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Mon 2022-03-14 21:54:28 CDT; 45s ago
       Docs: man:swayidle(1)
    Process: 3253739 ExecStart=/nix/store/6slnlma1imvpk2ih91xp54n7hpgff0qa-swayidle-1.7.1/bin/swayidle -w timeout 570 notify-send -u low -t 29500 -- 'Are you still there?' 'Your system will lock itself soon.' timeout 600 $HOME/.config/sway/scripts/lock.fish --bg-color 002b36 --fg-color 93a1a1 --primary-color 2aa198 --warning-color ffaa00 --error-color ff0000 timeout 630 swaymsg 'output * dpms off' resume swaymsg 'output * dpms on' before-sleep $HOME/.config/sway/scripts/lock.fish --bg-color 002b36 --fg-color 93a1a1 --primary-color 2aa198 --warning-color ffaa00 --error-color ff0000 (code=exited, status=255/EXCEPTION)
   Main PID: 3253739 (code=exited, status=255/EXCEPTION)
        CPU: 2ms

Mar 14 21:54:28 ponytower systemd[5734]: Started Idle manager for Wayland.
Mar 14 21:54:28 ponytower swayidle[3253739]: 2022-03-14 21:54:28 - [Line 880] Unsupported command '630'
Mar 14 21:54:28 ponytower systemd[5734]: swayidle.service: Main process exited, code=exited, status=255/EXCEPTION
Mar 14 21:54:28 ponytower systemd[5734]: swayidle.service: Failed with result 'exit-code'.

muni-corn avatar Mar 15 '22 03:03 muni-corn

If systemd does not parse the command string correctly, the ExecStart could point to a shell script (e.g. pkgs.writeShellScript)

berbiche avatar Mar 20 '22 20:03 berbiche

Something changed recently and now I'm struggling with this service, running the ExecStart in a terminal works great, running it through the service results in execve failed!: No such file or directory. I'm passing a writeShellScriptBin generated file to command. Can this be related?

EDIT: Sorry, seems like it was not. Doing it like this didn't fix it:

{
  systemd.user.services.swayidle.Service.ExecStart =
    let
      script =
        pkgs.writeShellScript "swayidle-usage" ''
          ${pkgs.swayidle}/bin/swayidle -w timeout 60 ${lock} before-sleep ${lock}
        '';
    in
    lib.mkForce (toString script);
}

EDIT2: In case it happens to anyone else, executing it in sway still works as expected:

{
  wayland.windowManager.sway.config.startup = [ { command = "${pkgs.swayidle}/bin/swayidle -w timeout 60 ${lock} before-sleep ${lock}"; } ];
}

EDIT3: Better than this, check https://github.com/nix-community/home-manager/issues/2752#issuecomment-1141325511

PedroHLC avatar May 30 '22 12:05 PedroHLC

@PedroHLC Your issue is not related to this ticket, the $PATH environment variable in systemd services only contains systemd's binaries, this is why you see these execve errors. swayidle tries to run the executables you have specified and the execve syscall looks up in $PATH if the executable is not a fully qualified path (it does not start with /). Make sure to use fully qualified paths for executables you run in your configuration i.e. ${pkgs.swayidle}/bin/swayidle -w timeout 60 ${pkgs.swaylock}/bin/swaylock ....

berbiche avatar May 30 '22 15:05 berbiche

@PedroHLC Your issue is not related to this ticket, the $PATH environment variable in systemd services only contains systemd's binaries, this is why you see these execve errors. swayidle tries to run the executables you have specified and the execve syscall looks up in $PATH if the executable is not a fully qualified path (it does not start with /). Make sure to use fully qualified paths for executables you run in your configuration i.e. ${pkgs.swayidle}/bin/swayidle -w timeout 60 ${pkgs.swaylock}/bin/swaylock ....

They already are absolute paths to the binaries, but indeed not related to this issue.

PedroHLC avatar May 30 '22 16:05 PedroHLC

@PedroHLC sorry, I forgot the issue was that swayidle runs executables with sh -c and sh is not in the $PATH. See my comment here https://github.com/nix-community/home-manager/pull/2849#discussion_r846411403 for a possible fix. https://github.com/swaywm/swayidle/blob/e81d40fca7533f73319e76e42fa9694b21cc9e6e/main.c#L157-L158

berbiche avatar May 30 '22 16:05 berbiche

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

  • If this is resolved, please consider closing it so that the maintainers know not to focus on this.
  • If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
If you are not the original author of the issue

  • If you are also experiencing this issue, please add details of your situation to help with the debugging process.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
Memorandum on closing issues

Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

stale[bot] avatar Aug 31 '22 01:08 stale[bot]

fwiw i think i worked around this issue by removing the -- in my lockWarningCmd

muni-corn avatar Aug 31 '22 13:08 muni-corn