xdbob / sway-services

Collection of systemd unit files and tools to run sway and tools inside systemd user services
MIT License
100 stars 20 forks source link

/etc/profile sourced twice when run from shell #13

Open carloabelli opened 4 years ago

carloabelli commented 4 years ago

When executing sway-user-service from a shell, /etc/profile has already been sourced and does not need to be sourced again. Although this has limited impact on functionality, it does cause annoyances such as duplicate entries in $PATH.

xdbob commented 4 years ago

I thought sway-user-service would always be launched by a login manager (maybe it should be somewhere outside the $PATH or I could take extra steps to support the use case).

Anyway, running sway from your console should be as simple as systemctl --user start sway

carloabelli commented 4 years ago

Ah that makes more sense though the usage statement in the readme is confusing.

Interestingly the reason I looked it up was because starting with systemctl --user start sway was failing and running sway-user-service worked (aside from the double sourcing). I haven’t had time yet to figure out the exact error, but something in the script must be necessary.

xdbob commented 4 years ago

I may have some bugs letting the (systemd's) environment polluted. If you reproduce the failure of systemctl --user start sway, it would be helpful if you dumped me (right after):

carloabelli commented 4 years ago

Here is the output after systemctl --user start sway.service fails. sway-user-service works fine.

$ systemctl --user --failed
  UNIT         LOAD   ACTIVE SUB    DESCRIPTION                              
● mako.service loaded failed failed A lightweight Wayland notification daemon
● sway.service loaded failed failed sway - SirCmpwn's Wayland window manager 

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

2 loaded units listed.
$ systemctl --user status sway.service
● sway.service - sway - SirCmpwn's Wayland window manager
     Loaded: loaded (/usr/lib/systemd/user/sway.service; static; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2020-05-27 14:11:43 EDT; 27s ago
       Docs: man:sway(5)
    Process: 1815 ExecStart=/usr/bin/sway (code=exited, status=1/FAILURE)
    Process: 1817 ExecStopPost=/usr/bin/systemctl --user unset-environment SWAYSOCK DISPLAY I3SOCK WAYLAND_DISPLAY (code=exited, status=0/SUCCESS)
   Main PID: 1815 (code=exited, status=1/FAILURE)

May 27 14:11:43 softmatrix systemd[1781]: sway.service: Scheduled restart job, restart counter is at 5.
May 27 14:11:43 softmatrix systemd[1781]: Stopped sway - SirCmpwn's Wayland window manager.
May 27 14:11:43 softmatrix systemd[1781]: sway.service: Start request repeated too quickly.
May 27 14:11:43 softmatrix systemd[1781]: sway.service: Failed with result 'exit-code'.
May 27 14:11:43 softmatrix systemd[1781]: Failed to start sway - SirCmpwn's Wayland window manager.
$ systemctl --user show-environment
HOME=/home/carloabelli
LANG=en_US.UTF-8
LOGNAME=carloabelli
MAIL=/var/spool/mail/carloabelli
PATH=/usr/local/bin:/usr/bin
SHELL=/bin/zsh
USER=carloabelli
XDG_RUNTIME_DIR=/run/user/1000
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus

Looks like sway is failing for some reason, I'll post the sway debugging output shortly.

carloabelli commented 4 years ago

Here is the sway debug output when starting with systemctl --user start sway.service:

May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] Linux softmatrix 5.6.14.a-1-hardened #1 SMP PREEMPT Fri, 22 May 2020 10:55:09 +0000 x86_64 GNU/Linux
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:168] Contents of /etc/os-release:
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] NAME="Arch Linux"
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] PRETTY_NAME="Arch Linux"
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] ID=arch
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] BUILD_ID=rolling
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] ANSI_COLOR="38;2;23;147;209"
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] HOME_URL="https://www.archlinux.org/"
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] DOCUMENTATION_URL="https://wiki.archlinux.org/"
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] SUPPORT_URL="https://bbs.archlinux.org/"
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] BUG_REPORT_URL="https://bugs.archlinux.org/"
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:152] LOGO=archlinux
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:140] LD_LIBRARY_PATH=(null)
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:140] LD_PRELOAD=(null)
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:140] PATH=/home/carloabelli/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/carloabelli/.gem/ruby/2.7.0/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/main.c:140] SWAYSOCK=(null)
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/server.c:40] Preparing Wayland server initialization
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [backend/session/logind.c:712] Session '3' isn't a graphical session (type: 'tty')
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [backend/session/direct-ipc.c:35] Do not have CAP_SYS_ADMIN; cannot become DRM master
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [backend/session/session.c:96] Failed to load session backend
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [backend/backend.c:286] Failed to start a DRM session
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [backend/noop/backend.c:51] Creating noop backend
May 27 14:20:22 softmatrix sway[3001]: 2020-05-27 14:20:22 - [sway/server.c:47] Unable to create backend
May 27 14:20:22 softmatrix systemd[1781]: sway.service: Main process exited, code=exited, status=1/FAILURE
carloabelli commented 4 years ago

Running systemctl --user import-environment before systemctl --user start sway.service works. So perhaps this should be clarified in the readme for how to run not using a display manager.

xdbob commented 4 years ago

Sorry, I did'nt took the time to look into it lately. But yeah it's environment related. I'm trying to figure out witch variable is needed and why.

