Crear un servicio con systemd en GNU/Linux

En este tutorial como ejemplo se crea en un sistema operativo GNU/Linux  un servicio con  systemd que ejecuta el servidor SimpleHTTPServer escrito en Python en el puerto 8000 del servidor local.
Por motivos de seguridad este servidor NO debería ejecutarse en ambientes de producción.

Crear un servicio con systemd

Systemd es un sistema init usado en las distribuciones GNU/Linux para iniciar (bootstrap) el espacio de usuario y gestionar a continuación todos sus procesos. Es actualmente el sistema init predeterminado en la mayoría de las distribuciones GNU/Linux.

Systemd trabaja con unidades (units) que son recursos (red, usb, etc.) gobernados por ficheros (unit files) almacenados en /lib/systemd/system que contienen secciones y directivas.

Tipos de unidades

Existen 12 tipos de unidades (unit types):

Services (.service): servicios
Target: grupo de unidades
Automount: filesystem auto-mount point
Device: nombres de dispositivos del kernel, que se pueden ver en sysfs y udev
Mount: punto de montaje del sistema de ficheros
Path: fichero o directorio
Scope: proceso externo no iniciado por systemd
Slice: una unidad de procesos de gestión
Snapshot: estado salvado de systemd
Socket: IPC (inter-process communication) socket
Swap: fichero swap
Timer: systemd timers

Para nombrar un unit file se utiliza el formato <nombre_recurso>.<tipo_unidad> (<resource_name>.<unit_type>) por ejemplo:

reboot.service

Un target se parece a un runlevel de SysV Init: por ejemplo graphical.target es similar a runlevel 5.

Los pasos para crear un servicio en Systemd son los siguientes:
1) Abrimos un terminal y creamos el fichero con las instrucciones  del nuevo servicio:

vim /lib/systemd/system/ejemplo.service

[Unit]
Description=Ejemplo
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=1
User=usuario
ExecStart=/usr/bin/env python3 /usuario/ejemplo.py

[Install]
WantedBy=multi-user.target

Aquí se debe cambiar el nombre del usuario y la ruta al script en python con vuestros datos. Salvamos y guardamos los cambios.

2) En el directorio /usuario/ (reemplazar la ruta con la vuestra escrita en el fichero anteriormente creado) se programa el siguiente script en python:

vim ejemplo.py

import http.server
import socketserver

PORT = 8000

handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer((«», PORT), handler) as httpd:
print(«Server started at localhost:» + str(PORT))
httpd.serve_forever()

Salvamos y guardamos los cambios.

3) Iniciamos el servicio, verificamos que funciona correctamente y lo habilitamos para que se ejecute automáticamente:

sudo systemctl start ejemplo
sudo systemctl status ejemplo
sudo systemctl enable ejemplo

Finalmente abrimos un navegador y escribimos la ruta al servidor SimpleHTTPServer reemplazando la IP con la vuestra:

http://10.0.2.2:8000/

Crear un timer con systemd

En este ejemplo se creará un timer en sistemas operativos GNU/Linux para ejecutar un script en bash.

Los pasos para crear un timer son los siguientes:
1) Abrimos un terminal y creamos el fichero con las instrucciones para el nuevo servicio:

vim /lib/systemd/system/fecha.service

[Unit]
Description=Una prueba

[Service]
Type=oneshot
ExecStart=/bin/bash /usuario/fecha.sh

Aquí se debe cambiar el nombre del usuario y la ruta al script en bash con vuestros datos. Salvamos y guardamos los cambios.

2) En el directorio /usuario/ (reemplazar la ruta con la vuestra escrita en el fichero anteriormente creado) programamos el siguiente script en python:

vim fecha.py

#!/bin/bash
FECHA=$(date ‘+%Y-%m-%d %H:%M:%S’); echo -e «$FECHA» >> /usuario/registro.log
echo -e «Hola mundo» >> /usuario/registro.log

Salvamos y guardamos los cambios.

le damos permisos de ejecución con:

chmod 755 fecha.sh

3) Ahora se debe crear el fichero timer:
vim /lib/systemd/system/fecha.timer

[Unit]
Description=Runs every 1 minutes fecha.sh

[Timer]
OnCalendar=*:0/1

[Install]
WantedBy=timers.target

Salvamos y guardamos los cambios.

4) Iniciamos el servicio, verificamos que funciona correctamente y lo habilitamos para que se ejecute automáticamente:

sudo systemctl start fecha
sudo systemctl status fecha
sudo systemctl enable fecha

Si hacemos algún cambio a los ficheros de systemd se debe ejecutar la siguiente orden:

systemctl daemon-reload

Algunos comandos útiles para systemd

Localización de los ficheros de las unidades:

/etc/systemd/system/
/usr/lib/systemd/system/

Listado de unidades en ejecución:

systemctl list-units –type [unit name]
systemctl list-unit-files –type=service
systemctl list-units –type service –all

Verificar el estado de un servicio:

systemctl status motd-news.service

Referencias

Wiki de Debian. https://wiki.debian.org/Debate/initsystem/systemd
Atareao.es. Como crear un servicio con systemd. https://www.atareao.es/tutorial/trabajando-con-systemd/como-crear-un-servicio-con-systemd/
Wikipedia. systemd. https://es.wikipedia.org/wiki/Systemd
Tutorial Digital Ocean. https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units-es