Blog de dada

DevOps, bidouilleur et routard plein de logiciels libres

Sortir d'un /boot débordant

Rédigé par dada / 11 septembre 2020 / 2 commentaires



Vous avez déjà souffert devant un /boot plein ? Oui, je le sais. C'est arrivé à tout le monde. Pas la peine de se cacher.

Fallait passer LVM ou Btfrs, vous me direz. J'entends bien. Des fois, les planètes s'alignent mal et faut faire avec. Je vous propose d'utiliser une solution radicale pour vous en sortir : supprimer la partition /boot pour la remplacer par un répertoire /boot à la racine.

1. Faire une sauvegarde

On va toucher à ce qui permet à votre serveur de démarrer. Faire une sauvegarde semble être une excellente idée.

2. Sauvegarder /boot

On va commencer par mettre de côté le contenu de la partition /boot :
root@ubuntu:/ mkdir /boot_bkp && cp -R /boot/* /boot_bkp/
On s'en servira plus tard.

3. Commenter le fstab

Comme on en n'a plus besoin, on va dégager l'entrée de /boot dans le /etc/fstab. Les lignes de conf ci-dessous sont des exemples, retenez seulement que les lignes contenant /boot doivent avoir un # devant.
root@ubuntu:/home/user# cat /etc/fstab 
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda3 during installation
UUID=392d55fd-d4e5-4a67-8834-5d29c7toto42 /               ext4    noatime,errors=remount-ro 0       1
# /boot was on /dev/sda2 during installation
#UUID=1b7533ec-96c2-4eef-9eac-b117c0toto42 /boot           ext4    noatime         0       2
# /home was on /dev/sda5 during installation
UUID=7545673f-5c08-4201-9e30-f56d32toto42 /home           ext4    noatime         0       2
# swap was on /dev/sda4 during installation
UUID=9ad39928-283d-43d6-8ee5-98e296toto42 none            swap    sw              0      
De cette façon, la partition ne sera plus montée en cas de redémarrage.

4. Démonter la partition

On va maintenant umount /boot :
root@ubuntu:/home/user# umount /boot
On peut vérifier la disparition de l'ancienne partition avec un simple grep :
root@ubuntu:/home/user# mount | grep boot
Si quelque chose apparaît, c'est que vous n'avez pas démonté la partition. Pensez à sortir de /boot sous peine de vous voir lire un truc du genre « blabla is too busy ! ».

5. Refaire un /boot à la racine

On va maintenant se servir du /boot_bkp créé plus tôt :
root@ubuntu:/home/user# mkdir /boot && cp -R /boot_bkp/* /boot
Ainsi, on se retrouve avec un /boot inutile mais à sa place.

6. Réinstallation de grub

On va lancer la procédure d'installation de grub sur votre disque comme s'il n’était plus là :
root@ubuntu:/home/user# grub-install /dev/sda
Installing for i386-pc platform.
Installation finished. No error reported.
L'installation de grub prend quelques secondes et n'est pas très bavarde. Vous pouvez ajouter l'option -v si vous êtes curieux.

À ce moment précis, tout est en ordre. Vous devriez pouvoir relancer votre machine et mamailler vos kernels comme bon vous semble. J'ajoute tout de même une dernière étape, sait-on jamais ?

7. Mettre à jour grub

On n'est jamais assez prudent, on va donc mettre à jour grub :
root@ubuntu:/home/user# update-grub
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.4.0-47-generic
Found initrd image: /boot/initrd.img-5.4.0-47-generic
Found linux image: /boot/vmlinuz-5.4.0-45-generic
Found initrd image: /boot/initrd.img-5.4.0-45-generic
done

Et voilà ! On se retrouve avec un /boot placé à la racine, avec les répertoire grub/ contenant le grub.cfg qui va bien et tout le reste.

Vous n'avez plus qu'à redémarrer, après avoir fait des backups.

Je me suis mis à l'impression 3D

Rédigé par dada / 11 août 2020 / 13 commentaires


Celles et ceux qui me suivent sur Mastodon ou Pixelfed savent que j'ai franchi le pas : j'ai enfin ma bête à la maison. Je vais vous raconter des trucs, parce que voilà, c'est un monde qu'il est quand-même chouette et qui se rapproche de celui des libristes.

Le choix de la bête

Quand je ne sais pas quoi choisir, je demande de l'aide. Je n'avais pas beaucoup de contraintes : une machine produite en France, avec une entreprise domiciliée en France et de quoi bidouiller sans me ruiner. Quelques toots plus tard, j'étais mis en relation avec des makers qui m'ont trouvé ce que je voulais : Dagoma 3D ! Une entreprise du Nord de la France qui fait des imprimantes 3D. Nickel.

Ne voulant pas d'un truc clé en main, exit la Magis, j'ai donc craqué pour une Disco Ultimate avec l'option écran. Quelques euros en moins (tirés de mon arrêt du tabac) et quelques jours plus tard, je me retrouve avec des petits cartons et beaucoup trop de bobines de PLA :


Je vous laisse parcourir l'album photo dédié à mes délires 3D pour comprendre qu'une imprimante 3D en kit, c'est vraiment un truc en kit. J'ai passé des heures à la monter. Dans ma mémoire, la dernière fois que j'ai autant souffert, c'était pour l'installation de ma première distribution GNU/Linux, Ubuntu 6.06, il y a plus de 14 ans !

Un univers libriste-compatible

J'ai découvert un truc assez fou : le monde de l'impression 3D est assez similaire au monde du logiciel libre.
  • On y retrouve un Github, qui s'appelle Thingiverse.
  • La plupart des imprimantes ont des plans en opensource.
  • Les pièces de rechanges sont imprimables.
  • Il existe un GNU/Linux des imprimantes : Marlin. Ce dernier est forké au bon vouloir des constructeurs.
  • Le logiciel pour préparer les impressions, Cura, est opensource et en python.
En gros, on a le droit d'utiliser, de modifier, d'améliorer et de redistribuer les modifications des outils. Ça ressemble à notre univers, non ?

Anecdote : j'ai cassé une pièce lors de l'assemblage de ma bête. J'ai tout de même réussi à finir le montage, à apprendre à gérer la machine et à imprimer la pièce cassée en allant sur le Github du constructeur. Rien que ça, je trouve que c'est génial.

On en fait quoi, de son imprimante ?

J'ai commencé par imprimer de quoi me servir sereinement d'elle. Une bobine, ça doit bien se dérouler, j'ai donc commencé par imprimer des supports de bobines. C'est simple et ça donne rapidement un résultat. Quoi de plus agréable que de commencer par un truc qui vous allez immédiatement utiliser ?

Ensuite, j'ai commencé par faire des choses pratiques comme un support pour mon téléphone, celui de mon père, de mon frangin, etc.... J'ai ensuite commencé à mêler le geek traditionnel du numérique et mes envies d'impression en sortant un boîtier pour Raspberry Pi :



Franchement, c'est comme une distribution GNU/Linux : vous en faites ce que vous voulez ! Amusez-vous à faire des recherches dans les sites qui regorgent de modèles pour vous rendre compte à quel point c'est fou.

L'autre jour, j'ai fait une recherche avec un modèle précis de plafonnier LED. Il manquait des attaches... Quelques minutes m'ont suffi pour trouver ces attaches modélisées gentiment par un illustre bienfaiteur. J'ai imprimé ça et le souci était réglé.
Dans le genre, j'ai deux disques durs externes en RAID1 branchés au module F de mon Turris Mox pour avoir mon Nextcloud en local. Une recherche rapide et je tombe sur de quoi ne plus les laisser traîner. J'adore.

La prise en main

Se mettre à l'impression 3D n'est pas une chose si facile que ça. C'est un environnement qui a ses codes et ses repères : on parle de slicer, de gauchissement (warping), de STL, de PLA, de Z Offset, skirt, etc. Le vocabulaire est dense.

Une chose que je n'avais pas comprise au départ : c'est le temps d'impression. Bordel que c'est lent ! Compter 30min pour un truc rikiki et une dizaine d'heure pour une pièce élaborée.

C'est aussi un univers riche en modèles : de l'imprimante à 150€ au monstre à 8 000€, il y a des différences. En trouvant la pièce que vous cherchiez sur, disons, cult3d, rien ne dit que vous allez pouvoir l'imprimer avec l'outil que vous avez à la maison. Il faut faire attention !

Comme toute nouvelle activité, il faut se mettre dedans, prendre le temps de se planter, de tester et de garder son calme.

La modélisation

Pour le moment, je continue à beaucoup m'appuyer sur ce que les gens partagent. Je me mets doucement à la modélisation mais c'est épuisant. C'est un monde que je ne connais pas du tout. Tout est à apprendre.

D'abord, il faut choisir son logiciel :
FreeCAD et OpenCAD sont les seuls logiciels libres de la liste. SketchUp ne me plaît pas. J'ai réussi à faire des pieds pour mon Mox avec ThinkerCAD. Ma première pièce conçue, imprimée et utilisée :


 
Ceci-dit, c'est Fusion360 que je vais approfondir. Pourquoi Fusion360 ? Ça semble être l'outil le plus poussé et le plus utilisé. De plus, ils ont pondu une version web qui permet de s'en servir sous Linux.

Des ressources ?

Après les liens fournis tout au long de ce billet, je vous encourage à rejoindre la joyeuse équipe que j'ai découvert sur le salon Matrix Impression3D. Là-bas, vous trouverez un lien vers un superbe pad regroupant tout ce qu'on a trouvé !

J'ai fait de la vidéoprotection

Rédigé par dada / 29 avril 2020 / 1 commentaire


Nan, je déconne ! J'ai fait de la vidéosurveillance. Il faut savoir appeler un chat un chat et je vous redirige vers cet article histoire de bien rigoler. Bref.

La genèse

Après avoir découvert la présence d'excréments sur la terrasse du jardin familial, nous avons déclaré que c'était de la merde de loir. Ni une, ni deux, on installe une cage pour capturer l'animal et le renvoyer chez le voisin plus loin. Il s'est avéré que nous nous sommes plantés et que c'était les rejets d'un hérisson !

Du coup, pour m'amuser, et ayant déjà une partie de la configuration disponible, j'ai décidé de mettre en place un système pour voir la créature se balader.

Le matériel

En photo, ça ne donne pas grand chose mais c'est rigolo :

  • Un Raspberry Pi B de 2011
  • Une webcam USB
  • Une batterie externe de 6 000 mAh
  • Un projecteur avec détecteur de mouvement

Configuration du Raspberry Pi

Raspbian

Pour commencer, installez l’indétrônable Raspbian dans la carte SD de votre Raspberry. Pensez à prendre une carte avec un peu d'espace disque. Ceci dit, ce n'est pas la peine d'en prendre une de 32 ou 64Go si, comme moi, vous utilisez le RPi 1 : cette vieille bête ne permet pas de jouer avec des grosses définitions. Oubliez le 1080p ou le 720p, ça sera bien moins.

Note : J'ai récemment appris que Ubuntu avait enfin une version dédiée au nano-ordinateur. C'est cool mais elle n'est compatible qu'avec les RPi modèles 2 à 4 : mon vieux jouet de 2011 n'est pas supporté.

Motion

Comme plus ou moins tout le monde, c'est Motion que j'utilise. Cet outil permet de détecter des mouvements en analysant, en gros, les changements de couleur des pixels. C'est très simple et très efficace.

Pour l'installer :
apt install motion
Niveau configuration, voici ce que j'ai modifié dans /etc/motion/motion.conf
daemon on
framerate 24
threshold 500
pre_capture 2
post_capture 2
Le fichier est assez long et indigeste. Je n'ai absolument pas tout lu. Si vous voulez en faire le tour, préparez un peu de café.

En faisant mes tests, je me suis rendu compte que si je voulais avoir le meilleur équilibre entre la puissance du RPi et la qualité/fluidité de la vidéo, je devais garder la résolution par défaut (320x240) et passer le framerate à 24. Augmenter l'une ou l'autre de ces variables sur un modèle B non overclockable, c'est mettre la machine à genou très vite.

Niveau détection du mouvement, le hérisson étant une petite créature, j'ai pas mal augmenté la sensibilité de Motion en la passant de 1500 à 500.

Si vous êtes des pros en matière de vidéo, je suis preneur d'info (simples) autour des réglages.

Au passage, je remercie ma nièce et son doudou pour le test grandeur nature de déclenchement de l'enregistrement :


Voyez qu'on ne fait pas de miracle avec ce genre de matos et que ça donne une ambiance flippante à une scène qui ne montre qu'une peluche de chat au bout d'un bambou.

Maintenant que le RPi fonctionne, que Motion tourne quand on le lui demande et que la batterie est chargée, y'a plus qu'à se préparer à allumer le dispositif à la tombée de la nuit. Si j'en crois mes logs, j'ai tout branché à 19h56. D'après ce site, j'ai maximum 7h devant moi.

Et le projecteur ?

L'animal que je cible dort le jour et se déplace de nuit. Ma webcam est toute naze. Du coup, il me faut un truc qui éclaire la zone filmée en cas de passage de la bête. Un petit projecteur avec détecteur de mouvement fait le boulot.  

Un projecteur qui fonctionne sur batterie et une batterie pour le RPi : oui, pas moyen de tirer un câble électrique jusqu'à la zone cible.

Le résultat

On s'en doute, toute cette opération repose sur une chance folle. Et je crois avoir eu de la chance :


C'est mignon, non ? Moi, je suis très fier !

Si on s'amuse à récapituler la chance qu'il a fallu pour avoir 20 secondes d'images floues :
  • La lumière s'est allumée quand le hérisson est passé
  • Motion a bien sauvegardé le passage de la bête
  • La batterie a tenu jusqu'au passage de la cible
  • La webcam posée en équilibre n'est pas tombée
  • Tout ce bordel était au bon endroit
  • Quand la batterie a lâché, l'arrêt brutal du RPi n'a pas corrompu les vidéos
  • Branché peu avant 20h, tout s'est arrêté vers 1h20. Loin des 7h théoriques
Bref. Courage à toutes celles et ceux qui n'ont pas la chance de profiter d'un peu de verdure.

Des bisous

Coronavirus, confinements solidaires

Rédigé par dada / 17 mars 2020 / 1 commentaire


Je relaie modestement la dernière vidéo de DataGueule en espérant que le message touche plus de monde que le coronavirus.




Alors que l’épidémie de coronavirus continue de s’étendre en Europe, il est vital de rappeler un fait essentiel : le COVID-19 ne circule pas de lui-même, ce sont les hommes et les femmes qui le font circuler. Chacune et chacun d’entre nous peut donc agir pour limiter sa propagation et ralentir au plus vite l’engorgement dramatique de nos hôpitaux. La seule action cruciale, nécessairement collective, tient en trois mots : “Restons chez nous”.

Classé dans : / Mots clés : aucun

De l'alerting à base de logs

Rédigé par dada / 12 février 2020 / 2 commentaires


Cela fait un moment que je cherche un moyen de déclencher des alertes à partir d'erreurs spécifiques dans les logs. En fait, ça fait depuis la sortie de Loki que j'en rêve.



Pour rappel, le couple Loki/Promtail, permet de centraliser des logs dans Grafana pour les visualiser calmement plus tard. En gros, ça peut donner un truc comme ça, ou comme ça.
Après avoir mis tout ça en place, je trouvais dommage de ne pas pouvoir continuer l'intégration jusqu'au bout : repérer un message d'erreur dans des logs et transformer l'écran de monitoring en sapin de Noël.

En fait, c'était déjà possible, j'avais juste raté l'information !

Préambule

Ce dont je vais parler dans la suite du billet nécessite d'avoir déjà la stack Loki + Promtail + Grafana + Prometheus + Alert-manager. Ça demande un peu d'huile de coude et de temps mais ça s'installe très bien.

Les Pipelines

Promtail, comme tout exporter, expose des metrics de toute sorte. De base, il fait des choses simples, mais avec les Pipelines, on peut pousser le truc plus loin : ajouter le timestanp à une ligne de log, modifier des labels, ajouter clairement le numéro de ligne du log et, on y est, créer une metric custom !

Créer une metric custom

On va commencer par un exemple très simple :
scrape_configs:
- job_name: system
  static_configs:
  - targets:
      - localhost
    labels:
      job: varlogs
      __path__: /var/log/*log
      hostname: diaspodon.fr
  pipeline_stages:
  - match:
      selector: '{job="varlogs"}'
      stages:
      - regex:
          expression: ".*(?P<error_message>error_message.*)"
      - metrics:
          error_total:
            type: Counter
            description: "total count of errors"
            source: error_message
            config:
              action: inc
Ceci est une partie de la configuration du Promtail en place sur mon serveur Mastodon. Ce n'est pas la plus propre du monde mais ça fera l'affaire.

Le job

On y voit la configuration qui permet de remonter les logs système de /var/log/*.log avec le label varlogs et un hostname forcé :
- job_name: system
  static_configs:
  - targets:
      - localhost
    labels:
      job: varlogs
      __path__: /var/log/*log
      hostname: diaspodon.fr

Le pipeline

On enchaîne ensuite avec le fameux pipeline, que je vais présenter en deux parties : le selector et les metrics 

- La partie selector
  pipeline_stages:
  - match:
      selector: '{job="varlogs"}'
      stages:
      - regex:
          expression: ".*(?P<error_message>error_message.*)"
Le selector permet de s'y retrouver. On va aller chercher à bidouiller les logs du job varlogs, pas ailleurs. Le stage permet de mettre en place une expression régulière en RE2, la version Google est regexp, pour filtrer l'information dont on a besoin.
Ici, je veux qu'une action soit déclenchée à chaque fois que error_message apparaît dans les logs. Celles et ceux qui ont une instance Mastodon savent de quoi je parle. Pour les autres, c'est quand un message ne peut pas atteindre son destinataire. C'est très courant.

- La partie metrics

Pour finir, la partie metrics est carrément celle qui nous intéresse le plus : elle va, comme son nom l'indique, créer une metric qui sera remontée à Prometheus.
      - metrics:
          error_total:
            type: Counter
            description: "total count of errors"
            source: error_message
            config:
              action: inc
On va lire la configuration lentement : La variable error_total sera de type Counter avec la description "total count of errors" et sera alimentée par error_message, défini dans la regexp précédente (entre les <>). De 0, la variable sera incrémentée de 1 à chaque match.

Prometheus

Vérifier la configuration

Vous voyez le truc ? On vient de mettre en place une metric custom qui sera remontée par Promtail vers Prometheus. À l'heure où j'écris ces lignes, cette metric ressemble à ça :
root@diaspodon ~ # curl -s http://localhost:9080/metrics   | grep custom
# HELP promtail_custom_error_total total count of errors
# TYPE promtail_custom_error_total counter
promtail_custom_error_total{filename="/var/log/daemon.log",hostname="diaspodon.fr",job="varlogs"} 92831
promtail_custom_error_total{filename="/var/log/syslog",hostname="diaspodon.fr",job="varlogs"} 50050
On retrouve bien la metric déclarée dans Promtail : error_total, avec son nom complet : promtail_custom_error_total.

Vous me direz que ce n'est pas très joli et vous aurez parfaitement raison. C'est un exemple, juste un exemple !

Mettre en place de l'alerting

Maintenant que vous avez des données dans Prometheus, rédiger une règle d'alerting est assez simple. On devrait s'en sortir avec ce type de chose :
  - alert: Error_total
    expr: promtail_custom_error_total > 1
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Instance {{ $labels.instance }} is invaded by custom errors!"
Simple, rapide, efficace. Si une erreur apparaît, elle sera repérée et une alerte sera déclenchée. Y'a plus qu'à faut qu'on vérifier que votre installation spamme correctement les développeurs pour les mettre sur le coup rapidement.

Pour aller plus loin

Je viens de rapidement parcourir le sujet pour vous donner envie d'y mettre le nez. En l'état, la configuration proposée a un gros problème : une fois qu'une erreur est détectée, le Counter sera incrémenté et rien ne lui permettre de revenir à 0. C'est assez chiant.

J'ai deux façons de contourner le problème : la première avec les développeurs, la deuxième avec ses seuls moyens.

Si les développeurs sont adorables, ils peuvent mettre en place un petit bout de code qui va écrire dans les logs que tout est revenu à la normale. En passant du Counter à une Gauge, on peut dire à Promtail d'incrémenter la metric quand un souci est détecté puis de la décrémenter quand tout redevient fonctionnel. Ça permet de jongler entre 0 et 1 et pas plus.

Par contre, si vous êtes tout seul, vous pouvez tricher en décidant de mettre en place une règle d'alerting qui fait un rate() sur 1h, ou la durée que vous voulez, pour avoir des passages à vide et des périodes de souci. Ça permet d'éviter de passer d'un Counter à une Gauge mais ça demande à mettre un délai de retour au calme long et d'être assidu sur les chan/salon/mail d'alerting.

Bref, c'est encore un point sur lequel je réfléchis. Si vous avez des idées, je prends.

Enfin voilà.

Des bisous