Créer un service systemd

Créer un service systemd

Sous Linux, Systemd est le candidat parfait pour gérer ses propres services. La bonne nouvelle c’est que c’est extrêmement simple d’en créer un. Voyons comment faire au travers d’un exemple : créer un service pour le démon Apache Exporter (utilisé pour récupérer les métrics d’Apache).

Ecrire le service

Rien de plus simple :

$ nano /etc/systemd/system/apache-exporter.service

Et on met dedans :

[Unit]
Description=Prometheus Apache Exporter

[Service]
User=nicolas
Group=nicolas
WorkingDirectory=/usr/bin
Type=simple
ExecStart=/usr/bin/apache_exporter
Restart=always

[Install]
WantedBy=multi-user.target

Et voilà. Rien de plus. En fait si, recharger la config :

$ systemctl daemon-reload

Opérations usuelles

Désormais, les commandes usuelles sont disponibles. On peut vérifier le status :

$ systemctl status apache-exporter
apache-exporter.service - Prometheus Apache Exporter
   Loaded: loaded (/etc/systemd/system/apache-exporter.service; disabled; vendor preset: enabled)
   Active: inactive (dead)

Activer le service :

$ systemctl start apache-exporter

Vérifier que le démon ciblé fonctionne correctement :

$ ss -lpt
LISTEN 0 128 *:9117 *:* users:(("apache_exporter",pid=904,fd=3))   

Parfait, le démon écoute bien sur le port 9117. Autres actions :

# Arrêter le service
$ systemctl stop apache-exporter

# Redémarrer le service
$ systemctl restart apache-exporter

# Activer le service au démarrage
$ systemctl enable apache-exporter
Created symlink /etc/systemd/system/multi-user.target.wants/apache-exporter.service → /etc/systemd/system/apache-exporter.service.

# Désactiver le service au démarrage
$ systemctl disable apache-exporter

Cas plus complexe

Supposons que nous voulions passer des paramètres. Par exemple, l’exporter mysql pour Prometheus requiert les identifiants à la base de données. Ces identifiants sont passés dans la variable d’environnement DATA_SOURCE_NAME. Au lieu de coder en dur ces paramètres créons un fichier de configuration :

$ nano /etc/default/mysql-exporter

Et on met dedans (adapter à vos besoin, ici il faut indiquer l’utilisateur qui a accès aux statistiques de MySQL) :

DATA_SOURCE_NAME=<user>:<password>#@(localhost:3306)/ 

Créer la configuration du service, on ajoute simplement la ligne EnvironmentFile :

[Unit]
Description=Prometheus Mysql Exporter

[Service]
User=nicolas
Group=nicolas
WorkingDirectory=/usr/bin
Type=simple
ExecStart=/usr/bin/mysqld_exporter
Restart=always
EnvironmentFile=/etc/default/mysql-exporter

[Install]
WantedBy=multi-user.target

Reste plus qu’à activer le service comme précédemment.

Créer un service systemd

Introduction à rsync

rsync est un des outils les plus efficaces pour synchroniser des dossiers, que ce soit localement ou entre deux machines en réseau.

Installation

rsync est déjà pré-installé sur la plupart des distributions Linux et macOS. Pour vérifier que c’est bien le cas (macOS):

$ rsync --version
rsync  version 2.6.9  protocol version 29

Si ce n’est pas le cas, installer le paquet (Debian):

$ sudo apt-get install rsync

Utilisation

Syntaxe

Trois cas de figure possibles :

Local vers Local:  rsync [option]... [SRC]... DEST
Local vers Distant: rsync [OPTION]... [SRC]... [USER@]HOST:DEST
Distant vers Local: rsync [OPTION]... [USER@]HOST:SRC... [DEST]
  • OPTION – Les options rsync
  • SRC – Répertoire source
  • DEST – Répertoire destination
  • USER – nom d’utilisateur de la machine distante
  • HOST – adresse IP ou nom d’hôte

