Bingung dengan entri ExecStartPre dalam file unit systemd


23

Saya memiliki layanan systemd yang perlu membuat direktori /run, tetapi jika tidak dijalankan sebagai pengguna non-root. Dari contoh blog, saya mendapatkan solusi berikut:

[Unit]
Description=Startup Thing

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 -u /opt/thing/doStartup
WorkingDirectory=/opt/thing
StandardOutput=journal
User=thingUser
# Make sure the /run/thing directory exists
PermissionsStartOnly=true
ExecStartPre=-/bin/mkdir -p /run/thing
ExecStartPre=/bin/chmod -R 777 /run/thing

[Install]
WantedBy=multi-user.target

Keajaiban ada di 3 baris yang mengikuti komentar. Tampaknya ini ExecStartPreakan berjalan sebagai root dengan cara ini, tetapi ExecStartakan berjalan sebagai pengguna yang ditentukan.

Ini menimbulkan 3 pertanyaan:

  1. Apa yang -dilakukan di depan /bin/mkdir? Saya tidak tahu mengapa itu ada di sana atau apa fungsinya.
  2. Ketika ada banyak ExecStartPre's di file unit, apakah mereka hanya berjalan secara seri dalam urutan bahwa mereka ditemukan dalam file unit? Atau metode lain?
  3. Apakah ini sebenarnya teknik terbaik untuk mencapai tujuan saya untuk membuat direktori jalankan dibuat sehingga pengguna non-root dapat menggunakannya?

Alasan bahwa ExecStartPrejalan sebagai root adalah PermissionsStartOnly=truearahan. Ini membatasi Userarahan hanya untuk ExecStartperintah. Lihat freedesktop.org/software/systemd/man/systemd.service.html
cayhorstmann

Jawaban:


30

Untuk pertanyaan tentang arahan systemd, Anda dapat menggunakan man systemd.directivesuntuk mencari halaman manual yang mendokumentasikan arahan. Dalam hal ini ExecStartPre=, Anda akan mendokumentasikannya man systemd.service.

Di sana dalam dokumen untuk ExecStartPre=, Anda akan menemukannya menjelaskan bahwa "-" utama digunakan untuk mencatat bahwa kegagalan dapat ditoleransi untuk perintah-perintah ini. Dalam hal ini, itu ditoleransi jika /run/thingsudah ada.

Dokumen di sana juga menjelaskan bahwa "beberapa baris perintah diizinkan dan perintah dijalankan satu demi satu, secara seri."

Salah satu peningkatan pada metode pra-pembuatan direktori Anda adalah tidak membuatnya bisa ditulis oleh dunia saat Anda hanya perlu ditulis oleh pengguna tertentu. Izin yang lebih terbatas akan diselesaikan dengan:

 ExecStartPre=-/bin/chown thingUser /run/thing
 ExecStartPre=-/bin/chmod 700       /run/thing

Itu membuat direktori dimiliki dan sepenuhnya dapat diakses dari pengguna tertentu.


Jawaban yang luar biasa, terima kasih atas petunjuk systemd.directives, saya selalu menemukan systemd sulit untuk mengetahui ke mana harus pergi. Itu membantu.
Travis Griggs

1
Anda mungkin harus mencakup RuntimeDirectorydan RuntimeDirectoryModejuga.
JdeBP

2

Jawaban untuk # 3:

Lihat petunjuk RuntimeDirectory=& RuntimeDirectoryMode=. Dokumentasi lengkap di sini . Namun secara ringkas (sedikit modifikasi pada teks, tetapi esensi tetap ada):

RuntimeDirectory=

       This option take a whitespace-separated list of directory names. The 
       specified directory names must be relative, and may not include "..". If
       set, one or more directories by the specified names will be created
       (including their parents) below /run (for system services) or below 
       $XDG_RUNTIME_DIR (for user services) when the unit is started. Also, the  
       $RUNTIME_DIRECTORY environment variable is defined with the full path of 
       directories. If multiple directories are set, then in the environment 
       variable the paths are concatenated with colon (":").

       The innermost subdirectories are removed when the unit is stopped. It is 
       possible to preserve the specified directories in this case if 
       RuntimeDirectoryPreserve= is configured to restart or yes. The innermost 
       specified directories will be owned by the user and group specified in 
       User= and Group=.

       If the specified directories already exist and their owning user or group 
       do not match the configured ones, all files and directories below the 
       specified directories as well as the directories themselves will have their 
       file ownership recursively changed to match what is configured. As an 
       optimization, if the specified directories are already owned by the right 
       user and group, files and directories below of them are left as-is, even if 
       they do not match what is requested. The innermost specified directories 
       will have their access mode adjusted to the what is specified in 
       RuntimeDirectoryMode=.

       Use RuntimeDirectory= to manage one or more runtime directories for the 
       unit and bind their lifetime to the daemon runtime. This is particularly 
       useful for unprivileged daemons that cannot create runtime directories in 
       /run due to lack of privileges, and to make sure the runtime directory is 
       cleaned up automatically after use. For runtime directories that require 
       more complex or different configuration or lifetime guarantees, please 
       consider using tmpfiles.d(5).


RuntimeDirectoryMode=

       Specifies the access mode of the directories specified in 
       RuntimeDirectory= as an octal number. Defaults to 0755. See "Permissions" 
       in path_resolution(7) for a discussion of the meaning of permission bits.

Jadi untuk meningkatkan itu, ini harus melakukan trik:

[Unit]
Description=Startup Thing

[Service]
Type=oneshot
ExecStart=/usr/bin/python3 -u /opt/thing/doStartup
WorkingDirectory=/opt/thing
StandardOutput=journal
User=thingUser
# Make sure the /run/thing directory exists
PermissionsStartOnly=true
RuntimeDirectory=thing
RuntimeDirectoryMode=0777

[Install]
WantedBy=multi-user.target
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.