[Pi] Désactiver le HDMI

Je fais fonctionner, depuis presque un mois maintenant, un raspberry pi zero w sur mon balcon, à l’aide d’un panneau solaire et d’une batterie. Au moment de la mise en place, j’ai donc cherché à réduire au maximum l’énergie consommée par le pi.

Après quelques recherches, j’ai trouvé qu’il était possible de désactiver le HDMI, pour une économie estimée à 25 mA. Pour réaliser cette opération de désactivation, on exécute la commande suivante (la ré-activation s’effectue avec l’option -p) :

/usr/bin/tvservice -o

Afin de s’assurer de la persistance de cette configuration en cas de redémarrage, on s’assure également d’ajouter la ligne dans le fichier /etc/rc.local .

Il est également possible de désactiver les leds pour économiser 5 mA par led. Je n’ai en revanche pas testé cette configuration, car je souhaitais pouvoir contrôler visuellement l’état du pi.

Source : Raspberry Pi Zero – Conserve power and reduce draw to 80mA

De l’importance de la sauvegarde dans l’auto-hébergement

Le 29 au soir, mon Pi a fait une petite chute d’une vingtaine de centimètre lorsque le câble d’alimentation s’est pris dans l’un des pieds de ma chaise de bureau. J’ai d’abord cru que la chute avait été sans conséquences. Mais l’allumage d’une LED rouge fixe et l’extinction de la LED verte m’ont rapidement convaincu du contraire.

Après une tentative infructueuse de relancer le serveur, je retire la carte SD du Pi afin de l’examiner et constate une très légère pliure à sa surface. J’extrais la carte, l’insère dans un lecteur afin de vérifier son contenu. Pas de partitions détectées et montées automatiquement. C’est mauvais signe. Je teste un montage manuel, la réponse est sans appel : « mauvais type de système de fichiers, option erronée, superbloc erroné sur /dev/sdg, page de code ou programme auxiliaire manquant, ou autre erreur.« . Par ailleurs, la carte SD est particulièrement chaude au toucher lorsque je la retire du lecteur. Une seule conclusion s’impose, la carte SD est morte.

Je vérifie le contenu de mon fichier .hubic_credentials en local et demande l’état de la chaîne de sauvegarde :

duplicity collection-status cf+hubic://<container> 

Une sauvegarde complète date de la veille (28 janvier), je me lance dans une première récupération locale des données avec :

duplicity restore --force -t now cf+hubic://<container> data

Une fois en possession d’une nouvelle carte SD, j’ai donc réinstallé Raspbian pour pouvoir réinstaller mon serveur. A ce stade, j’ai la chance d’avoir passé plusieurs heures à écrire un script Ansible me permettant de déployer automatiquement mes différents services à partir de la sauvegarde effectuée par duplicity. Tout fonctionne plutôt bien, jusqu’à ce qu’on arrive à la récupération des fichiers sur hubic, où un nombre non négligeable de requête termine en erreur 404 et oblige à relancer le script jusqu’à obtenir une réponse. Pas vraiment de solution de ce côté-là à part changer d’endroit pour le stockage de la sauvegarde. Les requêtes en erreur finissant en général par répondre après un laps de temps aléatoire pouvant aller jusqu’à plusieurs jours. Bref, cette solution n’est pas satisfaisante du tout !

Après pas loin d’une dizaine d’heure de tentative, l’ensemble des fichiers nécessaires à duplicity est finalement disponible en local sur le système d’exploitation tout neuf. C’est le moment de tester les différents services. Wallabag et Shaarli fonctionne directement avec l’ensemble des données accessible. Ce n’est malheureusement pas le cas de Gitea, FreshRSS et Nextcloud.

Petit tour dans les logs de FreshRSS : « Access to database is denied« . J’arrête le service mysql, le redémarre et rafraîchis la page. Bingo ! L’interface s’affiche.

Pour Gitea, le problème se situe également du côté de la base de donnée et le ticket correspondant sur le projet est le numéro 2979 . Après connexion à la base, un simple

 set global innodb_large_prefix = `ON`; 

résous le problème. L’ensemble des données est présent. Pas de perte.