Options les plus courantes :

  • -a--archive. Mode archive. Synchronisation récursive des deux dossiers, préserve les liens symboliques, les dates de modifications, les groupes, les permissions, les propriétaires.
  • -z--compress. Compresse les données avant de les envoyer vers la machine distante. A utiliser si le débit vers la machine distante est bas.
  • -P. Affiche une barre de progression pendant le transfert.
  • --delete. rsync effacera les fichiers présents dans le répertoire de destination mais non présent dans le répertoire source. Idéal pour créer des miroirs, attention toutefois bien faire des tests avec l’option -n avant.
  • -n ou --dry-run. Ne fais rien, affiche simplement ce qui sera fait si la commande est exécutée sans cette option.
  • -q--quiet. Supprime les message à caractère d’information.
  • -v--verbose. Augmente le nombre de messages affichés.
  • -e. Permet d’utiliser un autre shell distant que celui par défaut (ssh).
  • -t, --times. Préserve les dates.

Exemples : local vers local

Copier un fichier d’un répertoire à un autre sans le renommer :

$ rsync -a /home/filename.zip /tmp/

Copier un fichier d’un répertoire à un autre et le renommer :

$ rsync -a /home/filename.zip /tmp/newname.zip

Synchroniser le contenu de deux répertoire locaux (si le répertoire de destination n’existe pas, il sera créé) :

$ rsync -a /var/www/html/mysite/public_html/ /var/www/html/mysite/public_html_backup/

Précisions que rsync se comportera différemment si vous précisez ou non le slash de fin /. Si le slash de fin est présent sur le répertoire source, seul le contenu du répertoire sera synchronisé. Dans le cas contraire, un répertoire sera créé dans le répertoire de destination.

Exemples : local vers distant

Inutile de préciser que rsync doit être installé sur les deux machines.

Synchroniser un dossier local (source) avec un distant (destination) :

$ rsync -a /home/nicolas/ user@host_or_ip:/home/nicolas/

Synchroniser un dossier distant (source) vers un dossier local (destination) :

$ rsync -a user@host_or_ip:/home/nicolas/ /home/nicolas/

Spécifier un port ssh différent de 22 sur la machine distante :

$ rsync -a -e "ssh -p 2322" user@host_or_ip:/home/nicolas/ /home/nicolas/

Exclure des dossiers

Exclure un dossier du répertoire source (il ne sera donc pas copié vers le répertoire de destination) :

$ rsync -a --exclude="node_modules" --exclude="tmp" /src_directory/ /dst_directory/

L’option --exclude-from permet de spécifier une liste de ressources à exclure :

$ rsync -a --exclude-from='exclude-list.txt' /src_directory/ /dst_directory/

Bien sûr, le fichier doit exister :

$ cat exclude-list.txt
node_modules
tmp

Aller plus loin

Problématique

Mon environnement de développement est constitué d’un serveur et de deux postes clients, le tout sur le même réseau. Les postes de développement ne peuvent pas exécuter du code (pas de serveur installé localement, ni même de docker qui demande beaucoup trop de ressource), c’est le rôle du serveur de développement.

Ce qui suit n’est pas à reproduire dans un environnement professionnel. Ca fonctionne ici car il n’y a qu’un seul développeur (Bibi)

Chaque projet a donc un répertoire sur le serveur de développement. Le code est donc toujours sur le serveur de développement qui lui est un vrai serveur. Voici un schéma de l’infrastructure :

Avant de lancer son IDE préféré (phpstorm), il faut donc synchroniser le répertoire local du projet avec le répertoire distant du projet. rsync arrive donc à point nommer !

Première ébauche de la commande à utiliser :

$ rsync -aP --delete nicolas@192.168.1.91:projects/xblogv7/ $HOME/PhpstormProjects/xblogv7

Là je synchronise le dossier local $HOME/PhpstormProjects/xblogv7 avec son homologue distant.
Mais un problème se pose : et si je ne veux pas synchroniser certains dossiers (comme un certain node_modules par exemple) ? Il suffit de placer la liste des dossiers à exclure dans un ficher texte et d’utiliser l’option --exclude-from :

$ rsync -aP --delete --exclude-from="excluded-files.txt" nicolas@192.168.1.91:projects/xblogv7/ $HOME/PhpstormProjects/xblogv7

Automatisation

Ce n’est pas évident à voir, mais l’utilisation de l’option --delete pose un problème : comme elle efface les dossiers qui sont présents dans destination et pas dans source, le dossier de configuration de mon IDE (qui se trouve seulement dans destination) est supprimé lors de la synchronisation… Pas très cool ça. Pour remédier à ça, on va écrire un petit script bash qui va faire une copie de ce fameux dossier avant de lancer la commande rsync, et rétablira le dossier juste après.

