Digamos que eu queira que um programa esteja ativo entre 12:00h e 13:00h em uma máquina desktop (ou seja, se o PC estiver ligado em qualquer horário não pode ser garantido). Vou assumir que posso usar unidades systemd para isso.
Iniciar o serviço A
com um temporizador e contabilizar os tempos de desligamento é simples:
A.temporizador
[Timer]
Unit=A
OnCalendar=*-*-* 12:00:00
Persistent=true
A interrupção A
pode ser feita com um serviço conflitante, conforme sugerido anteriormente
A.service (com conflito):
#add conflict to A.service
[Unit]
Description=This is A.service
Conflicts=killA.service
#make sure killA considers A to be active
RemainAfterExit=yes
killA.service :
[Unit]
Description=kills A
[Service]
Type=oneshot
ExecStart=/bin/true
#kill only if A is running:
Requires=A.service
killA.timer
[Timer]
Unit=killA
OnCalendar=*-*-* 13:00:00
Persistent=true
Agora existem vários cenários possíveis:
- Ligado das 11h às 14h: inicie e pare conforme o esperado
Ligado das 11h às 12h30: inicia como esperado, mas nunca para -> o que acontecerá na próxima ligação?
- às 12:45: A vai começar? (último início há menos de 24h)
- às 14h: killA não deve ser executado, pois A não deve estar ativo
- às 12:15 do dia seguinte? (última partida há menos de 24 horas, mas a partida killA foi perdida)
- às 12:45 do dia seguinte? (última partida >24h atrás, mas killA <24h atrás. Será interrompido por killA?)
Ligado das 12h30 às 14h: iniciar e parar conforme o esperado (devido à persistência no A.timer)
ligado às 14h: A inicia por persistência. O killA irá desativá-lo imediatamente devido à dependência? Começar A pode ser evitado em primeiro lugar?
Resumidamente:
Como usar timers systemd para garantir que um serviço esteja ativo em um determinado intervalo de tempo e inativo fora do intervalo de tempo, independentemente de desligamentos/inicializações?
Exemplo prático de caso de uso: permitir ssh
-acesso somente no horário de trabalho.
PS: Talvez eu não entenda muito bem os temporizadores do systemd, ainda?
Eu tinha os mesmos requisitos.
Posso confirmar que dois cronômetros alcançando a inicialização resultam em uma condição de corrida, com um resultado aleatório.
E que tal um cenário em que o sistema reinicia mais de uma vez entre 12 e 13.
Persistent
pode não ajudar em nada nesse caso.Minha conclusão (mas eu adoraria estar errado) é que o systemd simplesmente não é feito para este caso de uso.
Meu trabalho é usar a configuração acima, sem os
Persistent
sinalizadores. Então eu crio um novoidle
serviço dedicado a lidar com o estado após a inicialização. Este serviço compara a hora atual com o estado atual do serviço de destino e inicia/para o serviço se não corresponderem. Observe que os horários de início/parada precisam ser duplicados nos cronômetros e no script de serviço 'gerenciador de inicialização', o que não é o ideal.Essa é a única maneira confiável que encontrei para garantir que meu serviço seja executado durante o período de tempo selecionado, independentemente das várias reinicializações.