Sommaire
- Un peu d'histoire
- Les langages interprétés
- Un cas concret: le miens
- Ma solution : Docker
- En langage compilé
Dans un lien récent sur LinuxFR, j'ai défendu la simplicité de mise en oeuvre de Python par rapport à C++…du moins au moins pour un POC, ou un petit script perso. Mais quand on développe un soft un peu plus complexe, eh bien j'avoue que pour ce qui est de tout le reste, autre que le pur développement, Python perd largement de son intérêt. Ou du moins, un bon langage compilé comme C++ , (je préfère, Rust) y gagne.
Un peu d'histoire
Si l'on a vanté la portabilité de C lors de sa sortie, ce n'est pas parce qu'un programme fonctionne tel quel sur n'importe quel OS/Architecture, mais parce qu'il compile a peu près sans changement, sur toute les architectures/OS. A l'époque, on programmait beaucoup en Assembleur ou alors chaque OS avait son propre langage. En C, on avait, et c'est toujours vrai, qu'a recompiler. Et même s'il peut toujours y avoir une dépendance a l'OS (Appels système) ou à l'Architecture (Big-Endian, Little-Endian), sur un OS/Architecture, on a qu'a vérifier les PATH et librairies… et si elles manque, c'est relativement simple à rajouter. On peut même compiler avec les librairies (empaqueter) (Sauf la libC).
Les langages interprétés
Depuis les premier OS, on a eu besoin de pouvoir lancer des programmes sans paser nécéssairement, par l'étape de compilation. Le premier langage interprété "en live" est le Shell (Bash, pour les Linuxien). L'énorme avantage, pour le développeur, c'est qu'il n'y a plus de risque de segfault (Il y a d'autres risque qui y sont du coup exacerbés, mais ce n'est pas le sujet). Cependant, il introduit un problème: c'est que le programme peut être parfaitement correct mais planter si l'interpréteur n'est pas à jour ou même parfois trop récent s'il n'y a pas de rétro-compatibilité. Et ça, c'est un véritable problème a plus d'un niveau pour le déploiement.
Si ce problème existe pour tout les langage interprété, paradoxalement, c'est quand la gestion des dépendance est trop simplifié et que le langage évolue trop qu'il est exacerbé.
Bash étant quasiment immuable (on peut parfois le déplorer), on a rarement des problèmes de ce type (Mais bien d'autres ;) ).
Pour Java, on galère, souvent avec les dépendances, mais somme toute le problème est assez limité. Comme c'est assez complexe d'ajouter des librairies, on en ajoute assez peu…
Pour Python, à contrario, c'est exacerbé. Comme on a des utilitaires comme PIP, on a trop souvent beaucoup de dépendances en cascades. Évidemment, les dépendances évitent de réinventer la roue. Cependant, pour chacune on a des contraintes sur leurs dépendances, voir sur la version du langage. On peut arriver au final a devoir gérer des dépendances complexes entre dépendances.
Les environnement virtuels, permettent simplement d'éviter les conflits avec les autres dépendances installées sur l'OS, mais on garde la même version du langage.
Un cas concret: le miens
Je développe OpenHEMS, un soft en Python, car c'est simple et que je m'appuie sur Home-Assistant et qu'au départ je voulais me contenter d'un script Home-Assistant. Ce soft intègre en dépendance le code-source (Car ce n'est plus complexe autrement) d'Emhass car ce soft intègre une gestion par IA éprouvé des panneaux solaires. Évidemment, j'ai envie de disposer de la dernière version d'Emhass (pour ne pas avoir les bugs, et les meilleurs fonctionnalités). Seulement, il utilise des fonctionnalités Python 3.10 (Je ne sais plus lesquels) et je souhaites le faire tourner sur une carte Open-Hardware (conformément à ma philosophie Open-Source) : Olinuximo. Seulement, OLinuXino ne propose que Debian 11 (C'est maintenu mais pas le dernier) et avec je n'ai que Python 3.9.
Au départ, j'ai pensé recompilé Python sur l'OS et l'embarqué. Cela me permet de gérer comme je veux mes dépendances. Oui mais voilà, ce n'est pas si simple, la compilation a fonctionné, mais je ne disposait pas de toutes les fonctionnalités. J'ai laissé tombé.
J'avais aussi voulu installé Emhass avec pip, mais le problème était plus grave encore, il m'installait une très ancienne version incompatible car elle avait été mal configuré. Et ce même avec Python3.12.
Ma solution : Docker
La manière la plus simple que j'ai trouvé (et sécurisé sans trop pénaliser les performances) c'est d'utiliser Docker. Mais du coup il faut se lancer dans une compilation docker (Avec Github).
Avec Docker OpenHEMS est beaucoup plus simple tester.
C'est aussi vrai que Docker sécurise OpenHEMS. Cela évite qu'une faille OpenHEMS permette de compromettre l'OS. De ce point de vue, c'est même plus sécurisé que de le faire tourner sous un user dédié. Mais cela coupe de tous les passe droits. Quand le logiciel tourne sous docker, il ne dispose pas de tous les accès à l'OS. Or OpenHEMS utilisait certains passe-droits:
1. Il tournait en root, ce qui me permettait de lancer le VPN pour un accès maintenance. Par sécurité (vie privé et autres), je ne veux pas laisser le VPN tourner en permanence. Je veux que l'utilisateur puisse autoriser manuellement la maintenance. J'ai donc utilisé un process root, un "pseudo-cron" qui se lance avec incron quand un fichier est modifié dans un répertoire spécifique.
2. Les logs étaient directement écris dans le /var/log/openhems, il faut un montage (Mais j'ai encore des problèmes là).
En fait, on peut lancer OpenHEMS sur Python 3.9 sans docker, mais on ne disposera pas de l'option Emhass ce qui est bloquant si l'on dispose de panneaux solaires…
PS : Peut-être n'ais-je pas fait les meilleurs choix. Je suis ouvert aux réflexions en commentaires.
En langage compilé
En langage compilé, (Rust j'aimerai), j'aurais certainement codé moins vite, mais j'aurais été plus rapide sur le déploiement. Concrètement, le problème de dépendance est géré à la compilation et on l'oublie trop souvent. Cette galère que j'ai bien connu en C/C++ évite bien des tracas après.
On ne peut pas dire qu'il n'y ait plus du tout de problème de dépendances. Tout le chalenge des distributions est de géré les conflits de version des librairies dynamiques. C'est tout de même minimisé.
En Python, c'est a un tel niveau que les distributions disposent toujours de Python2 en sus de Python3 (Alors que cela date) et que maintenant, on ne peut plus installer de dépendance avec pip (sur Debian du moins). On a accès qu'aux version disponibles et gérées par les mainteneurs de la distribution.
Commentaires :voir le flux Atomouvrir dans le navigateur