Add a Makefile to bare build Duniter
Lié au ticket #1405 (closed), voici un Makefile pour fabriquer la version « nue » de Duniter.
Merge request reports
Activity
Merci @sveyret :)
added 7 commits
-
43090d4b...584a9cbd - 4 commits from branch
dev
- 9b3b2520 - Add bare build Makefile
- 0476dcf2 - Use Makefile in build-*
- d76feeb1 - Use Makefile in Dockerfile
Toggle commit list-
43090d4b...584a9cbd - 4 commits from branch
Je pense avoir terminé @librelois, mais je n'ai pas réussi à monter un environment adéquat pour comparer les résultats entre l'ancienne méthode et la nouvelle.
Je voulais récupérer le résultat du CI, mais il semble ne pas réussir à le publier. Est-ce que tu peux me dire comment récupérer l'image Docker de test et un paquet v1.8 fabriqué avec l'ancienne méthode ? Et si tu as une idée de pourquoi les paquets que je fabrique ne se chargent pas dans la CI…
@sveyret l'image docker est publiée sur notre registry sous le tag test-image, tu peut la récupérée ainsi:
registry.duniter.org/nodes/typescript/duniter:test-image
C'est un registry public en lecture, ça devrait marcher sans droits particuliers.
Par contre je pense que l'image docker ne fonctionnera pas, car tu a supprimé le flag
RUSTFLAGS="-C target-feature=-crt-static"
qui est essentiel pour que le binaire Rust fonctionne sous Alpine.Concernant le résultat de la CI, s'il ne publie pas c'est parce que les artifacts générés sont trop gros, il faudrait que tu supprime les binaires intermédiaires et autres fichiers objets liés la compilation de leveldb et sqlite.
added 7 commits
-
31d2de70...097a1381 - 4 commits from branch
dev
- ec7a771a - Add bare build Makefile
- b196b9ba - Use Makefile in build-*
- c73a4cef - Use Makefile in Dockerfile
Toggle commit list-
31d2de70...097a1381 - 4 commits from branch
changed milestone to %1.8
@librelois, je vois aussi que le livrable ne contient pas du tout de répertoire
neon
. Est-ce qu'il peut être totalement supprimé après la génération du livrable ?added 2 commits
added 8 commits
-
9eb8d987...d609cd9a - 5 commits from branch
dev
- 964ed1d3 - Add bare build Makefile
- 0eef0c7e - Use Makefile in build-*
- fbd7a333 - Use Makefile in Dockerfile
Toggle commit list-
9eb8d987...d609cd9a - 5 commits from branch
added 8 commits
-
9eb8d987...d609cd9a - 5 commits from branch
dev
- 964ed1d3 - Add bare build Makefile
- 0eef0c7e - Use Makefile in build-*
- fbd7a333 - Use Makefile in Dockerfile
Toggle commit list-
9eb8d987...d609cd9a - 5 commits from branch
@librelois ça m'a l'air bon maintenant. J'ai fait quelques tests rapides, mais il serait bien que des tests plus poussés soient fait, si tu as du temps pour ça…
Est-ce que ton RPi4 est en 64 bits ?
C'est pour savoir si je peux considérer l'arm64 comme valide sur le paquet Gentoo.
Edited by Stéphane Veyret@librelois, lorsque j'essaie de démarrer la version bureau nue (sans toute la mise en paquet qu'il y a autour), j'ai le message « The server is not starting ». Tu as une idée de la raison ?
@librelois, autre question: pourquoi est-ce qu'on installe
nw
en tant que dépendance de duniter juste pour la compilation, puis qu'on le télécharge ensuite pour la livraison ? Ne pourrait-on pas se contenter de la version installée parnpm
?Est-ce que ton RPi4 est en 64 bits ?
Mon rpi4 a un processeur 64 bits mais un OS 32 bits : voir ici pourquoi c'est ainsi par défaut : https://www.raspberrypi.org/forums/viewtopic.php?t=252369
Comme il me sert de test pour le livrable dédié aux utilisateurs sous rpi3 et autres micro ordinateur sous architecture armv7l, je compte le laisser sur l'os 32 bits présent par défaut.
Donc l'arm64 je ne peut pas te dire si c'est valide ou non.
lorsque j'essaie de démarrer la version bureau nue (sans toute la mise en paquet qu'il y a autour), j'ai le message « The server is not starting ». Tu as une idée de la raison ?
Non aucune, tout ce qui est relatif a la version desktop c'est cgeek qui a mis ça en place, il faut demander à @c-geek
pourquoi est-ce qu'on installe
nw
en tant que dépendance de duniter juste pour la compilation, puis qu'on le télécharge ensuite pour la livraison ? Ne pourrait-on pas se contenter de la version installée parnpm
?Il me semble que
nw
est nécessaire au runtime pour la version desktop justement, mais je me trompe peut-être, @c-geek peut tu nous éclairer ? :)Donc l'arm64 je ne peut pas te dire si c'est valide ou non.
Pas de soucis. Si quelqu'un m'indique que c'est valide, je modifierai le paquet Gentoo à ce moment là.
Il me semble que
nw
est nécessaire au runtime pour la version desktopC'est le cas, mais j'arrive à démarrer avec la version installée par
npm
, donc je me demandais pourquoi télécharger en plus une version autonome…Bon, je suis en train de m'arracher les cheveux pour ma version nue. Je pense avoir retiré tout ce qui est bundled dans la version générée, et tout fonctionne bien. J'ai l'impression que j'ai bien les mêmes fichiers que dans la version nue. Et pourtant, le serveur de la version nue ne démarre pas…
j'arrive à démarrer avec la version installée par
npm
, donc je me demandais pourquoi télécharger en plus une version autonome…Bonne question, il devait y avoir une bonne raison pour laquelle @c-geek a fait comme ça a l'époque :)
Et pourtant, le serveur de la version nue ne démarre pas…
Mince, même la variante server ? Je croyais que tu n'avais des problèmes qu'avec la variante desktop ?
Le paquet deb server buildé par la CI fonctionne bien chez moi.
J'ai également buildé un paquet deb pour armv7l sur mon rpi4 et il semble bien fonctionner sur mon rpi4 :)
Edited by ÉloïsIl me semble que
nw
est nécessaire au runtime pour la version desktop justement, mais je me trompe peut-être, @c-geek peut tu nous éclairer ? :)Oui
nw
est nécessaire au runtime de la version Desktop. Par contre pournw-gyp
c'est plutôt au runtime a priori.lorsque j'essaie de démarrer la version bureau nue (sans toute la mise en paquet qu'il y a autour), j'ai le message « The server is not starting ». Tu as une idée de la raison ?
C'est que la partie serveur crashe.
Quand on lance la commande
duniter-desktop
depuis un poste Debian, c'est en réalité/opt/duniter/nw
qui est lancé avec les paramètres définis dans/opt/duniter/package.json
à savoir :"main": "index.html", "node-main": "./bin/duniter"
Autrement dit :
- la partie front va être lancée via nw + le fichier index.html ==> cette partie fonctionne bien chez toi @sveyret
- la partie back va être lancée via un NodeJS embarqué par NW (fichier
/opt/duniter/lib/libnode.so*
).
Pour savoir ce qui plante, c'est un peu casse-tête car il n'y a pas de logs tous faits. Il te faut le produire en modifiant un peu de code JS. Mais dans 99% des cas c'est une librairie écrite en C/C++, et probablement aussi en Rust.
Ma méthode (utilisée de nombreuses fois pour Windows car c'était la plateforme la plus capricieuse vis-à-vis du code compilé) :
- Editer le fichier
/opt/duniter/bin/duniter
- Remplacer son contenu en ajoutant des
require("fs").writeFileSync('/tmp/etape1', 'Debug-message')
aux étapes clés du lancement. Exemple :
#!/usr/bin/env node "use strict"; require("fs").writeFileSync('/tmp/etape1', 'Avant import des ExitCodes') // Test 1 const ExitCodes = require("../app/lib/common-libs/exit-codes").ExitCodes; require("fs").writeFileSync('/tmp/etape2', 'Avant import de NewLogger') // Test 2 const logger = require("../app/lib/logger").NewLogger(); // Specific errors handling process.on('uncaughtException', (err) => { // Dunno why this specific exception is not caught if (err.code && err.code !== "EADDRNOTAVAIL" && err.code !== "EINVAL" && err.code !== "ENOENT") { logger.error(err.stack || err.message || err); process.exit(ExitCodes.UNCAUGHT_EXCEPTION); } }); (async () => { try { require("fs").writeFileSync('/tmp/etape3', 'Avant autoStack') // Test 3 const stack = require('../index').Statics.autoStack(); require("fs").writeFileSync('/tmp/etape4', 'Avant executeStack') // Test 4 await stack.executeStack(process.argv); require("fs").writeFileSync('/tmp/etape1', 'Apres executeStack') // Test 5 // Everything went well, close Duniter quietly. process.exit(ExitCodes.OK); } catch (e) { require("fs").writeFileSync('/tmp/etape_error', e && e.message || e) // Erreur // If an unhandled error occured logger.error(e.stack || e.message || e); process.exit(ExitCodes.UNHANDLED_ERROR); } finally { // If we did not succeed to close before, force close with error. process.exit(ExitCodes.FORCE_CLOSE_AFTER_ERROR); } })()
Avec l'exemple ci-dessus tu auras déjà un début de réponse avec les six logs d'étape/erreur.
Je n'ai pas plus pratique à proposer. Par contre, cette méthode fonctionne à 100%.
Edited by Cédric MoreauPour observer ce qui s'est passé :
$ ll /tmp/etape* -rw-rw-r-- 1 cgeek cgeek 26 mai 10 16:21 /tmp/etape1 -rw-rw-r-- 1 cgeek cgeek 25 mai 10 16:21 /tmp/etape2 -rw-rw-r-- 1 cgeek cgeek 15 mai 10 16:21 /tmp/etape3 -rw-rw-r-- 1 cgeek cgeek 18 mai 10 16:21 /tmp/etape4
Ici, je n'ai eu aucun problème et Duniter fonctionne.
Si tu as eu une erreur, tu n'auras peut-être pas été jusqu'à l'étape 4 voire tu auras eu la production d'un fichier
/tmp/etape_error
.Edited by Cédric MoreauJe n'ai pas compris la question
Actuellement, on télécharge (avec curl) une version de NW, mais lors de la compilation, on utilise une version installée par
npm install nw
. J'ai essayé de démarrer le bureau en utilisant cette dernière version, et cela fonctionne aussi bien. Ce que je me demandais, du coup, c'est est-ce qu'on ne pourrait pas ne plus télécharger NW et se contenter de la version installée parnpm
.Si tu as eu une erreur, tu n'auras peut-être pas été jusqu'à l'étape 4
Non, cela s'arrête à l'étape 2 et je n'ai pas d'erreur…
Il faudrait que j'en sache un peu plus sur NW. Sur Gentoo, je peux parfaitement installer la bonne version avec
npm install nw@0.33.1
, mais je ne peux pas vraiment controller la version de node que l'utilisateur souhaite utiliser. Peut-on trouver automatiquement la version ADDON_VERSION utilisée par la version de node ?Je pense que c'est un problème de compatibilité :
Error: /home/stephane/Developpements/duniter/work/neon/native/index.node: undefined symbol: _ZN2v82V818GlobalizeReferenceEPNS_8internal7IsolateEPm at Object.Module._extensions..node (internal/modules/cjs/loader.js:760:18) at Module.load (internal/modules/cjs/loader.js:623:32) at tryModuleLoad (internal/modules/cjs/loader.js:562:12) at Function.Module._load (internal/modules/cjs/loader.js:554:3) at Module.require (internal/modules/cjs/loader.js:661:17) at require (internal/modules/cjs/helpers.js:20:18) at Object.<anonymous> (/home/stephane/Developpements/duniter/work/neon/lib/index.js:3:16) at Module._compile (internal/modules/cjs/loader.js:713:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:730:10) at Module.load (internal/modules/cjs/loader.js:623:32)
Oui c'est possible, cela peut revenir au même si le
nw
téléchargé par npm est identique. Par contre je ne vois aucune instructionnpm install nw
dans les procédures de livraison, donc je ne sais pas comment tu l'obtiens.Non, cela s'arrête à l'étape 2 et je n'ai pas d'erreur…
C'est typique d'un crash au chargement d'une des libraires compilées. Quand on regarde le fichier
app/lib/logger.js
, on voit que lui même importeapp/lib/system/directory.js
qui lui-même charge des dépendances à SQLite et LevelDB, qui sont compilés.Le plus probable c'est que ces librairies n'ont pas été compilées pour nw comme c'est réalisé par la CI :
npm install -g node-pre-gyp || exit 1 # [...] nw_compile() { [[ -z ${1} ]] && exit 1 cd ${1} || exit 1 node-pre-gyp --runtime=node-webkit --target=${NW_VERSION} configure || exit 1 node-pre-gyp --runtime=node-webkit --target=${NW_VERSION} build || exit 1 [[ -z ${2} ]] || ${2} ${1} ${3} cd .. } # [...] cd "${RELEASES}/desktop_/node_modules/" nw_compile leveldown nw_copy "build/Release/" nw_compile sqlite3 nw_copy_node
Edited by Cédric MoreauOui complètement, l'ABI de Node 8 n'est pas celle de Node 9, et même au sein d'une même version majeure il y a des modifications d'ABI.
Pour plus de tests :
sudo sed '16 a require("fs").writeFileSync("/tmp/etape2.1", "Chargement SQLite")' app/lib/system/directory.js -i sudo sed '18 a require("fs").writeFileSync("/tmp/etape2.2", "Chargement CFS")' app/lib/system/directory.js -i sudo sed '22 a require("fs").writeFileSync("/tmp/etape2.3", "Chargement LevelDB")' app/lib/system/directory.js -i sudo sed '24 a require("fs").writeFileSync("/tmp/etape2.3", "Chargement LevelDB OK")' app/lib/system/directory.js -i
Résultat :
$ ll /tmp/etape* -rw-rw-r-- 1 cgeek cgeek 26 mai 10 17:06 /tmp/etape1 -rw-rw-r-- 1 cgeek cgeek 25 mai 10 17:06 /tmp/etape2 -rw-rw-r-- 1 cgeek cgeek 17 mai 10 17:06 /tmp/etape2.1 -rw-rw-r-- 1 cgeek cgeek 14 mai 10 17:06 /tmp/etape2.2 -rw-rw-r-- 1 cgeek cgeek 21 mai 10 17:06 /tmp/etape2.3 -rw-rw-r-- 1 cgeek cgeek 15 mai 10 17:06 /tmp/etape3 -rw-rw-r-- 1 cgeek cgeek 18 mai 10 17:06 /tmp/etape4
Ça s'arrête en étape 2.1 pour moi.
@c-geek, du coup, comment est-ce que je peux gérer automatiquement la compilation si je ne connais pas la version de node utilisée, et que je ne contrôle que la version de nw ?
Oui je pense, étant donné qu'à une version de NW correspond une version de Node. Voir titre de chaque release. Exemple :
[2018/09/11] - NW.js v0.33.1 Released with Node.js v10.10.0
Ce qui explique dans le contenu du script
build-lin.sh
qu'on retrouve ces valeurs :ADDON_VERSION=64 # Correspond au n° de version d'addon généré pour NW en version 0.33.1 NW_VERSION=0.33.1 # Car NW 0.33.1 embarque NodeJS 10.10.0 qui a un n° de version d'addon `64`
Mais en fait tout ça est géré par l'instruction :
node-pre-gyp --runtime=node-webkit --target=${NW_VERSION} configure || exit 1 node-pre-gyp --runtime=node-webkit --target=${NW_VERSION} build || exit 1
D'ailleurs cette commande doit générer un livrable dont l'ABI (matérialisée par un numéro de version d'addon) doit être
64
, comme matérialisé par le${ADDON_VERSION}
dans le script :nw_copy() { # [...] local dest=lib/binding/Release/node-v${ADDON_VERSION}-linux-x64 # [...] } # [...] ADDON_VERSION=64
Autrement dit, tu peux vérifier la version d'addon générée par les outils que tu utilises en vérifiant le nom du fichier présent dans lib/binding/Release/ de chaque module requérant compilation (SQLite, LevelDB).
Par contre, pas sûr que tu puisses utiliser autre chose que les versions ci-dessus (ça peut marcher mais je n'ai pas testé).
Edited by Cédric MoreauJustement, dans la nouvelle procédure, j'ai repris ces instructions, mais j'ai vu qu'il avait généré à la fois un node-v64-linux-x64 et un node-v72-linux-x64. Je vais essayer de comprendre pourquoi et si je peux m'en sortir. Sinon, tant pis, les Gentoo-istes vont m'en vouloir, mais la version Gentoo sera une version purement binaire récupérée de la génération automatique du CI.
@sveyret non je pense pas car c'est SQLite qui plante.
comment est-ce que je peux gérer automatiquement la compilation si je ne connais pas la version de node utilisée
@sveyret tu ne peut pas, ne serait ce qu'a cause du code Rust. En effet, le binaire Rust (
neon/native/index.node
) est compilé pour une version de node spécifique. La version de node utilisée au runtime doit être strictement la même que celle utilisée lors de la compilation, ce n'est pas possible de faire autrement car Neon ne supporte pas la N-api.Edited by ÉloïsSi j'ai bien compris, neon (qui fait partie de rust ?) compile également un certain nombre de choses. Mais neon ne va pas utiliser la même version de node que celle fournie pas NW… Je me demande si ce n'est pas de là qui viendrait le problème…
Neon sert à compiler du code Rust sous un format binaire utilisable par NodeJs, Neon compile pour la version de node sélectionnée par nvm (ou à défaut, la version de node installée sur le système).
Edited by ÉloïsOK, donc, si j'ai bien compris, sur mon poste (qui est en node v12), neon va compiler un certain nombre de choses en v12, tandis que nw, en version 0.33.1 compile pour du v10. Du coup, j'ai des versions compilées en conflit. Dans l'idéal, il faudrait que je force neon a utiliser la version de nw, mais ça me semble difficile, d'autant que neon a déjà terminé sa compilation lorsque l'on ajoute nw.
Tant pis, si je ne peux pas forcer node 10, j'utiliserai une version binaire de duniter pour Gentoo. Ça veut dire que l'objectif initial de ce Makefile n'est pas atteint, mais ce n'est pas grave, cela pourra peut-être servir plus tard.
Merci à vous deux pour votre aide. Je vais encore faire quelques corrections, notamment pour utiliser le nw ajouté par npm, ça évitera les conflits de version, puis ça sera bon pour moi.
@librelois c'est bon pour moi…
Pour Gentoo, je pense que je ferai 2 versions, l'une en source imposant node 10, l'autre en binaire n'imposant rien.
@librelois zut, je n'aurai pas dû lancer les derniers tests, ils échouent systématiquement en timeout. Tu as moyen de fusionner quand même où tu veux que je pousse une nouvelle version ?
@sveyret oui je peut fusionner quand même mais je ne vais pas le faire ce soir, c'est un changement lourd de conséquence, j'aimerais tester les livrables docker et desktop de mon coté, ce qui va me demander un peu de temps.
Ne t'inquiète pas, je ne sortirai pas la version 1.8 sans avoir mergé cettte MR ;)
Edited by ÉloïsQuelques tests supplémentaires ne seraient effectivement pas de trop !
Pour info :
- je n'ai pas pu tester la dernière version de Docker car celle qui est disponible est toujours celle d'hier et je ne sais pas pourquoi elle ne se met pas à jour, même si je suis plutôt confiant puisque les dernières modifications ne concernent pas Docker ;
- je n'ai pas testé les paquets Debian non plus, même si leur contenu n'a pas dû changer avec les dernières modifications.
Merci, bonne fin de weekend…
Edited by Stéphane Veyret@sveyret le paquet deb desktop ne fonctionne pas, ça plante à l'installation du paquet (script postinst):
Paramétrage de duniter-desktop (20200510.1706.51) ... chmod: impossible d'accéder à '/opt/duniter//locales': Aucun fichier ou dossier de ce type
Je pense que tu supprime trop de truc, la version desktop a besoin du dossier
locales
.added S-waiting author label
@librelois Voilà, j'ai un peu modifié la procédure. Les
chmod
ne sont pas nécessaires parce que le.zip
conserve les droits adéquats. J'ai également modifié la fabrication du zip pour qu'il conserve les liens symboliques. Et j'ai créé un nouveau script pour démarrerduniter-desktop
. Mes tests (manuels, je n'ai pas de Debian sous la main) ont réussis.removed S-waiting author label
@sveyret le lanceur de la version desktop ne fonctionne plus du coup. Il faut que tu modifie le fichier
release/extra/debian/package/DEBIAN/postinst
pour créer le bon lien symbolique, faut remplacer la ligne 17 :ln -s $DUN_SOURCES/nw /usr/bin/duniter-desktop
par
ln -s $DUN_SOURCES/duniter-desktop /usr/bin/duniter-desktop
Edited by Éloïs@sveyret en fait tu avais déjà modifié le lien symbolique dans postinst, mais tu avais oublié de modifier la condition permettant de détecter que l'on est dans le cas "desktop", je viens de corriger ce détail moi-même et de merger ta branche, merci beaucoup pour cette excellente contribution :)
ps: J'ai mergé manuellement après un rebase, c'est pour cela que gitlab n'arrive pas a détecté que la MR a été mergée, mais ton code est bien sur la branche dev.
Edited by Éloïs@librelois super, merci pour tes tests (et corrections finales) !