#!/usr/bin/env bash

# Backup IDE settings
idea_settings="${HOME}/PhpstormProjects/xblogv7/.idea"
restore=false
if [[ -e "$idea_settings" ]]
then
    echo "IDE Directory found, create a backup..."
    cp -rp "$idea_settings" "/tmp/idea"
    restore=true
fi

declare EXCLUDED_LIST
EXCLUDED_LIST[0]="public/"
EXCLUDED_LIST[1]="var/"
EXCLUDED_LIST[2]=".git/"
EXCLUDED_LIST[3]="_dev/node_modules/"

# Build excluded list
for item in "${EXCLUDED_LIST[@]}"
do
    echo "$item" >> excluded-files.txt
done

rsync -aP --delete --exclude-from="excluded-files.txt" nicolas@192.168.1.91:projects/xblogv7/ $HOME/PhpstormProjects/xblogv7

rm excluded-files.txt

# Restore IDE settings
if [ "$restore" = true ]
then
    echo "Restore backup IDE settings..."
    mkdir "$idea_settings"
    cp -rp "/tmp/idea/" "${idea_settings}"
    rm -r "/tmp/idea/"
fi

Références externes

Créer un service systemd

Renommage en masse de fichiers

Une application typique serait de changer les extensions de tous les fichiers d’un répertoire. On peut le faire dans une boucle for :

for f in *.html; do 
    mv -- "$f" "${f%.html}.php"
done

Purger les fichiers temporaires macOS

Purger les fichiers temporaires macOS

Parfois il est intéressant de supprimer tous les fichiers temporaires que macOS a pu laisser sur son passage (sur un montage samba par exemple).
Il suffit d’exécuter ces 2 commandes dans le répertoire à nettoyer :

$ find . -regex '.+/\._.+' | xargs -d "\n" rm
$ find . -name '.DS_Store' -type f | xargs -d "\n" rm

Explication :

  • find . -regex '.+/\._.+' : on recherche tous les fichiers qui commencent par ._
  • xargs -d "\n" rm : chaque fichier trouvé est passé en argument à la commande rm. L’option -d permet de changer le délimiteur d’argument, utilise quand les nom de dossiers et fichiers contiennent des espaces.
Créer un service systemd

Traquer de l’espace disque caché

Qui ne s’est pas retrouvé dans une situation similaire ? On veut lister l’espace consommé par les partitions :

$ df -h
Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur
[...]
/dev/md2           421G    421G     0 100% /home

Et en se plaçant dans le répertoire /home, on voit que le compte n’y ait pas :

$ du -scbh
279G	.
279G	total

What the heck is that ?? Pas de panique, il s’agit souvent d’un ou plusieurs fichiers volumineux qui sont restés ouvert et qui échappent donc à la commande du. C’est là qu’intervient la commande lsof :

lsof /dev/md2
COMMAND   PID    USER   FD   TYPE DEVICE     SIZE/OFF     NODE
gzip     3738    root    0r   REG    9,2 151198527488  8126470 /home/backups/ladameduweb1-home.20190311.master.tar.gz (deleted)

Et voilà, j’avais fait un delete sauvage sur un fichier en cours de compression !

Ressources externes

FTP en ligne de commande

Tout d’abord, se connecter en ligne de commande :

$ ftp <ip>
$ ftp user@domain.com

Autre solution :

$ ftp
$ ftp> open 192.168.1.31
Connected to 192.168.1.31.
Name (192.168.1.31:nicolas): user01

Entrez les informations de connexion puis utiliser l’une des commandes suivantes :

appendajoute un fichier à un autre
asciipasse le transfert en mode ascii
bellémet un son à la fin du transfert
binarypasse le transfert en mode binaire
byetermine la session ftp
cdchange le répertoire de travail distant courant
closetermine la session ftp
deleteefface le fichier distant désigné
debugpasse en mode debug
diraffiche le listing des répertoires
disconnecttermine la session ftp
gettélécharge le fichier distant désigné sur la machine locale
helpaffiche l’aide
lcdchange le répertoire locale de travail
lsalias de dir
mdeleteefface plusieurs fichiers
mdirliste le contenu d’un répertoire distant