Como parar uma unidade enquanto outra unidade é executada

3

No momento, estou tentando configurar backups automatizados usando o borg . Para isso, escrevi um serviço ao usuário systemd (chamado borgbackup.service) que estou planejando iniciar por um temporizador.

O Borg também pode montar um repositório de backup como um sistema de arquivos virtual e eu gostaria de manter meus backups montados o tempo todo. Eu escrevi outro serviço de usuário para o que eu chamei borgmount.service. No entanto, é impossível criar backups enquanto o repositório está montado.

Minha solução atual para este problema consiste nestas linhas no meu borgbackup.service para parar e reiniciar o serviço de montagem antes e depois do backup.

ExecStartPre=/usr/bin/systemctl --user stop borgmount.service
ExitStart=/bin/sh -c "borg create ::$(date) --exclude-caches --keep-tag-files"
ExecStopPost=/usr/bin/systemctl --user start borgmount.service

Isso parece muito feio e não leva em conta o estado em que a unidade borgmount.service estava quando o backup foi iniciado (talvez tenha sido interrompido e desativado).

Existe uma maneira melhor de fazer isso?

    
por Niautanor 14.01.2017 / 14:47

1 resposta

1

Não é uma solução perfeita, mas em vez de ExecStartPre você pode usar Conflicts .

Conflitos =

A space-separated list of unit names. Configures negative requirement dependencies. If a unit has a Conflicts= setting on another unit, starting the former will stop the latter and vice versa. Note that this setting is independent of and orthogonal to the After= and Before= ordering dependencies.

Você pode combinar isso com um ExecStopPost que verifica se o conflito está ativado:

ExecStopPost=/usr/bin/systemctl is-enabled borgmount.service && /usr/bin/systemctl --user start borgmount.service

Se você não estiver familiarizado com o operador && , se o primeiro comando for bem-sucedido, o segundo será executado. systemctl is-enabled retorna 0 quando a unidade está ativada.

Ainda não abrange o caso de uso em que o serviço foi ativado e interrompido, mas você provavelmente ainda poderia manipular um ExecStopPost mais complexo ou até mesmo determinar o estado em ExecStartPre . É muito ruim systemd não ter uma diretiva Interupts ou similar, para parar outra unidade apenas enquanto a unidade estiver funcionando.

Em vez de um ExecStartPost , você também pode especificar Conflicts= em borgmount.service e, em vez de executar apenas systemctl start borgbackup.service , pode executar systemctl start borgbackup.service borgmount.service , mas isso exige que você lembre de executar ambos.

Outra alternativa (provavelmente a mais limpa) seria usar o Conflicts em ambos os serviços e criar um novo alvo para backup que inclua ambos os serviços.

borgbackup.service precisaria:

Before=borgmount.service para garantir que seja executado primeiro

WantedBy=${NEW_TARGET} para garantir que a execução do novo destino faça com que seja executado.

borgmount.service precisaria:

WantedBy=${NEW_TARGET} , você pode especificar várias diretivas WantedBy em uma unidade.

Depois, você pode acionar seu backup usando systemctl start ${NEW_TARGET} .

O bom desse método é que, se borgmount.service não estiver ativado, ele não será executado no ${NEW_TARGET} e, se você quiser acionar o backup sem executar borgmount.service , poderá chamar o borgbackup.service em seu próprio.

    
por 03.05.2017 / 19:51