En ce qui concerne Nextcloud, le problème est à chercher du côté de la configuration de la sauvegarde. En effet, en y regardant de plus près, il semble que pour limiter la taille de la sauvegarde, je n’avais configuré que la sauvegarde du dossier data, au moment de la mise en place. En fait, après analyse, il s’avère que c’est bien pire, le dossier semble être présent dans la sauvegarde, mais pas son contenu. Étrange. Rien de catastrophique néanmoins, les données présentes sur mon instance Nextcloud sont toutes synchronisées soit sur mon ordinateur, soit sur mon téléphone, et par ailleurs, l’instance ne contient aucune donnée critique qui n’ait elle-même fait l’objet d’une sauvegarde sur un autre support.

Côté réinstallation, j’ai configuré Nextcloud pour utiliser la base existante réimportée à partir de la sauvegarde. Au passage, j’en ai profité pour faire la mise à jour vers la version 15. Les contacts, les calendriers et les tâches sont revenus à partir de la sauvegarde, j’ai perdu au passage l’enregistrement d’un événement, perte sans conséquence. La sauvegarde étant journalière, les pertes sont très limitées. Pour la partie fichier, c’est plus compliqué, puisque le dossier nextcloud du serveur n’est pas présent dans la sauvegarde. Les fichiers étant présent en totalité sur mon disque dur local, j’ai donc supprimé l’intégralité du contenu sur le serveur via l’interface web et j’ai forcé la synchronisation à partir du contenu local via le client Nextcloud.

Cette mésaventure m’a permis de tester ma procédure de sauvegarde et de déploiement automatisé du serveur et de ses services en conditions réelles. J’ai identifié quelques faiblesses, notamment du côté du système de stockage utilisé par duplicity, à savoir hubic et un problème de configuration du côté de la sauvegarde de Nextcloud. Au passage, pas de perte de données ou d’informations, ce qui est un point plus que positif. A cette occasion, j’en ai également profité pour mettre à jour certaines parties dépréciées de mon script Ansible. Des améliorations sont donc prévues, en particulier pour trouver une alternative correcte à hubic pour stocker les données de sauvegarde.

Préparation du système pour le Pi

Reprise synthétique des informations de la documentation officielle pour l’installation de l’image d’un système d’exploitation pour le Raspberry Pi depuis GNU/Linux.

Première étape:

  • Télécharger Raspbian.
  • Vérifier le hash du zip récupéré.
  • Extraire le fichier image de l’archive ZIP.
  • Lister les supports de stockage connectés avec lsblk.
  • Brancher la carte SD/microSD.
  • Réexécuter lsblk.
  • Noter l’identifiant correspondant de la forme mmcblk0 ou sdX (X, lettre minuscule non accentuée).
  • Si d’éventuelles partitions sur la carte sont montées, les démonter: umount /dev/sdX1.

Place ensuite à l’installation:

dd bs=4M if=2018-03-13-raspbian-stretch.img of=/dev/sdX status=progress conv=fsync

Enfin, exécuter sync afin de s’assurer que l’on peut retirer la carte sans risque.

Pour ma part, j’ajoute une étape supplémentaire consistant à activer SSH par défaut. Pour cela, il suffit de monter la carte et de créer un fichier vide nommé ssh dans la partition boot: sudo touch ssh (point de montage visible dans lsblk. On peut démonter toutes les partitions de la carte ensuite). De cette manière, le Pi devient accessible en SSH avec les identifiants par défaut dès son premier démarrage et on peut ainsi exécuter directement un script Ansible pour le configurer automatiquement.

Sauvegarde du contenu d’une carte SD

J’ai réalisé dernièrement quelques essais d’applications audio compatible Raspberry Pi. En cas de test non satisfaisant, je voulais être en mesure de redéployer aisément l’ancien système. Le site officiel du Raspberry Pi fournit pour ce cas précis de bonnes explications.

Je retiens donc les commandes suivantes permettant de copier le contenu d’une carte SD et de pouvoir le réécrire à l’identique, avec au passage, compression des données pour gagner en espace disque.

Pour sauvegarder :

sudo dd bs=4M if=/dev/mmcblk0 | gzip > pi.img.gz

Et pour déployer la sauvegarde :

gunzip --stdout pi.img.gz | sudo dd bs=4M of=/dev/mmcblk0

En remplaçant bien évidemment /dev/mmcblk0 par le chemin vers la carte SD sur le système hôte.