Variáveis dinâmicas em arquivos da unidade de serviço systemd

7

Existe uma maneira de atribuir dinamicamente variáveis de ambiente em um arquivo de unidade de serviço systemd?

Temos uma máquina com 4 GPUs e queremos ativar várias instâncias de um determinado serviço por GPU. Por exemplo:

  • gpu_service @ 1: 1.serviço
  • gpu_service @ 2: 1.serviço
  • gpu_service @ 3: 1.serviço
  • gpu_service @ 4: 1.serviço
  • gpu_service @ 1: 2.serviço
  • gpu_service @ 2: 2.serviço
  • gpu_service @ 3: 2.serviço
  • gpu_service @ 4: 2.serviço
  • ad nauseam

Assim, o 1: 1, 2: 1, etc. são efetivamente% i no arquivo da unidade de serviço.

Para que o serviço se vincule a uma GPU específica, o executável do serviço verifica uma determinada variável de ambiente, por exemplo:

USE_GPU=4

Existe uma maneira que eu posso pegar o% i dentro do arquivo da unidade de serviço e executá-lo através de alguma função (shell) para derivar o número da GPU, e então eu posso definir a variável de ambiente USE_GPU de acordo?

O mais importante é que não quero o incômodo de escrever vários arquivos /etc/systemd/system/gpu_service@x:y.service/local.conf para poder criar mais instâncias.

    
por Kal 17.11.2016 / 08:01

3 respostas

5

Se você for cuidadoso, pode incorporar uma pequena sequência de script bash como seu comando exec no arquivo de serviço da instância. Por exemplo

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

O $$ na string se tornará um único $ no resultado passado para o bash, mas o mais importante será parar o ${...} de ser interpolado pelo systemd. (As versões anteriores do systemd não documentavam o uso de $$ , portanto, não sei se ele era suportado).

    
por 17.11.2016 / 16:32
4

Parece que você pode definir variáveis de ambiente dentro de um arquivo de unidade do systemd ...

Por sugestão dos comentadores, aqui está a solução:

Using environment variables in systemd units

Environment directive

systemd has an Environment directive which sets environment variables for executed processes. It takes a space-separated list of variable assignments. This option may be specified more than once in which case all listed variables will be set. If the same variable is set twice, the later setting will override the earlier setting. If the empty string is assigned to this option, the list of environment variables is reset, all prior assignments have no effect. Environments directives are used in built-in Container Linux systemd units, for example in etcd2 and flannel.

With the example below, you can configure your etcd2 daemon to use encryption. Just create /etc/systemd/system/etcd2.service.d/30-certificates.conf drop-in for 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

Then run sudo systemctl daemon-reload and sudo systemctl restart etcd2.service to apply new environments to etcd2 daemon.

Texto citado retirado do seguinte URL: link

    
por 23.02.2017 / 06:06
2

Não construído de maneira. Você precisa fazer essas coisas antes do início do seu serviço. Uma maneira seria colocá-lo em um arquivo de ambiente.

[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=...
    
por 17.11.2016 / 14:35