I am trying to run a Plasma session as a different user from bash by running sudo -u $TARGET_USER dbus-launch --exit-with-session startplasma-wayland.

However, when trying to do so, I get an error “Could not create wayland socket”.

My goal is to start a Plasma session as a specified user, wait for the user to log out and continue running the script.

  • Does anyone know how I might be able to fix this error?
  • Do you know of another way to start a Plasma session as a different user and wait for the session to exit?

I also tried to do the same using the sudo --preserve-env --set-home XDG_RUNTIME_DIR=/run/users/$(id -u $TARGET_USER) switches.

When doing so, I get the following messages repeatedly:

No backend specified, automatically choosing drm
kwin_core: Failed to take control of /org/freedesktop/login1/session/_311 session. Maybe another compositor is running?
kwin_wayland_drm: Failed to open drm device at "/dev/dri/card1"
kwin_wayland_drm: No suitable DRM devices have been found

However, logging in to the tty with the $TARGET_USER directly and running dbus-launch --exit-with-session startplasma-wayland works properly as expected.

  • Strit
    link
    fedilink
    22 months ago

    Why not just log in as the user in TTY and then start it?

    I’n not sure I understand the use-case of why it needs a Plasma session to start a script that needs to keep running afterwards. If the script itself does not need a plasma session, then you can just start it as a user service with systemd.

  • @manuthOP
    link
    1
    edit-2
    2 months ago

    Alright, so I found an absolute trainwreck of a solution. All the ways I have tested (sudo, login, openvt, machinectl, systemd-run) don’t work because important variables like XDG_SESSION_ID are not created. So probably these methods don’t open up a real session or something…?

    What I did is to automatically open up a session for the specified user - in this case using getty. Using these code lines, I created a systemd-configuration and booted it up by running systemctl daemon-reload:

    {
        printf %s\n \
            "[Service]" \
            "ExecStart=" \
            "ExecStart=-/sbin/agetty -o '-p -f -- \\u' --noclear --autologin $TARGET_USER %I \$TERM"
    } | sudo tee "/etc/systemd/system/getty@tty2.service.d/autologin.conf"
    
    sudo systemctl daemon-reload
    sudo systemctl restart getty@tty2
    

    source: https://wiki.archlinux.org/title/Getty

    After this, the user has a running session and proper environment variables set up. I use pgrep to wait for the expected process to show up:

    sessionPid=""
    
    while [ -z "$sessionPid" ]; do
        sessionPid=$(sudo pgrep -t tty2 -u "$TARGET_USER")
    done
    

    The environment variables of the process with the PID $sessionPid can then be borrowed to run startplasma-wayland properly as the desired user:

    sudo -u "$TARGET_USER" \
        env \
            $(sudo -u "$TARGET_USER" fish -c "cat /proc/$sessionPid/environ | string split0)") \
            /usr/lib/plasma-dbus-run-session-if-needed startplasma-wayland
    

    The fact, that this command would always end up focussing on tty2 after exiting the plasma session, I kind of abused the openvt-command to force the focus to return to the previous tty:

    openvt -sw -- \
        sudo -u "$TARGET_USER" \
            env \
                $(sudo -u "$TARGET_USER" fish -c "cat /proc/$sessionPid/environ | string split0)") \
                /usr/lib/plasma-dbus-run-session-if-needed startplasma-wayland
    

    I also did some quirks like using openvt to find an unused tty. If you want to see the whole thing in action - script is here:

    https://git.nuth.ch/manuth/PortValhalla/src/commit/b6329693d6fd717c8ca6f7a278a864930b7f705d/scripts/Common/Software/rclone/main.fish#L10-L60