Динамічні змінні у файлах системного сервісного блоку


14

Чи є спосіб динамічно призначити змінні середовища у файлі системного блоку обслуговування?

У нас є машина, яка має 4 GPU, і ми хочемо розкручувати кілька примірників певної послуги на один графічний процесор. Наприклад:

  • gpu_service @ 1: 1.service
  • gpu_service @ 2: 1. сервіс
  • gpu_service @ 3: 1.service
  • gpu_service @ 4: 1.service
  • gpu_service @ 1: 2.service
  • gpu_service @ 2: 2.service
  • gpu_service @ 3: 2.service
  • gpu_service @ 4: 2.service
  • реклама нудота

Отже, 1: 1, 2: 1, і т.д., є фактично% i у файлі сервісного блоку.

Для того, щоб служба прив’язана до певного GPU, виконуваний сервіс перевіряє певну змінну середовища, наприклад:

USE_GPU=4

Чи є спосіб я взяти% i у файл сервісного блоку і запустити його через якусь функцію (оболонку), щоб отримати номер GPU, і тоді я можу встановити змінну середовища USE_GPU відповідно?

Найголовніше, що я не хочу /etc/systemd/system/gpu_service@x:y.service/local.confклопотання писати декілька файлів, просто я можу створити більше екземплярів.

Відповіді:


10

Якщо ви обережні, ви можете включити невелику послідовність скриптів bash як свою команду exec у службовий файл екземпляра. Напр

ExecStart=/bin/bash -c 'v=%i; USE_GPU=$${v%:*} exec /bin/mycommand'

Рядок $$в рядку стане одиничним $у результаті, переданому bash, але важливіше, що він не перестане ${...}інтерполюватися системою. (Раніші версії systemd не документували використання $$, тому я не знаю, чи підтримувався він тоді).


Я в кінцевому підсумку робив щось подібне. :)
Кал

1
Зателефонувати a, bash -cщоб запустити програму з одиничного файлу? Дзвінок exec? Це подібно до використання навантажувача навантажувача (можливо, з іншим навантажувачем на вершині), оскільки перший навантажувач має проблеми з фактичним навантажувачем.
Девід Тонхофер

На жаль, ви не можете використовувати ExecStartPre для написання env-файлу, а потім використовувати його, мабуть, він повинен бути записаний заздалегідь, щоб щось подібне спрацювало. Або сценарій обгортки, щоб зробити розбиття :) Іншим химерним варіантом було б створити ще один сервіс для налаштування env. файл, не впевнений , як це буде працювати з шаблонами Тхо: stackoverflow.com/a/42841480/32453
rogerdpack

8

Не побудовано в дорозі. Вам потрібно зробити це перед тим, як розпочнеться служба. Одним із способів було б розміщення його у файлі середовища.

[Service]
# Note you need to escape percentage sign
ExecStartPre=/bin/sh -c "my_awesome_parser %%i > /run/gpu_service_%i"
EnvironmentFile=/run/gpu_service_%i
ExecStart=...

3

Схоже, ви дійсно можете встановити змінні середовища всередині файлу системного блоку ...

За пропозиціями коментаторів, ось таке рішення:

Використання змінних середовища в системних одиницях

Екологічна директива

systemd має директиву Environment, яка встановлює змінні середовища для виконуваних процесів. Він займає розділений пробілом список змінних призначень. Ця опція може бути задана не раз, і в цьому випадку будуть встановлені всі перелічені змінні. Якщо одну і ту ж змінну встановлено двічі, пізніша установка буде замінено більш ранній. Якщо порожній рядок призначений цій опції, список змінних оточуючих середовищ скидається, всі попередні призначення не впливають. Директиви щодо оточення використовуються у вбудованих системних підрозділах Container Linux, наприклад, у etcd2 та flannel.

Наведеному нижче прикладі ви можете налаштувати демона etcd2 на використання шифрування. Просто створіть /etc/systemd/system/etcd2.service.d/30-certificates.confвибудову для etcd2.service:

[Service]
# Client Env Vars
Environment=ETCD_CA_FILE=/path/to/CA.pem
Environment=ETCD_CERT_FILE=/path/to/server.crt
Environment=ETCD_KEY_FILE=/path/to/server.key
# Peer Env Vars
Environment=ETCD_PEER_CA_FILE=/path/to/CA.pem
Environment=ETCD_PEER_CERT_FILE=/path/to/peers.crt
Environment=ETCD_PEER_KEY_FILE=/path/to/peers.key

Потім запустіть sudo systemctl daemon-reloadі sudo systemctl restart etcd2.serviceзастосуйте нові середовища до демона etcd2.

Цитований текст, взятий із такої URL-адреси: https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html


2
Хоча це теоретично може відповісти на питання, бажано було б сюди включити істотні частини відповіді та надати посилання для довідки.
Стівен Рауч

1
Хоча ваш коментар теоретично може покращити мої майбутні відповіді в обміні ставок, бажано, щоб ви включили в свій коментар основні частини відповіді, а не просто коментуючи, щоб вказати, наскільки хтось може бути некомпетентним :)
CyberK

1
Ласкаво просимо на обмін стеками! Дякую за коментар, ти змусив мене посміхнутися. Також дякуємо, що знайшли час для редагування своєї відповіді. Ми намагаємось створити щось, що матиме значення з часом, і відповіді лише на посилання просто не старіють.
Стівен Рауч

Якщо ви додасте, Environment=ABC=%iвін встановлює env. змінна "до сукупності% i". Я здогадуюсь, ви могли б зробити обгортку, щоб зняти "речі, які не надходять цитаті", які ви не хочете, і це називає справжній виконуваний файл. Але якщо ви робите обгортку, ви навіть можете просто передати її %iяк аргумент колишнього:ExecStart=my_wrapper %i
rogerdpack

Питання стосувалося "динамічних" змінних; ти просто дав нам відповідь на статичне рішення.
Отей

0

Це некрасиво і не зовсім те, про що ви просили, і не дозволяє автозапустити, але для послідовників можна зробити щось, використовуючи середовище systemctl :

$ sudo systemctl set-environment USE_GPU=4 # add it to the env. variables for future services
$ sudo systemctl start gpu_service@4:2.service

Просто намагаюся перерахувати всі можливі способи :)

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