Difference between revisions of "Systemd/User"

From ArchWiki
Jump to: navigation, search
m (Using systemd --user To Manage Your Session: pam.d updates)
(Auto-login)
(19 intermediate revisions by 7 users not shown)
Line 3: Line 3:
 
[[Category:Boot process]]
 
[[Category:Boot process]]
 
[[es:Systemd/User]]
 
[[es:Systemd/User]]
 +
[[it:Systemd/User]]
 
{{Article summary start}}
 
{{Article summary start}}
 
{{Article summary text|Covers how to set up [[systemd]] user sessions.}}
 
{{Article summary text|Covers how to set up [[systemd]] user sessions.}}
Line 13: Line 14:
 
== Setup ==
 
== Setup ==
  
=== Using systemd --user To Manage Your Session ===
+
=== startx ===
  
Systemd has many amazing features, one of which is the ability to track programs using cgroups (by running {{ic|systemctl status}}). While awesome for a pid 1 process to do, it is also extremely useful for users, and having it set up and initialize user programs, all the while tracking what is in each cgroup is even more amazing.
+
{{Note|This step is unnecessary if you plan to use autologin.}}
  
I began using [http://blog.gtmanfred.com/?p=26 gtmanfred's guide] to set this up. I rewrote it partially to be of more help, and partially to help get this into my head even more.  
+
Users should first set up systemd-logind to manage their session. If [[systemd]] is running as the system init daemon, then this is already happening.
  
All of your systemd user units will go to $HOME/.config/systemd/user. These units take precedence over units in other systemd unit directories.
+
Next, the user must launch systemd by putting the following in their {{ic|~/.xinitrc}} '''before the exec line''': (This will only do anything if you start your DE/WM with {{ic|startx}} or {{ic|xinit}})
 +
{{bc|systemd --user &}}
  
There are two packages you need to get this working, both currently available from the AUR: {{AUR|xorg-launch-helper}} and {{AUR|user-session-units}}.
+
After starting X, the user can check whether their session is now being managed by systemd-logind with the following command:
  
Next is setting up your targets. I set up two, one for my window manager and another as a default target. The window manager target should be populated like so:
+
{{bc|<nowiki>
 +
$ loginctl --no-pager show-session $XDG_SESSION_ID | grep Active
 +
</nowiki>}}
  
[Unit]
+
If this command prints {{ic|1=Active=yes}}, then the user is now using systemd-logind to manage their session. The user should remove any instances of '''ck-launch-session''' or '''dbus-launch''' from their {{ic|~/.xinitrc}}, as those commands are unneeded.
Description=Window manager target
+
Wants=xorg.target
+
Wants=myStuff.target
+
Requires=dbus.socket
+
AllowIsolate=true
+
+
[Install]
+
Alias=default.target
+
  
This will be the target for your graphical interface.
+
=== Display Managers ===
 +
All of the major display managers are now using systemd-logind by default, so the {{ic|loginctl}} command from the previous section should work as stated. A user simply has to add {{ic|systemd --user}} as a program to be started by their desktop environment.
  
I put together a second target called mystuff.target. This will be 'WantedBy' all services but your window manager:
+
=== Using systemd --user To Manage Your Session ===
  
[Unit]
+
Systemd has many amazing features, one of which is the ability to track programs using cgroups (by running {{ic|systemctl status}}). While awesome for a '''pid 1''' process to do, it is also extremely useful for users, and having it set up and initialize user programs, all the while tracking what is in each cgroup is even more amazing.
Description=Xinitrc Stuff
+
Wants=i3wm.target
+
+
[Install]
+
Alias=default.target
+
  
Link this unit to default.target. When you start {{ic|systemd --user}}, it will start this target.  
+
All of your systemd user units will go to {{ic|$HOME/.config/systemd/user}}. These units take precedence over units in other systemd unit directories.
  
Next you need to begin writing services. First you should throw together a service for your window manager. I named mine i3.service:
+
There are two packages you need to get this working, both currently available from the [[AUR]]: {{AUR|xorg-launch-helper}} and optionally, {{AUR|user-session-units}} if you want to have autologin working.  
  
[Unit]
+
Next is setting up your targets. You should set up two, one for window manager and another as a default target. The window manager target should be populated like so:
Description=i3 window manager service
+
Before=mystuff.target
+
After=xorg.target
+
+
[Service]
+
Requires=xorg.target
+
Environment=PATH=/home/wgiokas/.cabal/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/wgiokas/bin
+
Environment=DISPLAY=:0
+
ExecStart=/usr/bin/i3
+
Restart=always
+
RestartSec=10
+
+
[Install]
+
WantedBy=wm.target
+
  
Note the [Install] section includes a 'WantedBy' part. When using {{ic|systemctl --user enable}} it will link this as $HOME/.config/systemd/user/i3wm.target.wants/i3.service, allowing it to be started at login. I would recommend enabling this service, not linking it manually.
+
{{hc|$HOME/.config/systemd/user/wm.target|<nowiki>
 +
[Unit]
 +
Description=Window manager target
 +
Wants=xorg.target
 +
Wants=myStuff.target
 +
Requires=dbus.socket
 +
AllowIsolate=true
  
You can fill your user unit directory with a plethora of services, I currently have ones for mpd, gpg-agent, offlineimap, parcellite, pulse, tmux, urxvtd, xbindkeys and xmodmap to name a few.
+
[Install]
 +
Alias=default.target
 +
</nowiki>}}
 +
This will be the target for your graphical interface.
  
If you want to have systemd automatically log you in on boot, then you can use the unit in user-session-units to do so. I would recommend enabling a screen locker for this so that someone booting your computer cannot just get your privelages.
+
Put together a second target called {{ic|mystuff.target}}. This will be 'WantedBy' all services but your window manager:
  
If you installed user-session-units as listed above, then you must copy user-session@.service to {{ic|/etc/systemd/system}} directory and edit the user-session@.service (not the user-session@yourloginname.service) and edit this line:
+
{{hc|$HOME/.config/systemd/user/mystuff.target|<nowiki>
 +
[Unit]
 +
Description=Xinitrc Stuff
 +
Wants=wm.target
  
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket
+
[Install]
 +
Alias=default.target
 +
</nowiki>}}
  
to this: (Note the subtle change where the {{ic|%I}} become {{ic|%U}})
+
Link this unit to {{ic|default.target}}. When you start {{ic|systemd --user}}, it will start this target.
  
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/dbus/user_bus_socket
+
Next you need to begin writing services. First you should throw together a service for your window manager:
  
As well as an install section:
+
{{hc|$HOME/.config/systemd/user/YOUR_WM.service|<nowiki>
 +
[Unit]
 +
Description=your window manager service
 +
Before=mystuff.target
 +
After=xorg.target
 +
Requires=xorg.target
  
  [Install]
+
[Service]
WantedBy=graphical.target
+
#Environment=PATH=uncomment:to:override:your:PATH
 +
ExecStart=/full/path/to/wm/executable
 +
Restart=always
 +
RestartSec=10
 +
   
 +
[Install]
 +
WantedBy=wm.target
 +
</nowiki>}}
  
You will need to patch systemd to do this, so either using systemd-git from after [http://cgit.freedesktop.org/systemd/systemd/commit/?id=067d851d30386c553e3a84f59d81d003ff638b91 commit 067d851d] or patch it into systemd with the [[ABS]]. After 197, it should be in the mainline systemd.
+
{{Note|The {{ic|[Install]}} section includes a 'WantedBy' part. When using {{ic|systemctl --user enable}} it will link this as {{ic|$HOME/.config/systemd/user/wm.target.wants/i3.service}}, allowing it to be started at login. Is recommended enabling this service, not linking it manually.}}
  
Add this line to /etc/pam.d/login or /etc/pam.d/system-auth:
+
You can fill your user unit directory with a plethora of services, including ones for '''mpd''', '''gpg-agent''', '''offlineimap''', '''parcellite''', '''pulse''', '''tmux''', '''urxvtd''', '''xbindkeys''' and '''xmodmap''' to name a few.
  
session    required    pam_systemd.so
+
===Auto-login===
  
Because user-session@.service starts on tty1, you will need to disable {{ic|getty@tty1.service}}.
+
If you want to have systemd automatically log you in on boot, then you can use the unit in user-session-units to do so. Enabling a screen locker for will stop someone from booting your computer into a nice, logged in session.  
  
One of the most important things you can add to the service files you will be writing is the use of Before= and After= in the [Unit] section. These two parts will determine the order things are started. Say you have a graphical application you want to start on boot, you would put `After=xorg.target' into your unit. Say you start ncmpcpp, which requires mpd to start, you can put `After=mpd.service' into your ncmpcpp unit. You will eventually figure out exactly how this needs to go either from experience or from reading the systemd manual pages. I would recommend starting with [http://www.freedesktop.org/software/systemd/man/systemd.unit.html systemd.unit(5)].
+
If you installed user-session-units as listed above, then you must copy {{ic|user-session@.service}} to {{ic|/etc/systemd/system}} directory and edit the {{ic|user-session@.service}} (not the {{ic|user-session@yourloginname.service}}) and edit this line:
  
Once all of this is up and running, you can type {{ic|systemctl --user status i3.service}} (or whatever your window manager or desktop environment is called) and see something like this:
+
{{bc|1=Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket}}
{{bc|<nowiki>
+
i3.service - i3wm
+
  Loaded: loaded (/home/wgiokas/.config/systemd/user/i3.service; enabled)
+
  Active: active (running) since Wed 2012-12-19 20:28:24 CST; 3h 8min ago
+
Main PID: 11115 (i3)
+
  CGroup: name=systemd:/user/wgiokas/3/systemd-11047/i3.service
+
  ├─11115 /usr/bin/i3
+
  ├─11127 i3bar --bar_id=bar-tyxnbu --socket=/run/user/1000/i3/ipc-socket.11115
+
  ├─11133 i3status -c /home/wgiokas/.i3/status.conf
+
  ├─27069 /bin/zsh
+
  ├─27088 luakit
+
  ├─29306 /bin/zsh
+
  └─29317 dwb
+
</nowiki>}}
+
  
{{Note|For future fun, remember that you can write {{ic|<unit>@.service}}s too, and in that service {{ic|%i}} will expand to the text between the {{ic|@}} and the {{ic|.service}} part, so if I wanted to have multiple instances of a window manager, for example on different displays, I could set the {{ic|<nowiki>DISPLAY=%i</nowiki>}} and enable {{ic|i3@:0.service}} or even {{ic|i3@123.123.123.123:5.service}} if that tickled my fancy.}}
+
to this:  
  
=== startx ===
+
{{bc|1=Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/dbus/user_bus_socket}}
  
Users should first set up systemd-logind to manage their session. If [[systemd]] is running as the system init daemon, then this is already happening.
+
{{Note|Notice the subtle change where the {{ic|%I}} become {{ic|%U}})}}
 +
As well as an install section:
  
Next, the user must launch systemd by putting the following in their {{ic|~/.xinitrc}} '''before the exec line''':
+
{{bc|1=
systemd --user &
+
[Install]
 +
WantedBy=graphical.target
 +
}}
  
After starting X, the user can check whether their session is now being managed by systemd-logind with the following command:
+
or if you have no login manager:
$ loginctl --no-pager show-session $XDG_SESSION_ID | grep Active
+
If this command prints {{ic|<nowiki>Active=yes</nowiki>}}, then the user is now using systemd-logind to manage their session. The user should remove any instances of '''ck-launch-session''' or '''dbus-launch''' from their {{ic|~/.xinitrc}}, as those commands are unneeded.
+
  
=== Display Managers ===
+
{{bc|1=
All of the major display managers are now using systemd-logind by default, so the {{ic|loginctl}} command from the previous section should work as stated. A user simply has to add {{ic|systemd --user}} as a program to be started by their desktop environment.
+
[Install]
 +
WantedBy=getty.target
 +
}}
 +
 
 +
You will need to patch systemd to do this, so either using '''systemd-git''' from after [http://cgit.freedesktop.org/systemd/systemd/commit/?id=067d851d30386c553e3a84f59d81d003ff638b91 commit 067d851d] or patch it into systemd with the [[ABS]]. After 197, it should be in the mainline systemd.
 +
 
 +
Add this line to {{ic|/etc/pam.d/login}} and {{ic|/etc/pam.d/system-auth}}:
 +
 
 +
{{bc|session    required    pam_systemd.so}}
 +
 
 +
Because {{ic|user-session@.service}} starts on tty1, you will need to add {{ic|1=Conflicts=getty@tty1.service}} to the service file.
 +
 
 +
One of the most important things you can add to the service files you will be writing is the use of {{ic|1=Before=}} and {{ic|1=After=}} in the {{ic|[Unit]}} section. These two parts will determine the order things are started. Say you have a graphical application you want to start on boot, you would put {{ic|1=After=xorg.target}} into your unit. Say you start '''ncmpcpp''', which requires '''mpd''' to start, you can put {{ic|1=After=mpd.service}} into your ncmpcpp unit. You will eventually figure out exactly how this needs to go either from experience or from reading the systemd manual pages. Starting with [http://www.freedesktop.org/software/systemd/man/systemd.unit.html systemd.unit(5)] is a good idea.
  
 
== User Services ==
 
== User Services ==
Line 136: Line 139:
 
A unit installed by a package that is meant to be run by a [[systemd]] user instance should install the unit to {{ic|/usr/lib/systemd/user/}}. The system adminstration can then modify the unit by copying it to {{ic|/etc/systemd/user/}}. A user can then modify the unit by copying it to {{ic|~/.config/systemd/user/}}.
 
A unit installed by a package that is meant to be run by a [[systemd]] user instance should install the unit to {{ic|/usr/lib/systemd/user/}}. The system adminstration can then modify the unit by copying it to {{ic|/etc/systemd/user/}}. A user can then modify the unit by copying it to {{ic|~/.config/systemd/user/}}.
 
=== Example ===
 
=== Example ===
The following is an example of a user version of {{ic|mpd.service}}:
+
The following is an example of a user version of the mpd service.
[Unit]
+
{{hc|mpd.service|<nowiki>
Description=Music Player Daemon
+
[Unit]
+
Description=Music Player Daemon
[Service]
+
ExecStart=/usr/bin/mpd --no-daemon
+
+
[Install]
+
WantedBy=default.target
+
  
 +
[Service]
 +
ExecStart=/usr/bin/mpd --no-daemon
 +
 +
[Install]
 +
WantedBy=default.target
 +
</nowiki>}}
 
=== Example with variables ===
 
=== Example with variables ===
 
The following is an example of a user version of {{ic|sickbeard.service}}, which takes into account variable home directories where SickBeard can find certain files:
 
The following is an example of a user version of {{ic|sickbeard.service}}, which takes into account variable home directories where SickBeard can find certain files:
[Unit]
+
{{hc|sickbeard.service|<nowiki>
Description=SickBeard Daemon
+
[Unit]
+
Description=SickBeard Daemon
[Service]
+
 
ExecStart=/usr/bin/env python2 /opt/sickbeard/SickBeard.py --config %h/.sickbeard/config.ini --datadir %h/.sickbeard
+
[Service]
+
ExecStart=/usr/bin/env python2 /opt/sickbeard/SickBeard.py --config %h/.sickbeard/config.ini --datadir %h/.sickbeard
[Install]
+
 
WantedBy=default.target
+
[Install]
 +
WantedBy=default.target
 +
</nowiki>}}
  
 
As detailed in {{ic|man systemd.unit}}, the {{ic|%h}} variable is replaced by the home directory of the user running the service. There are other variables that can be taken into account in the [[systemd]] manpages.
 
As detailed in {{ic|man systemd.unit}}, the {{ic|%h}} variable is replaced by the home directory of the user running the service. There are other variables that can be taken into account in the [[systemd]] manpages.
  
== External links ==
+
== See also ==
 +
* [http://blog.gtmanfred.com/?p=26 gtmanfred's guide - the original guide]
 +
* [https://bitbucket.org/KaiSforza/systemd-user-units/wiki/Home KaiSforza's bitbucket wiki]
 
* [https://github.com/grawity/systemd-user-units Collection of useful systemd user units]
 
* [https://github.com/grawity/systemd-user-units Collection of useful systemd user units]
* [https://github.com/KaiSforza/systemd-user-units More systemd user units]
+
* [https://bitbucket.org/KaiSforza/systemd-user-units More systemd user units]

Revision as of 17:00, 30 January 2013

Summary help replacing me
Covers how to set up systemd user sessions.
Related
systemd

systemd offers users the ability to run an instance of systemd to manage their session and services. This allows users to start, stop, enable, and disable units found within certain directories when systemd is run by the user. This is convenient for daemons and other services that are commonly run as a user other than root or a special user, such as mpd.

Setup

startx

Note: This step is unnecessary if you plan to use autologin.

Users should first set up systemd-logind to manage their session. If systemd is running as the system init daemon, then this is already happening.

Next, the user must launch systemd by putting the following in their ~/.xinitrc before the exec line: (This will only do anything if you start your DE/WM with startx or xinit)

systemd --user &

After starting X, the user can check whether their session is now being managed by systemd-logind with the following command:

$ loginctl --no-pager show-session $XDG_SESSION_ID | grep Active

If this command prints Active=yes, then the user is now using systemd-logind to manage their session. The user should remove any instances of ck-launch-session or dbus-launch from their ~/.xinitrc, as those commands are unneeded.

Display Managers

All of the major display managers are now using systemd-logind by default, so the loginctl command from the previous section should work as stated. A user simply has to add systemd --user as a program to be started by their desktop environment.

Using systemd --user To Manage Your Session

Systemd has many amazing features, one of which is the ability to track programs using cgroups (by running systemctl status). While awesome for a pid 1 process to do, it is also extremely useful for users, and having it set up and initialize user programs, all the while tracking what is in each cgroup is even more amazing.

All of your systemd user units will go to $HOME/.config/systemd/user. These units take precedence over units in other systemd unit directories.

There are two packages you need to get this working, both currently available from the AUR: xorg-launch-helperAUR and optionally, user-session-unitsAUR if you want to have autologin working.

Next is setting up your targets. You should set up two, one for window manager and another as a default target. The window manager target should be populated like so:

$HOME/.config/systemd/user/wm.target
[Unit]
Description=Window manager target
Wants=xorg.target
Wants=myStuff.target
Requires=dbus.socket
AllowIsolate=true

[Install]
Alias=default.target

This will be the target for your graphical interface.

Put together a second target called mystuff.target. This will be 'WantedBy' all services but your window manager:

$HOME/.config/systemd/user/mystuff.target
[Unit]
Description=Xinitrc Stuff
Wants=wm.target

[Install]
Alias=default.target

Link this unit to default.target. When you start systemd --user, it will start this target.

Next you need to begin writing services. First you should throw together a service for your window manager:

$HOME/.config/systemd/user/YOUR_WM.service
[Unit]
Description=your window manager service
Before=mystuff.target
After=xorg.target
Requires=xorg.target

[Service]
#Environment=PATH=uncomment:to:override:your:PATH
ExecStart=/full/path/to/wm/executable
Restart=always
RestartSec=10
 
[Install]
WantedBy=wm.target
Note: The [Install] section includes a 'WantedBy' part. When using systemctl --user enable it will link this as $HOME/.config/systemd/user/wm.target.wants/i3.service, allowing it to be started at login. Is recommended enabling this service, not linking it manually.

You can fill your user unit directory with a plethora of services, including ones for mpd, gpg-agent, offlineimap, parcellite, pulse, tmux, urxvtd, xbindkeys and xmodmap to name a few.

Auto-login

If you want to have systemd automatically log you in on boot, then you can use the unit in user-session-units to do so. Enabling a screen locker for will stop someone from booting your computer into a nice, logged in session.

If you installed user-session-units as listed above, then you must copy user-session@.service to /etc/systemd/system directory and edit the user-session@.service (not the user-session@yourloginname.service) and edit this line:

Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket

to this:

Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/dbus/user_bus_socket
Note: Notice the subtle change where the %I become %U)

As well as an install section:

[Install]
WantedBy=graphical.target

or if you have no login manager:

[Install]
WantedBy=getty.target

You will need to patch systemd to do this, so either using systemd-git from after commit 067d851d or patch it into systemd with the ABS. After 197, it should be in the mainline systemd.

Add this line to /etc/pam.d/login and /etc/pam.d/system-auth:

session    required    pam_systemd.so

Because user-session@.service starts on tty1, you will need to add Conflicts=getty@tty1.service to the service file.

One of the most important things you can add to the service files you will be writing is the use of Before= and After= in the [Unit] section. These two parts will determine the order things are started. Say you have a graphical application you want to start on boot, you would put After=xorg.target into your unit. Say you start ncmpcpp, which requires mpd to start, you can put After=mpd.service into your ncmpcpp unit. You will eventually figure out exactly how this needs to go either from experience or from reading the systemd manual pages. Starting with systemd.unit(5) is a good idea.

User Services

Users may now interact with units located in the following directories just as they would with system services (ordered by ascending precedence):

  • /usr/lib/systemd/user/
  • /etc/systemd/user/
  • ~/.config/systemd/user/

To control the systemd instance, the user must use the command systemctl --user.

Installed by packages

A unit installed by a package that is meant to be run by a systemd user instance should install the unit to /usr/lib/systemd/user/. The system adminstration can then modify the unit by copying it to /etc/systemd/user/. A user can then modify the unit by copying it to ~/.config/systemd/user/.

Example

The following is an example of a user version of the mpd service.

mpd.service
[Unit]
Description=Music Player Daemon

[Service]
ExecStart=/usr/bin/mpd --no-daemon

[Install]
WantedBy=default.target

Example with variables

The following is an example of a user version of sickbeard.service, which takes into account variable home directories where SickBeard can find certain files:

sickbeard.service
[Unit]
Description=SickBeard Daemon

[Service]
ExecStart=/usr/bin/env python2 /opt/sickbeard/SickBeard.py --config %h/.sickbeard/config.ini --datadir %h/.sickbeard

[Install]
WantedBy=default.target

As detailed in man systemd.unit, the %h variable is replaced by the home directory of the user running the service. There are other variables that can be taken into account in the systemd manpages.

See also