2

I'm currently using a systemd unit file to configure a service which uses X server display.

The X server instance is launched by the user logged in (currently pi user) but the service is launched at root.

I can successfully launch the service using systemctl start test_graphic_app if I hard code the .Xauthority file location into XAUTHORITY variable from the unit file as follow

[Unit]
Description=Test Graphic App
After=multi-user.target

[Service]
Type=simple

User=root
Group=root

Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/pi/.Xauthority"

ExecStart=/usr/bin/python3 /usr/sbin/test_graphic_app.py

KillSignal=SIGINT
SuccessExitStatus=SIGINT

StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=test_graphic_app

Restart=on-failure

[Install]
WantedBy=default.target

However this obviously doesn't work if I log using another user or if I run it locally on my laptop cause the user launching X is not pi

I would like to dynamically get the .Xauthority file location on the system.


I've tried using sudo xauth info | grep Authority | awk '{print $3}' as follow

Environment="XAUTHORITY=$(/usr/bin/xauth info | grep Authority | awk '{print $3}')"

ExecStartPre=/bin/bash -c 'export XAUTHORITY=${XAUTHORITY}'

However if the command works on my laptop, it doesn't on the pi

## On laptop ##
$ sudo xauth info | grep "Authority file" | awk '{print $3}'
/run/user/1000/gdm/Xauthority

## On pi ##
$ sudo xauth info | grep "Authority file" | awk '{print $3}'
xauth:  file /root/.Xauthority does not exist
/root/.Xauthority

I was unable find how to get the .Xauthority file location depending on the user that have launched the X server instance. Also, I don't want to allow any user to use X display doing xhost +

How can I get the location within my systemd unit?

Is there any better solution other than finding the .Xauthority location?

  • The easy solution is not to launch your service at boot, but launch it when this particular user logs in. Or use a display manager, which will launch the X server, and launch the service once the X server is up. Trying to start your service before there is any X server it can connect is broken, no matter how many workarounds you try. If the service does anything important which you need at boot, split it into a non-graphical and a graphical part. – dirkt Sep 17 '18 at 6:28
  • I'm using autolog on the raspberry pi and default.target is set to graphical runlevel, so the service start after X has been launched. – Arkaik Sep 18 '18 at 8:06
2

There are more sophisticated versions of xhost +, namely xhost +si:localuser:root which adds only local user root to the list of allowed connections.

You need to find where to put this command so it is run on login, depending on your distribution. Look in /etc/X11/ for an existing file using xhost already. On my pi I found it in /etc/X11/Xsession.d/35x11-common_xhost-local:

if type xhost >/dev/null 2>&1; then
  xhost +si:localuser:$(id -un) || :
fi

On another system it was in /etc/X11/xinit/xinitrc.d/localuser.sh.

  • Do you know a way to do it permanently so I just have to run it at install ? – Arkaik Sep 16 '18 at 16:24
  • I'm not sure what you mean. Just create a shell script file with a name like 35-add-root-xhost in the appropriate directory, with the new extra xhost command in it, and make sure it is executable. It will be run at each login. – meuh Sep 16 '18 at 17:58
  • My issue is that I will deploy the app on several linux systems using an install script so I'm looking for a way to allow root to connect X (with xhost +si:localuser:root for example) but permanently with one command ran at install. The script would be nice if the location were always the same on the system. – Arkaik Sep 16 '18 at 20:15
0

Add this to your install script:

sudo mkdir /opt/xauthorityfix
sudo chmod 777 /opt/xauthorityfix
echo "#!/bin/sh" > /opt/xauthorityfix/setxauthority.sh
echo "export XAUTHORITY=$XAUTHORITY" >> /opt/xauthorityfix/setxauthority.sh
sudo chmod 755 /opt/xauthorityfix

After that, wrap your python script in this shell script:

#!/bin/sh

source /opt/xauthorityfix/setxauthority.sh
/usr/bin/python3 /usr/sbin/test_graphic_app.py

And just have your systemd service start that script instead!

Just make sure that the XAUTHORITY environment variable is set when your install script is run. You can do that by not running it with sudo, or by using sudo -E.

Basically, this stores the XAUTHORITY environment variable as it is when the install script is run, allowing you to easily refer to it later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.