Outils pour utilisateurs

Outils du site


openrc

Openrc, l'init system

Alpine Linux conserve un init system (chargé de lancer les programmes au démarrage et surveiller les services/daemons) simple : OpenRC. Evidemment, d'autres distrib le proposent aussi, même si systemd a tendance à se généraliser (mais pas sur les distrib légère style buildroot, Alpine…)

Docs sur Alpine Linux, Archlinux.

Commandes populaires

# Change service state, get info about state
rc-service <service name> start | stop | restart | status
 
# Auto start on/off
rc-update add | del <service name>
 
# Infos sur les services en cours de fonctionnement
rc-status

Créer son propre service

Sur Alpine Linux, les applications communes (docker, syncthing, …) proposent souvent un paquet spécifique pour fournir le script d'init qui va bien, exemple syncthing-openrc.
Le script est dispo dans /etc/init.d/nom-service si jamais on souhaite le modifier.

Pour le créer de toute pièce, on peut s'inspirer des services qui existe déjà dans /etc/init.d/, sinon je suis sur que la doc d'Archlinux en parle, ou alors le wiki d'Alpine Linux.
Allez, voici un résumé :

  • Le script doit commencer par #!/sbin/openrc-run
  • Le script doit être executable chmod u+x <mon_script> * Le script doit être rangé dans /etc/init.d/ * Ne pas réécrire les fonctions start et stop' si elles n'ont rien de spécial, openrc s'en charge tout seul
  • La définition de variables peut suffire pour un script simple
  • depend(){ use net } permet de temporiser le démarrage pour attendre la dispo du réseau
  • Le pidfile doit être seulement accessible par root, on rajoute donc le flag –make-pidfile pour demander à root de créer le fichier (sinon c'est la commande appelée qui s'en occupe, mais les droits d'utilisateur peuvent poser pb)
  • L'emplacement des log doit être en écriture pour le user choisi (au besoin, on fait un sous dossier dans /var/log avec les droits en écriture pour ce user

Voici un exemple :

#!/sbin/openrc-run
 
name="geometeo_storage"
description="Démarre geometeo_storage pour accueillir les requêtes d'enregistrements de température"
command="/home/geo/geometeo-server/start_storage.sh"
command_args=""
command_user="geo"
pidfile="/run/${name}.pid"
start_stop_daemon_args="--make-pidfile"
command_background="yes"
output_log="/var/log/geometeo/storage.log"
error_log="/var/log/geometeo/storage.err"
 
# Dépendances : attends que le réseau soit démarré
depend() {
    need net
    use logger
}

Sous-processus

Le script sh appelé dans l'exemple précédent a pour objectif de fournir un environnement python pour executer un programme python :

#!/bin/sh
# start_storage.sh
 
cd /home/geo/geometeo-server
source .venv/bin/activate
python geometeo_storage.py # ne se termine pas, car attend des requêtes jusqu'à la fin des temps

Problème : openrc n'a pas connaissance des programmes enfants et un arrêt rc-service geometeo stop n'arrête que le script start_storage.sh, pas le programme python geometeo_storage.py.

Le mieux est d'adapter le script sh de la manière suivante :

#!/bin/sh
# start_storage.sh
 
 
cd /home/geo/geometeo-server
 
source .venv/bin/activate
 
# Fonction pour arrêter proprement
cleanup() {
    pkill -P $$  # Tue tous les enfants de ce script
    exit 0
}
 
# Capture SIGTERM et SIGINT
trap cleanup SIGTERM SIGINT
 
python geometeo_storage.py &
 
# Attend la fin des enfants
wait

la fonction cleanup() est exécutée à la fermeture du script start_storage.sh, et se charge de kill tous les processus enfants :

  • trap cleanup SIGTERM SIGINT, surveille les signaux SIGTERM et SIGINT et appelle la fonction cleanup
  • La commande pkill -P $$ sert à tuer tous les processus dont le parent est le shell courant
    • $$ dans un script shell représente le PID (numéro d’identification de processus) du shell qui exécute le script
    • pkill -P <pid> demande à pkill de signaler (par défaut, tuer) tous les processus dont le parent a ce PID
    • Donc pkill -P $$ va typiquement terminer tous les processus lancés depuis ce script (par exemple des commandes en arrière-plan), pour éviter qu’ils continuent à tourner après une erreur ou en fin de script.

Il est nécessaire d'exécuter le script enfant en background avec &, sinon le rc-service geometeo stop freeze car attend la fin du script sh start_storage.sh (testé par moi).

openrc.txt · Dernière modification : de luc