Como configurar o systemd para transformar um script simples com o standardIO em um serviço de rede

3

Estou tentando configurar um script bash como um serviço de rede que atende na porta tcp 6666. Mas o serviço falha na inicialização com esses erros:

 heartbeat]# systemctl status heartbeat.service
● heartbeat.service - Service de collecte des signaux de vie
   Loaded: loaded (/etc/systemd/system/heartbeat.service; disabled; vendor preset: disabled)
   Active: failed (Result: resources)

mai 12 12:32:48 Chalet systemd[1]: heartbeat.service: Got more than one socket.
mai 12 12:32:48 Chalet systemd[1]: heartbeat.service: Failed to run 'start' task: Invalid argument
mai 12 12:32:48 Chalet systemd[1]: Failed to start Service de collecte des signaux de vie.
mai 12 12:32:48 Chalet systemd[1]: heartbeat.service: Unit entered failed state.
mai 12 12:32:48 Chalet systemd[1]: heartbeat.service: Failed with result 'resources'.
mai 12 12:33:18 Chalet systemd[1]: heartbeat.service: Got more than one socket.
mai 12 12:33:18 Chalet systemd[1]: heartbeat.service: Failed to run 'start' task: Invalid argument
mai 12 12:33:18 Chalet systemd[1]: Failed to start Service de collecte des signaux de vie.
mai 12 12:33:18 Chalet systemd[1]: heartbeat.service: Failed with result 'resources'.

Eu não entendo essa mensagem "heartbeat.service: tenho mais de um soquete" significa. Você pode me ajudar a entender onde estou errado?

Eu configurei o systemd assim:

heartbeat.socket:

[Unit]
Description=Socket pour le demon heartbeat
PartOf=heartbeat.service

[Socket]
ListenStream=0.0.0.0:6666
Accept=true

[Install]
WantedBy=sockets.target

heartbeat.service:

[Unit]
Description=Service de collecte des signaux de vie
After=network.target heartbeat.socket
Requires=heartbeat.socket

[Service]
Type=simple
ExecStart=/bin/bash /usr/heartbeat/heartbeat.bash
RemainAfterExit=no
StandardInput=socket
StandardOutput=inherit

[Install]
WantedBy=multi-user.target

/usr/heartbeat/heartbeat.bash é:

 #!/bin/bash
while true
do
        read -r entree
        if [[ $entree == "frequence" ]]
        then
                echo "3600"
        fi
        if [[ -n $entree ]]
        then
                logger "heartbeat receveid : $entree"
        fi
done
    
por xoubih 12.05.2017 / 14:56

1 resposta

2

Renomear heartbeat.service heartbeat @ .service fez o trabalho.

A resposta foi simplesmente na página de manual systemd.socket (RTFM duas vezes, se uma não for suficiente ...):

Para cada arquivo de soquete, um arquivo de serviço correspondente deve existir, descrevendo o serviço para iniciar o tráfego de entrada no soquete (consulte systemd.service (5) para obter mais informações sobre arquivos .service). O nome da unidade .service é, por padrão, igual ao nome da unidade .socket, mas pode ser alterado com a opção Service = descrita abaixo. Dependendo da configuração da opção Accept = descrita abaixo, essa unidade de serviço deve ser nomeada como a unidade .socket, mas com o sufixo substituído, a menos que seja substituído por Service =; ou deve ser uma unidade de modelo com o mesmo nome. Exemplo: um arquivo de soquete foo.socket precisa de um serviço correspondente foo.service se Accept = false estiver definido. Se Accept = true for definido, um arquivo de modelo de serviço foo @ .service deverá existir a partir do qual os serviços serão instanciados para cada conexão de entrada.

Consequentemente, o serviço não deve ser iniciado, pois ele é instanciado pelo systemd e disparado pela unidade de soquete (que precisa ser iniciada para escutar a porta tcp para conexões de entrada)

Como não atribuímos nenhum nome à instância, para aqueles que estariam curiosos sobre o nome da instância dada por% I no serviço, parece ser o número da instância menos um (ou seja, a primeira instância tem o nome). 0 ID):

[root@Chalet ~]# systemctl status heartbeat.socket
● heartbeat.socket - Socket pour le demon heartbeat
   Loaded: loaded (/etc/systemd/system/heartbeat.socket; disabled; vendor preset: disabled)
   Active: active (listening) since Mon 2017-05-15 15:25:03 CEST; 7h ago
   Listen: 0.0.0.0:6666 (Stream)
 Accepted: 5; Connected: 5

mai 15 15:25:03 Chalet systemd[1]: Listening on Socket pour le demon heartbeat.
[root@Chalet ~]# ncat 127.0.0.1 6666              
what is %I in the service ?
^C
[root@Chalet ~]# systemctl status heartbeat.socket
● heartbeat.socket - Socket pour le demon heartbeat
   Loaded: loaded (/etc/systemd/system/heartbeat.socket; disabled; vendor preset: disabled)
   Active: active (listening) since Mon 2017-05-15 15:25:03 CEST; 7h ago
   Listen: 0.0.0.0:6666 (Stream)
 Accepted: 6; Connected: 6

mai 15 15:25:03 Chalet systemd[1]: Listening on Socket pour le demon heartbeat.
[root@Chalet ~]# journalctl -ra                   
-- Logs begin at Sat 2016-11-19 19:12:18 CET, end at Mon 2017-05-15 23:02:21 CEST. --
mai 15 23:02:21 Chalet root[7224]: heartbeat receveid : what is %I in the service ?
mai 15 23:01:43 Chalet systemd[1]: Started Service de collecte des signaux de vie pour 5 (127.0.0.1:50920).
    
por 15.05.2017 / 23:29