I now think it's XDG_SESSION_ID so you can try with systemctl --user import-environment XDG_SESSION_ID instead of importing the whole environment.

I'm also thinking about how to best handle the environment variables (and yeah I will need to provide a script at least to do the cleanup).

markstos commented 3 years ago

In sway-user-service one option could be to add a check for one the environment variable that's only set by a display manager. Some are listed here:

https://unix.stackexchange.com/questions/536810/why-are-the-xdg-variables-for-my-account-undefined-when-i-login-through-ssh

If the script is being run by a display manager, source /etc/profile. If not, don't.

Another solution is to not source /etc/profile at all. /etc/profile is a "bashism" that is not read by other shells like Fish. More discussion is here:

https://github.com/fish-shell/fish-shell/issues/3665

More modern alternatives for setting global environment variables include /etc/environment and /etc/environment.d (man environment.d). However, if you do ls /etc/profile.d/, you may find some apps you care about are still setting some evironment variables using the bash-specific /etc/profile approach.

tinywrkb commented 2 years ago

IMO considering Sway is running as a systemd service, sourcing /etc/profile is going the wrong way.

Here's my soluion:

/usr/lib/systemd/user-environment-generators/10-os

#!/bin/sh

# PATH
PATH=/usr/bin
[ -d /usr/bin/site_perl ] && PATH+=:/usr/bin/site_perl
[ -d /usr/bin/vendor_perl ] && PATH+=:/usr/bin/vendor_perl
[ -d /usr/bin/core_perl ] && PATH+=:/usr/bin/core_perl
PATH+=:"$HOME"/.local/bin

# XDG dirs
XDG_CACHE_HOME="$HOME/.cache"
XDG_CONFIG_HOME="$HOME/.config"
XDG_DATA_HOME="$HOME/.local/share"

echo "XDG_CACHE_HOME=$XDG_CACHE_HOME"
echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME"
echo "XDG_DATA_HOME=$XDG_DATA_HOME"

# Flatpak
FLATPAK_USER_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/flatpak"
FLATPAK_SYSTEM_DIR="${FLATPAK_SYSTEM_DIR:-/var/lib/flatpak}"
FLATPAK_SYSTEM_CACHE_DIR=${FLATPAK_SYSTEM_DIR}/tmp

PATH+=":${FLATPAK_USER_DIR}/exports/bin"
PATH+=":${FLATPAK_SYSTEM_DIR}/exports/bin"

echo "FLATPAK_USER_DIR=$FLATPAK_USER_DIR"
echo "FLATPAK_SYSTEM_DIR=$FLATPAK_SYSTEM_DIR"
echo "FLATPAK_SYSTEM_CACHE_DIR=$FLATPAK_SYSTEM_CACHE_DIR"

# print PATH, this should stay at the end of the generator
echo "PATH=$PATH"

bash.functions

if [ -z "$OS_BASH_FUNCTIONS" ]; then
  export OS_BASH_FUNCTIONS=1

  source_executable_output(){
set -a
source /dev/fd/0 <<EOF
$($1)
EOF
set +a
  }
  export -f source_executable_output

  import_systemd_environment(){
    local env_gens=()
    local env_gen_dirs=()

    # directories order according to systemd.generator.7 man page
    for d in /{run,etc,usr/lib}/systemd/user-environment-generators; do
      [ -d $d ] && env_gen_dirs+=($d)
    done

    # find all environment generators, only keep file name
    for f in $(find ${env_gen_dirs[@]} -perm -0005 -type f); do
      env_gens+=($(basename $f))
    done

    # sort and remove duplicates
    IFS=$'\n' env_gens=($(sort -u <<<${env_gens[*]}))
    unset IFS

    for env_gen in ${env_gens[@]}; do
      for d in ${env_gen_dirs[@]}; do
        if [ -f ${d}/${env_gen} ]; then
          source_executable_output ${d}/${env_gen}
          break
        fi
      done
    done
  }
  export -f import_systemd_environment
fi

bashrc.patch

--- a/etc/bash.bashrc
+++ b/etc/bash.bashrc
@@ -20,3 +20,14 @@
 esac

 [ -r /usr/share/bash-completion/bash_completion   ] && . /usr/share/bash-completion/bash_completion
+
+# load bash functions
+[ -r /etc/bash.functions ] && . /etc/bash.functions
+
+if [ -z "$IMPORTED_SYSTEMD_ENV" ]; then
+  export IMPORTED_SYSTEMD_ENV=1
+  import_systemd_environment
+fi
+
+# load bash_profile from xdg config dir
+[ -r ~/.config/bash/bashrc ] && . ~/.config/bash/bashrc

And add any other environment variable that you need via environment.d or with an environment generator.

tinywrkb commented 2 years ago

Oh! And also ~/.config/bash/bashrc

...

################################################################################
##############################    Extra PATHs     ##############################
################################################################################

if [ -z "$BASH_EXTRA_PATHS" ]; then
  export BASH_EXTRA_PATHS=1

  extra_paths=("$HOME/.local/share/flatpak-run-cli/exports/bin"
               "$HOME/.local/pyvenv/default/bin"
               "$HOME/.local/poetry/bin")

  for extra_path in ${extra_paths[@]}; do
    if [[ ":$PATH:" != *":$extra_path:"* ]]; then
      PATH+=":$extra_path"
    fi
  done

  export PATH
fi