Плутати записи ExecStartPre в файлі системного блоку


23

У мене є система systemd, для якої потрібно створити каталог /run, але в іншому випадку запускатись як користувач, що не має root. З прикладу блогу я отримав таке рішення:

[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

Магія - у 3 рядках, які слідують за коментарем. Мабуть, ExecStartPre's буде запускатися як root таким чином, але ExecStartзапуск буде виконуватися як зазначений користувач.

Це призвело до 3 питань, хоча:

  1. Що -робити перед /bin/mkdir? Я не знаю, чому це там чи що він робить.
  2. Коли ExecStartPreв одиничному файлі є декілька, вони просто виконуються послідовно в тому порядку, який вони знаходять у файлі одиниці? Або якийсь інший метод?
  3. Це насправді найкраща техніка для досягнення моєї мети - створити каталог запуску, щоб користувач, що не має root, міг ним користуватися?

Причиною того, що він ExecStartPreпрацює як root, є PermissionsStartOnly=trueдиректива. Він обмежує Userдирективу лише ExecStartкомандою. Дивіться freedesktop.org/software/systemd/man/systemd.service.html
cayhorstmann

Відповіді:


30

З будь-якими питаннями щодо системних директив ви можете скористатися man systemd.directivesдля пошуку довідкової сторінки, яка документує директиву. У випадку з цим ExecStartPre=ви знайдете це документально man systemd.service.

Там, в документах для ExecStartPre=, ви побачите, що пояснено, що провідний "-" використовується для того, щоб відзначити, що відмова допускається для цих команд. У цьому випадку це допускається, якщо воно /run/thingвже існує.

Документи також пояснюють, що "дозволено кілька командних рядків, і команди виконуються одна за одною, послідовно".

Одне вдосконалення вашого методу попереднього створення каталогу - це не зробити його доступним для запису у світі, коли вам потрібно лише його записати певним користувачем. Більш обмежені дозволи будуть виконані:

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

Це робить каталог, який належить певному користувачеві та повністю доступний йому.


Дивовижна відповідь, дякую за натяк на systemd.directives, мені завжди важко зрозуміти systemd, куди йти. Це допомагає.
Тревіс Гріггс

1
Ви, мабуть, повинні покривати RuntimeDirectoryі RuntimeDirectoryModeтеж.
JdeBP

2

Відповідь на номер 3:

Перегляньте RuntimeDirectory=& RuntimeDirectoryMode=директиви. Повні документи тут . Але підсумовуючи (незначна зміна тексту, але суть повинна залишитися):

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.

Отже, щоб скористатися цим, це повинно зробити трюк:

[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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.