Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cronjob can't find daemon #164

Open
nxwbxdy opened this issue Aug 16, 2023 · 14 comments
Open

cronjob can't find daemon #164

nxwbxdy opened this issue Aug 16, 2023 · 14 comments

Comments

@nxwbxdy
Copy link

nxwbxdy commented Aug 16, 2023

I changed the example script that works when i execute it as the logged in user. It tells me the it can't find the socket file when I run it with cron. I also tried to set the XDG_RUNTIME_DIR=/run/user/$(id -u) but it didn't work. I am not an expert so I need a little help with this.

❯ cat ~/.scripts/swww/change-background
#!/bin/bash

if [[ $# -lt 1 ]] || [[ ! -d $1 ]]; then
    echo "$0 <dir>"
    exit 1
fi

swww img "$(find $1 -type f | shuf -n 1)" --transition-fps 60 --transition-step 90 --transition-type wipe --transition-angle 100 2>> ~/not_working.txt >> ~/not_working.txt
~
❯ sudo crontab -u luky -l
[sudo] password for luky:
* * * * * bash ~/.scripts/swww/change-background ~/Pictures/background
~
❯ cat ~/not_working.txt

Error: "Socket file not found. Are you sure swww-daemon is running?"
Error: "Socket file not found. Are you sure swww-daemon is running?"
Error: "Socket file not found. Are you sure swww-daemon is running?"
Error: "Socket file not found. Are you sure swww-daemon is running?"
Error: "Socket file not found. Are you sure swww-daemon is running?"
@J-C-Zeppeli-Gyro
Copy link

J-C-Zeppeli-Gyro commented Aug 22, 2023

I managed to work around the problem, because I had that error too.
In the hyprland.conf I set the script to change the bg to exec and every other I don't need to be executed every time to exec-once.
So I created another script that edits the hyprland.conf file, just adds 1row at the end then deletes that row.

home/$USER/.config/hypr/hyprland.conf
{
...
exec = /path/to/bg/changer/script
...
}

/path/to/hyprland.conf/editor
{
...
echo "Anything" >> home/$USER/.config/hypr/hyprland.conf
sed -i '$d' home/$USER/.config/hypr/hyprland.conf
...
}

crontab
{
...
* * * * * /path/to/hyprland.conf/editor
...
}

@nxwbxdy
Copy link
Author

nxwbxdy commented Sep 16, 2023

I made my own daemon for now the loop file basically calls the background changer and the loop file is called from the hyprland config with the delay. I hope this will be fixed one day with the daemon. https://github.com/moessler-bit/.scripts/tree/main/swww

@eccentricfae
Copy link

So for anyone wondering this is a problem not just with running "swww img ..." with cron but running it with elevated privileges (as root, w/ sudo etc). Hopefully this info will help people looking into the problem

@nxwbxdy
Copy link
Author

nxwbxdy commented Sep 19, 2023

I am currently learning rust and could try to find the problem once i am more familiar with the language

@eccentricfae
Copy link

So I found the issue (I think?)
In file: utils/src/ipc.rs, line 331
let runtime_dir = if let Ok(dir) = std::env::var("XDG_RUNTIME_DIR") {

The std::env::var("XDG_RUNTIME_DIR") returns an error (i.e. env var not found) when program is run with elevated privileges. What's funny is that when I run: echo $XDG_RUNTIME_DIR , sudo echo $XDG_RUNTIME_DIR and su then echo $XDG_RUNTIME_DIR I get the same output, so in my mind it means that XDG_RUNTIME_DIR is set and visiable for both user account and root account.

But when the rust program tries to read that variable (using std::env::var("XDG_RUNTIME_DIR")):

  • it works when program is run "normally" (without sudo / root privileges)
  • doesn't work when program is run with sudo / root privileges (as if the variable was not set?)

I verified this issue to be persistent across different Rust codebases, so the issue is with the std::env::var() instruction itself rather then swww codebase.

I will try to figure out if this can be fixed in some way but I'm quite new to Rust (like I started learning Rust few days ago lmao) so I encourage someone experienced with Rust to try and fix it

@nxwbxdy
Copy link
Author

nxwbxdy commented Sep 19, 2023

So that would mean that any rust program that uses the std::env crate doesn't work with sudo privileges

@nxwbxdy
Copy link
Author

nxwbxdy commented Sep 19, 2023

I think the author isn't using a normal daemon like systemd i think. I have to look into this i don't know too much yet

@eccentricfae
Copy link

eccentricfae commented Sep 19, 2023

So update:
it seems that when you run the program with sudo calling user's enviroment variables do not transfer (see the output of printenv and sudo printenv), which is kinda whack because when you enter root account (using su) and use the printenv command all the variables are still set, therefore I can only assume that cron runs the swww img command not "as root (as in using su to log in to a root account)" but "with sudo".
When you run swww img:

  • as user or with su then swww img works
  • with sudo (as either su or user) - it doesn't work

Bad news is that there's probably nothing that can be done to rectify it in this codebase, because this is not an issue with rust, but this is an issue with linux enviroment variables and / or cron daemon.
Good news: you can easily create such script that will rectify this issue at linux-enviroment level:

#!/bin/bash

export XDG_RUNTIME_DIR=/run/usr/1000 # Assuming this is also your $XDG_RUNTIME_DIR value
swww img /path/to/img

works on my machine when added as a script that is supposed to be run as a cron job and when run with sudo

@StitiFatah
Copy link

So update: it seems that when you run the program with sudo calling user's enviroment variables do not transfer (see the output of printenv and sudo printenv), which is kinda whack because when you enter root account (using su) and use the printenv command all the variables are still set, therefore I can only assume that cron runs the swww img command not "as root (as in using su to log in to a root account)" but "with sudo". When you run swww img:

  • as user or with su then swww img works
  • with sudo (as either su or user) - it doesn't work

Bad news is that there's probably nothing that can be done to rectify it in this codebase, because this is not an issue with rust, but this is an issue with linux enviroment variables and / or cron daemon. Good news: you can easily create such script that will rectify this issue at linux-enviroment level:

#!/bin/bash

export XDG_RUNTIME_DIR=/run/usr/1000 # Assuming this is also your $XDG_RUNTIME_DIR value
swww img /path/to/img

works on my machine when added as a script that is supposed to be run as a cron job and when run with sudo

Thanks it works on my machine too, had written a python script to pick random images from specified folders and it was driving me crazy

@nergdron
Copy link

nergdron commented Apr 17, 2024

as an update, I just ran into this, and had to add export WAYLAND_DISPLAY="wayland-1" to my script to get things to work, since perhaps per-wayland sockets was implemented after folks found the workaround initially. it might be nice to just have these variables default to those values in the swww codebase if the env vars aren't defined? wouldn't fix every use case, but would catch the most common one at least.

@DaniD3v
Copy link

DaniD3v commented Jun 7, 2024

Note that this behavior isn't even according to XDG spec.

image
(from the arch wiki)

I'd suggest adding a fallback to /run/user/UID. For getting the UID I'm not sure whether there's something in std but I know this library works. Would add quite a bit of unnecessary bloat tho.

@DaniD3v
Copy link

DaniD3v commented Jun 7, 2024

I just had a look at the current code for this

let runtime_dir = if let Ok(dir) = std::env::var("XDG_RUNTIME_DIR") {
        dir
    } else {
        "/tmp/swww".to_string()
    };

This is a terrible default. $XDG_RUNTIME_DIR is /run/user/UID in 99% of cases. We should also use that default. + /tmp is insecure. Wouldn't want other users randomly setting my wallpaper.

@LGFae
Copy link
Owner

LGFae commented Jun 7, 2024

@DaniD3v, well, sure. But that's not really what's causing this problem. That's just the daemon's socket location. The wayland socket location is what we need to find. Right now if we can't get it from XDG_RUNTIME_DIR we just give up. The code was simply copy-pasted from wayland.rs, so if it's a problem here, it's also a problem over there.

EDIT: actually, no. This is really a problem in the daemon, since for wayland you can just set WAYLAND_DIPLAY to an absolute path and you don't have to use XDG_RUNTIME_DIR.

I'd suggest adding a fallback to /run/user/UID. For getting the UID I'm not sure whether there's something in std but I know this library works. Would add quite a bit of unnecessary bloat tho.

We can just use rustix's getuid. We already depend on rustix anyway.

@LGFae
Copy link
Owner

LGFae commented Jun 8, 2024

@nergdron

I just ran into this, and had to add export WAYLAND_DISPLAY="wayland-1" to my script to get things to work, since perhaps per-wayland sockets was implemented after folks found the workaround initially. it might be nice to just have these variables default to those values in the swww codebase if the env vars aren't defined? wouldn't fix every use case, but would catch the most common one at least.

#327 implements this. But note that we default to wayland-0, not wayland-1. This is consistent with libwayland's behavior. Which means that, if you need to export WAYLAND_DISPLAY=wayland-1, ironically, this still won't fix your particular use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants