Skip to content

Make reproiner to maintain persistent GUI session for reproiner user #141

Open
@yarikoptic

Description

@yarikoptic

For

Ideally, there should be a solution (configuration) for desktop manager to start a dedicated Xorg to that external HDMI display which would be used for calibratrion, without any ability to control it from local periphery (keyboard etc). Meanwhile we should just make reproiner login into reprostim account upon boot, so that :0 DISPLAY becomes available for the user to present on whenever display is attached. And otherwise to be able to run X0 screen grab vnc so we could attach remotely to observe/diagnose.

Questions/possible show stopper:

  • would it work ok without any monitor attached to start with?
according to claude following measures could be taken to disable external keyboard/mouse to prevent intrusion/interference Yes, there are several approaches to lock out external input devices while allowing GDM to start. Here are the most effective methods:

Using udev rules (Recommended)

Create a udev rule to automatically disable USB input devices:

# /etc/udev/rules.d/99-disable-usb-input.rules
SUBSYSTEM=="input", ATTRS{idVendor}=="*", ATTRS{idProduct}=="*", ATTRS{bInterfaceClass}=="03", ATTRS{bInterfaceSubClass}=="01", RUN+="/bin/sh -c 'echo remove > /sys%p/uevent'"

# For USB HID devices specifically
SUBSYSTEM=="usb", ATTR{bDeviceClass}=="03", ATTR{bDeviceSubClass}=="01", RUN+="/usr/bin/rmmod usbhid"

Reload udev rules:

sudo udevadm control --reload-rules
sudo udevadm trigger

X11 InputClass configuration

Create an X11 configuration to ignore USB input devices:

# /etc/X11/xorg.conf.d/99-disable-usb-input.conf
Section "InputClass"
    Identifier "Disable USB keyboards"
    MatchIsKeyboard "on" 
    MatchUSBID "*:*"
    Option "Ignore" "true"
EndSection

Section "InputClass"
    Identifier "Disable USB mice"
    MatchIsPointer "on"
    MatchUSBID "*:*" 
    Option "Ignore" "true"
EndSection

Kernel module approach

Blacklist USB HID modules entirely:

# /etc/modprobe.d/blacklist-usb-input.conf
blacklist usbhid
blacklist hid_generic
blacklist hid_apple
# Add other HID drivers as needed

Update initramfs:

sudo update-initramfs -u

Runtime control script

For dynamic control, you can create a script that removes USB input devices:

#!/bin/bash
# disable-usb-input.sh

# Remove USB keyboards
for kbd in /sys/bus/usb/drivers/usbhid/*/input/input*/event*; do
    if [ -e "$kbd" ]; then
        device=$(basename "$kbd")
        echo "Removing USB keyboard: $device"
        echo "$device" > /sys/class/input/$device/uevent
    fi
done

# Alternatively, unbind all USB HID devices
for device in /sys/bus/usb/drivers/usbhid/*; do
    if [ -L "$device" ]; then
        echo $(basename "$device") > /sys/bus/usb/drivers/usbhid/unbind
    fi
done

Systemd service for automation

Create a systemd service to run before GDM:

# /etc/systemd/system/disable-usb-input.service
[Unit]
Description=Disable USB Input Devices
Before=gdm.service
DefaultDependencies=false

[Service]
Type=oneshot
ExecStart=/usr/local/bin/disable-usb-input.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Important considerations

  • Built-in keyboards/touchpads: These methods may also affect laptop built-in devices if they appear as USB devices internally
  • Recovery access: Ensure you have alternative access (SSH, console, etc.) before implementing
  • Selective blocking: You might want to whitelist specific vendor/product IDs for trusted devices
  • Testing: Test thoroughly in a VM or non-production environment first

The udev rules approach is generally most reliable as it works at the kernel level before devices are exposed to userspace applications.

claude instructions on starting service so it has access to Xorg

Yes, there are several ways to autostart systemd services for a user with access to their XOrg session. Here are the main approaches:

User systemd services (Recommended)

Create a user service file:

# ~/.config/systemd/user/my-service.service
[Unit]
Description=My X11 Application
After=graphical-session.target
Wants=graphical-session.target

[Service]
Type=simple
ExecStart=/path/to/your/application
Environment=DISPLAY=:0
# Inherit user's environment
Environment=XDG_RUNTIME_DIR=%i
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

Enable and start:

systemctl --user enable my-service.service
systemctl --user start my-service.service

Using graphical-session.target

For services that specifically need the graphical session:

# ~/.config/systemd/user/x11-app.service
[Unit]
Description=X11 Application
After=graphical-session.target
BindsTo=graphical-session.target

[Service]
Type=simple
ExecStart=/usr/bin/your-x11-app
Environment=DISPLAY=:0
Environment=XAUTHORITY=%h/.Xauthority

[Install]
WantedBy=graphical-session.target

Enable lingering for the user

To ensure user services start even when the user isn't logged in:

sudo loginctl enable-linger username

Using XDG autostart (Alternative)

Create a desktop entry that systemd can manage:

# ~/.config/autostart/my-app.desktop
[Desktop Entry]
Type=Application
Name=My Application
Exec=systemctl --user start my-service.service
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true

Environment variables for X11 access

Common environment variables your service might need:

[Service]
Environment=DISPLAY=:0
Environment=XAUTHORITY=%h/.Xauthority
Environment=XDG_RUNTIME_DIR=/run/user/%i
Environment=WAYLAND_DISPLAY=wayland-0
# For DBus session access
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%i/bus

System service with user context

If you need a system service but want it to run as a specific user:

# /etc/systemd/system/user-x11-service.service
[Unit]
Description=X11 Service for User
After=graphical.target
Wants=graphical.target

[Service]
Type=simple
User=username
Group=username
ExecStart=/path/to/application
Environment=DISPLAY=:0
Environment=HOME=/home/username
Environment=XDG_RUNTIME_DIR=/run/user/1000
WorkingDirectory=/home/username

[Install]
WantedBy=graphical.target

For GDM specifically

If you want the service to start with GDM login:

# ~/.config/systemd/user/gdm-session.service
[Unit]
Description=Application for GDM Session
After=gdm-session.target
BindsTo=gdm-session.target

[Service]
Type=simple
ExecStart=/usr/bin/your-application
Environment=DISPLAY=:0

[Install]
WantedBy=gdm-session.target

Debugging tips

Check if your user service is running:

systemctl --user status my-service.service
systemctl --user list-units --type=service

Check environment variables available to the service:

systemctl --user show-environment

The user systemd approach is most appropriate for Debian systems as it properly integrates with the session management and provides the cleanest separation of concerns.

Also see

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions