Systemd Socket Activation Aciona um script bash

1

Gostaria de disparar periodicamente um script bash remoto. Como isso precisa funcionar é que um aplicativo de terceiros se conectará a um sistema do CentOS 7 em uma porta TCP específica e enviará uma pequena mensagem de texto. O SSH não é uma opção por causa do aplicativo de terceiros.

Quando a mensagem é recebida, ela precisa passar o endereço IP para o script bash. Eu gostaria que o script bash fosse executado e depois fosse adormecido até a próxima mensagem. Eu preferiria não escrever um daemon. Eu só quero manter isso simples.

Essas mensagens podem aparecer algumas vezes por semana ou menos. Nós tínhamos isso rodando usando o xinetd mas não sabíamos exatamente como fazer isso funcionar com o systemd.

Aqui está o que eu tenho até agora:

/etc/systemd/systemfoo.service

[Unit]
Description=Foo Service
After=network.target foo.socket
Requires=foo.socket

[Service]
Type=oneshot
ExecStart=/bin/bash /opt/foo/foo.sh
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target

/etc/systemd/systemfoo.socket

[Unit]
Description=Foo Socket
PartOf=foo.service

[Socket]
ListenStream=127.0.0.1:7780

[Install]
WantedBy=sockets.target

/opt/foo/foo.sh

#!/bin/bash

# Not sure how to get IP
logger -t FOO "Connection received:"
# Do some action

Isso é o que eu vejo no log:

Jul 10 17:29:32 localhost systemd: Listening on Foo Socket.
Jul 10 17:29:32 localhost systemd: Starting Foo Socket.
Jul 10 17:29:32 localhost systemd: Started Foo Service.
Jul 10 17:29:32 localhost systemd: Starting Foo Service...
Jul 10 17:29:32 localhost FOO: Connection received
Jul 10 17:29:53 localhost systemd: Started Session 4 of user vagrant.
Jul 10 17:29:53 localhost systemd-logind: New session 4 of user vagrant.
Jul 10 17:29:53 localhost systemd: Starting Session 4 of user vagrant.
Jul 10 17:29:56 localhost su: (to root) vagrant on pts/1
Jul 10 17:30:11 localhost systemd: Started Foo Service.
Jul 10 17:30:11 localhost systemd: Starting Foo Service...
Jul 10 17:30:11 localhost FOO: Connection received
Jul 10 17:30:11 localhost systemd: Started Foo Service.
Jul 10 17:30:11 localhost systemd: Starting Foo Service...
Jul 10 17:30:11 localhost FOO: Connection received
Jul 10 17:30:11 localhost systemd: Started Foo Service.
Jul 10 17:30:11 localhost systemd: Starting Foo Service...
Jul 10 17:30:11 localhost FOO: Connection received
Jul 10 17:30:11 localhost systemd: Started Foo Service.
Jul 10 17:30:11 localhost systemd: Starting Foo Service...
Jul 10 17:30:11 localhost FOO: Connection received
Jul 10 17:30:11 localhost systemd: Started Foo Service.
Jul 10 17:30:11 localhost systemd: Starting Foo Service...
Jul 10 17:30:11 localhost FOO: Connection received
Jul 10 17:30:11 localhost systemd: start request repeated too quickly for foo.service
Jul 10 17:30:11 localhost systemd: Failed to start Foo Service.
Jul 10 17:30:11 localhost systemd: Unit foo.socket entered failed state.
Jul 10 17:30:11 localhost systemd: Unit foo.service entered failed state.
Jul 10 17:30:11 localhost systemd: foo.service failed.

Alguma sugestão sobre como fazer o systemd executar o script uma vez e, em seguida, aguardar a próxima mensagem antes de executá-lo novamente?

Para teste, estou apenas a executar:

echo "Hello" | nc 127.0.0.1 7780

Configuração de trabalho atualizada

/etc/systemd/[email protected] Observe o @.

[Unit]
Description=Foo Service
After=network.target systemfoo.socket
Requires=systemfoo.socket

[Service]
Type=oneshot
ExecStart=/bin/bash /opt/foo/foo.sh
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target

/etc/systemd/systemfoo.socket

[Unit]
Description=Foo Socket
[email protected]

[Socket]
ListenStream=127.0.0.1:7780
Accept=Yes

[Install]
WantedBy=sockets.target

/opt/foo/foo.sh

#!/bin/bash

# Not sure how to get IP
logger -t FOO "Connection received: $REMOTE_ADDR $REMOTE_PORT"
# Do some action

Necessário para carregar a configuração no systemd:

systemctl enable systemfoo.socket
systemctl start systemfoo.socket
    
por Hugh 11.07.2018 / 18:21

1 resposta

2

Você deve adicionar Accept=yes à unidade de soquete, indicando que o systemd deve iniciar instâncias de serviço separadas para cada conexão e, em seguida, transformar a unidade de serviço em um modelo ( [email protected] ) para ser instanciado separadamente para cada conexão. Em seguida, o endereço e a porta remotos devem estar disponíveis nas variáveis de ambiente REMOTE_ADDR e REMOTE_PORT , de acordo com a% man_de% manpage.

    
por 11.07.2018 / 18:37

Tags