
Estoy intentando crear un servicio con systemd, donde uso python3 para crear un socket simple y dejarlo como demonio, pero he hecho varios intentos pero en ambos casos sin éxito. Por hoy systemd me ha ganado, pero mañana es otro día para intentarlo.
Servidor
import socket
host = '127.0.0.1'
port = 9999
BUFFER_SIZE = 1024
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
socket_tcp.bind((host, port))
socket_tcp.listen(5) # Esperamos la conexión del cliente
conn, addr = socket_tcp.accept() # Establecemos la conexión con el cliente
with conn:
print('[*] Conexión establecida')
while True:
# Recibimos bytes, convertimos en str
data = conn.recv(BUFFER_SIZE)
# Verificamos que hemos recibido datos
if not data:
break
else:
print('[*] Datos recibidos: {}'.format(data.decode('utf-8')))
conn.send(data) # Hacemos echo convirtiendo de nuevo a bytes
Client
import socket
# El cliente debe tener las mismas especificaciones del servidor
host = '127.0.0.1'
port = 9999
BUFFER_SIZE = 1024 MESSAGE = 'Hola, mundo!' # Datos que queremos enviar with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
socket_tcp.connect((host, port))
# Convertimos str a bytes
socket_tcp.send(MESSAGE.encode('utf-8'))
data = socket_tcp.recv(BUFFER_SIZE)
Archivo de unidad de configuración
sudo nano /etc/systemd/system/socket_prueba.service
sudo rm -r /etc/systemd/system/socket_prueba.service
[Unit]
Description= Server Relay System: Manager
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/local/bin/pipenv run python /path/test_server.py
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable socket_prueba.service
sudo systemctl start socket_prueba.service
sudo systemctl status socket_prueba.service
Resultado:
● socket_prueba.service - Server Relay System: Manager
Loaded: loaded (/etc/systemd/system/socket_prueba.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2021-09-25 16:07:17 -05; 58min ago
Process: 25771 ExecStart=/usr/local/bin/pipenv run python
/home/path>
Main PID: 25771 (code=exited, status=2)
sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Scheduled restart job, restart counter is >
sep 25 16:07:17 serversaas systemd[1]: Stopped Server Relay System: Manager.
sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Start request repeated too quickly.
sep 25 16:07:17 serversaas systemd[1]: socket_prueba.service: Failed with result 'exit-code'.
sep 25 16:07:17 serversaas systemd[1]: Failed to start Server Relay System: Manager.
intención 2 Fuente:systemd y pitón
● socket_prueba.socket - Socket prueba
Loaded: loaded (/etc/systemd/system/socket_prueba.socket; disabled; vendor preset: enabled)
Active: failed (Result: service-start-limit-hit) since Sat 2021-09-25 17:00:47 -05; 4s ago
Triggers: ● socket_prueba.service
Listen: 127.0.0.1:9999 (Stream)
sep 25 17:00:47 vidm-OMEN systemd[1]: Listening on Socket prueba.
sep 25 17:00:47 vidm-OMEN systemd[1]: socket_prueba.socket: Failed with result 'service-start-limit-hit'.
Respuesta1
Aquí está listo para implementar comandos simples de implementación de shell para su caso, puede cambiar directorios, nombre, descripción del servicio o script, etc., la descripción se encuentra a continuación:
Crear directorio y script en sí.
mkdir /usr/src/python-socket -p
cat > /usr/src/python-socket/python-socket.py << 'EOL'
import socket
host = '127.0.0.1'
port = 9999
BUFFER_SIZE = 1024
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket_tcp:
socket_tcp.bind((host, port))
socket_tcp.listen(5) # Esperamos la conexión del cliente
conn, addr = socket_tcp.accept() # Establecemos la conexión con el cliente
with conn:
print('[*] Conexión establecida')
while True:
# Recibimos bytes, convertimos en str
data = conn.recv(BUFFER_SIZE)
# Verificamos que hemos recibido datos
if not data:
break
else:
print('[*] Datos recibidos: {}'.format(data.decode('utf-8')))
conn.send(data) # Hacemos echo convirtiendo de nuevo a bytes
EOL
Configurar variables para crear el servicio systemd
SERVICE_NAME=python-socket
SERVICE_DESCRIPTION="Test python service"
SERVICE_COMMAND="/usr/bin/python3 /usr/src/python-socket/python-socket.py"
SERVICE_WORK_DIR=/usr/src/python-socket/
SERVICE_USER=root
Implementar la configuración del servicio systemd
cat > /etc/systemd/system/${SERVICE_NAME}.service << EOL
[Unit]
Description=${SERVICE_DESCRIPTION}
After=multi-user.target
[Service]
Environment="FROM=SYSTEMD"
WorkingDirectory=${SERVICE_WORK_DIR}
Type=simple
User=${SERVICE_USER}
ExecStart=${SERVICE_COMMAND}
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
KillMode=process
[Install]
WantedBy=multi-user.target
EOL
Aplicar nuevo servicio, iniciarlo y comprobar
systemctl daemon-reload
systemctl enable ${SERVICE_NAME}
systemctl stop ${SERVICE_NAME}
systemctl start ${SERVICE_NAME}
systemctl status ${SERVICE_NAME}
Como resultado, la configuración del servicio systemd se verá así
[Unit]
Description=Test python service
After=multi-user.target
[Service]
Environment="FROM=SYSTEMD"
WorkingDirectory=/usr/src/python-socket/
Type=simple
User=root
ExecStart=/usr/bin/python3 /usr/src/python-socket/python-socket.py
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
KillMode=process
[Install]
WantedBy=multi-user.target
Dónde:
Environment="FROM=SYSTEMD"
- alguna variable env si quieres pasar a tu script de Python
Type=simple
- servicio systemd simple que funcionará mientras el script esté activo
RemainAfterExit=no
Restart=always
RestartSec=2
StartLimitBurst=999999
StartLimitInterval=0
Estos parámetros no permitirán que su script esté inactivo en ninguna condición; comenzará si falla continuamente
KillMode=process
- Así es como se detendrá tu script, si no tienes eventos SIG especiales en tu script de Python, es universal