Zigbee2mqtt : Image docker de test basée Gladys v4

Je ne suis pas d’accord, toutes les images que j’ai utilisé jusqu’à maintenant te permette d’utiliser un chemin de persistance différent de chemin officiel.

Le réel problème qu’on a ici c’est de devoir spécifier plusieurs chemin si on utilise un chemin alternatif.

A-t-on vraiment besoin de spécifier un chemin pour la base données, ne peut on pas tout simplement mettre tous les fichiers au sein du conteneur dans un même dossier, ici surement /var/lib/gladysassistant donc fixer la valeur du SQLITE_FILE_PATH (et donc de le supprimer de la config et ensuite simplement demander à l’utilisateur de remplir la valeur PERSISTANCE_FOLDER (par exemple) qui ferait un mapping entre le dossier du conteneur et l’hote ?

La on est dans un cas ou si on veut tester plusieurs images de gladys on doit modifier tous les chemins de la config, le SQLITE_FILE_PATH puis le dossier dans le conteneur et le dossier de mapping sur l’hôte.

Effectivement tout fonctionne bien maintenant, c’est vrai que comme mon message l’indique d’au dessus on soit obligé de changer trois valeurs pour faire ça, mais tous les problèmes sont résolus.

Les deux types d’appareils aquara que j’ai fonctionnent bien, le chemin des fichiers est bien modifié comme il faut et la remontée des infos se fait bien sur le dashboard, bravo pour le taff à tout ceux qui ont bossé sur cette intégration. :slight_smile:

Relis moi, j’ai pas dit que techniquement c’était pas possible. J’ai juste dit qu’on ne peut pas exploser toutes les instances de gladys en production. Car faire ce changement ça pète tout.

Exact cas particulier, pas en production. La commande de @cicoub13 marche parfaitement car tous les paths correspondent.

Bref c’est de l’héritage.

1 « J'aime »

Pourquoi ne pas simplement faire comme l’exposition des ports avec Docker ?
Par exemple, par défaut une application se lance sur le port 3456, mais tu veux exposer le port 80 publiquement, alors tu utilises l’option -p 80:3456.

Pour moi il faut faire pareil dans Gladys : tout est stocké dans le conteneur par défaut dans /var/lib/gladysassistant et la modification du chemin passe par la modification du chemin du conteneur : -v /data/exemple/Gladys:/var/lib/gladysassistant.

Ça me semble plus simple faire et à comprendre !

1 « J'aime »

Bah c’est le cas pour Gladys, le problème n’est pas là.

Il faudrai pourvoir depuis le conteneur récupérer le bind (-v) pour le communiquer aux autres conteneurs. Si on gère ça ça résoud tout.

Objectif: récupérer depuis le conteneur le bind sur /var/lib/gladysassistant

@cicoub13 Je viens de tester rapidement sans allez vraiment au bout un petit bout de js avec la lib qu’on utilise.

var Docker = require('dockerode');
var docker = new Docker({socketPath: '/var/run/docker.sock'});
// ICI on peut remplacer gladys par os.hostname
var container = docker.getContainer('gladys');

 container.inspect(function (err, data) {
         var string = JSON.stringify(data);
         var objectValue = JSON.parse(string);
         console.log(objectValue['HostConfig']['Binds']);
});

Me retourne les mounts standards

[
  '/var/run/docker.sock:/var/run/docker.sock',
  '/var/lib/gladysassistant:/var/lib/gladysassistant'
]

Une petite regex pour récupérer le bind côté host et ça devrai résoudre ce point ?

Pas mal. J’aime bien l’idée. Mais comment je récupère le bon ? Vu qu’on peut monter n’importe quel dossier du host et n’importe quel dossier dans docker (avec SQLITE_FILE_PATH).
Et même monter plusieurs dossiers.

Et ça commence à devenir compliqué :smile:

J’ai envie de dire le sql c’est la db peut importe.

Gladys dans tout les cas ( pour la partie mqtt et zigbee ) doit écrire sa conf dans /var/lib/gladysassystant , là on est dans le conteneur.
En récupérant le bind côté host on peut s’en servir pour créer les autres conteneurs et gérer la persistance.

Mon précédant post n’est pas le bon exemple car je bind le même path. Mais par exemple si je prends le cas de @Albenss

-v /var/lib/z2m-test:/var/lib/gladysassistant

Mon bout de js va retourner

[
  '/var/run/docker.sock:/var/run/docker.sock',
  '/var/lib/z2m-test:/var/lib/gladysassistant'
]

D’ailleurs j’ai tester vite fait une regex ( que j’ai pas réussi à implémenter en js mais c’est pas le sujet :sweat_smile: )

EDIT: regex101 propose un générateur de code pour tester. :expressionless: et ça fait le taf

1 « J'aime »

@VonOx ça me semble bien cette solution :slight_smile: Effectivement, ça éviterait de forcer l’utilisateur à mettre ces données dans /var/lib/gladysassistant sur l’host si il n’a pas ce dossier de dispo.

Seule remarque, côté JS il faudra faire tourner la regex avec le basePath et pas /var/lib/gladysassistant, et on sera bon!

@cicoub13 tu intègre ça à la PR Zigbee2mqtt ?

A part ça, je suis bon pour merger la PR zigbee2mqtt, j’ai vu ta vidéo @cicoub13 et ça dépote! C’est vraiment du beau boulot rien à redire :slight_smile: Congrats à tous ceux qui ont travaillé sur cette PR c’est génial !

Le basepath ? Déso j’ai pas compris

EDIT: Ah le SQLITE_FILE_PATH ?

Je peux aussi faire une PR rapidement pour ajouter la fonction dans la lib/system pour éviter de charger celle de cicoub

EDIT2: Basé sur le getNetworkMode c’est crado car eslint cri un peu mais voilà une base @cicoub13

const get = require('get-value');
const { PlatformNotCompatible } = require('../../utils/coreErrors');
const { exec } = require('../../utils/childProcess');

/**
 * @description Get Gladys host bind folder from docker environment.
 * @returns {Promise} Resolve with host path.
 * @example
 * const getDockerHostFolder = await this.getDockerHostFolder();
 */
async function getDockerHostFolder() {
  if (!this.dockerode) {
    throw new PlatformNotCompatible('SYSTEM_NOT_RUNNING_DOCKER');
  }

  if (!this.dockerHostFolder) {
    const regex = /([\/[\w-]+]*):\/var\/lib\/gladysassistant/gm;
    const cmdResult = await exec('head -1 /proc/self/cgroup | cut -d/ -f3');
    const [containerId] = cmdResult.split('\n');
    const gladysContainer = this.dockerode.getContainer(containerId);
    const gladysContainerInspect = await gladysContainer.inspect();
    const bindPaths = get(gladysContainerInspect, 'HostConfig.Binds');
    const matches = bindPaths.matchAll(regex);
    this.dockerHostFolder = matches[0];
  }

  return this.dockerHostFolder;
}

module.exports = {
  getDockerHostFolder,
};

Oui, utiliser la fonction basePath qu’a fait @cicoub13 dans sa PR qui utilise le SQLITE_FILE_PATH pour trouver le dossier utilisé en interne.

C’est en cours :wink: c’est compliqué de tester tous les cas (plusieurs dockers qui contiennent le mot gladys, pas de volume monté, …)

1 « J'aime »

Faut faire par id ( comme la fonction getnetworkmode)

2 « J'aime »

C’est là où on fait erreur !

En interne ça doit toujours être /var/lib/gladysassistant. ( standard à définir )
Cette variable ( SQLITE_FILE_PATH ) doit être par défaut dans l’image avec ce path.

Là on doit gérer cette variable ( utilisée que pour la db ) et le bind de persistance

Pour la création des conteneurs de service c’est seulement le bind host qui compte , peut importe où est la DB dans le conteneur.

Y’a 2 sujets:

  • Comment gérer les “datas” gladys dans l’image => /var/lib/gladysassistant en standard
  • Comment créer des conteneurs de service qui utilise le même bind host path que gladys => la fonction que je propose ( /???/??? bindé sur /var/lib/gladysassistant )

Non, parce qu’en local sur nos machines, ou hors docker tu veux le mettre ou tu veux !

Après c’est vrai que hors docker ou sur nos machines on fait pas pop des containers du coup

Oui c’est pour ça que j’ai écrit en interne.

La variable doit être définie par défaut dans l’image docker, on a pas à la définir au docker run
Je ne parle pas de la supprimer, elle est utile hors docker effectivement.

Le sujet c’est en environnement docker uniquement.

1 « J'aime »

Effectivement dans l’image docker ça vaudrait le coup de la définir par défaut.

Après, pour ce sujet Zigbee2mqtt, autant ne pas hardcoder le dossier, on se base sur la variable d’environnement comme ça c’est évolutif

Ce que je voulais dire c’est que cette variable définie l’emplacement de la base , qui n’est pas forcément bindé sur le host mais pour lancer les conteneurs de service c’est l’information nécessaire le bind host ( qui peut être complétement différent même si peu probable ). Exploiter cette variable était une mauvaise idée ( de ma part )

EDIT: Et je ne souhaite pas hardcoder nno plus juste récupérer le dossier côté host qui a été défini par l’utilisateur lors de son docker run. C’est le plus safe de mon point de vue

1 « J'aime »

Bon, c’est corrigé. J’ai mis le getContainerMounts dans le core Zigbee2mqtt service by cicoub13 · Pull Request #1098 · GladysAssistant/Gladys · GitHub
et le reste dans mon service.
Dans le futur, peut-être que d’autres services en auraient besoin.

2 « J'aime »

Je n’apporte aucune pierre à votre édifice mais je voulais vous remercier pour tout votre travail !!
Possédant pas mal de matos Aqara mais pas de gateway, je suis super impatient de pouvoir utiliser tout ça.

Merci 1000 fois ! :pray:

1 « J'aime »