tag:linuxfr.org,2005:/users/oiseaurochLinuxFr.org : les contenus de oiseauroch2021-04-22T11:42:21+02:00/favicon.pngtag:linuxfr.org,2005:News/404272021-04-18T09:55:08+02:002021-04-18T12:36:17+02:00Créer le paquet Pétrolette pour YunohostLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<div><p>J’ai récemment découvert comment créer un paquet YunoHost avec l’application <a href="https://wbo.ophir.dev/">Whitebophir</a> (présenté ici <a href="//linuxfr.org/news/wbo-un-tableau-blanc-interactif">même</a>. Suite à la <a href="//linuxfr.org/news/petrolette-1-2-5-km-h">dépêche sur Pétrolette</a> et voyant dans les commentaires une <a href="//linuxfr.org/nodes/123765/comments/1847695">demande</a> pour un paquet YunoHost, je me dis que c’est l’occasion.</p>
</div><ul><li>lien nᵒ 1 : <a title="https://yunohost.org" hreflang="fr" href="https://linuxfr.org/redirect/108270">Yunohost</a></li><li>lien nᵒ 2 : <a title="https://linuxfr.org/news/yunohost-des-versions-de-3-0-a-3-3" hreflang="fr" href="https://linuxfr.org/redirect/108271">Une précédente dépèche sur Yunohost</a></li><li>lien nᵒ 3 : <a title="https://github.com/YunoHost-Apps/petrolette_ynh" hreflang="en" href="https://linuxfr.org/redirect/108272">Paquet Yunohost de Pétrolette</a></li><li>lien nᵒ 4 : <a title="https://framagit.org/yphil/petrolette" hreflang="en" href="https://linuxfr.org/redirect/108273">Pétrolette</a></li><li>lien nᵒ 5 : <a title="https://yunohost.org/fr/contribute/packaging_apps" hreflang="fr" href="https://linuxfr.org/redirect/108274">Documentation de Yunohost</a></li><li>lien nᵒ 6 : <a title="https://github.com/YunoHost/example_ynh" hreflang="en" href="https://linuxfr.org/redirect/108275">application d'exemple</a></li></ul><div><h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#toc-pr%C3%A9sentation-de-yunohost">Présentation de Yunohost</a></li>
<li><a href="#toc-installation-de-p%C3%A9trolette-en-local">Installation de Pétrolette en local</a></li>
<li>
<a href="#toc-cr%C3%A9ation-du-paquet-yunohost">Création du paquet YunoHost</a><ul>
<li><a href="#toc-larchitecture">L’architecture</a></li>
<li><a href="#toc-manifestjson">manifest.json</a></li>
<li><a href="#toc-le-dossier-de-configuration">Le dossier de configuration</a></li>
<li><a href="#toc-les-scripts">Les scripts</a></li>
</ul>
</li>
<li><a href="#toc-ajout-au-catalogue">Ajout au catalogue</a></li>
<li><a href="#toc-lint%C3%A9gration-continue">L’intégration continue</a></li>
</ul>
<h2 id="toc-présentation-de-yunohost">Présentation de Yunohost</h2>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f79756e6f686f73742e6f72672f696d616765732f792f752f6e2f6f2f682f79756e6f686f73746c6f676f766572746963616c2d31346536333035392e706e67/yunohostlogovertical-14e63059.png" alt="yunohost" title="Source : https://yunohost.org/images/y/u/n/o/h/yunohostlogovertical-14e63059.png"></p>
<p>Le projet YunoHost a déjà été présenté plusieurs fois sur linuxfr mais pour rappel : </p>
<blockquote>
<p>YunoHost est un système d’exploitation qui vise à simplifier autant que possible l’administration d’un serveur pour ainsi démocratiser l’auto-hébergement tout en restant fiable, sécurisé, éthique et léger. C’est un projet de logiciel libre maintenu exclusivement par des bénévoles. Techniquement, il peut être vu comme une distribution basée sur Debian GNU/Linux et peut s’installer sur de nombreux types de matériel.</p>
</blockquote>
<h2 id="toc-installation-de-pétrolette-en-local">Installation de Pétrolette en local</h2>
<p>Dans un premier temps, on vérifie comment s’installe l’application ciblée et quelles sont les possibilités d’installation. Il faut notamment savoir s’il est possible de : </p>
<ul>
<li>configurer le/les ports de l’application ;</li>
<li>installer l’application sur un sous chemin du domaine ;</li>
<li>installer plusieurs instances de l’application sur la même machine ; </li>
<li>s’installer derrière l’authentification de YunoHost.</li>
</ul>
<p>Dans notre cas, l’application n’a aucun système d’authentification et peut donc se mettre facilement derrière le portail captif de YunoHost. En revanche, on ne peut pas installer l’application dans un sous-répertoire du domaine ni choisir le port de l’application. Ce dernier point empêche donc aussi l’installation de plusieurs instances. Heureusement, une <a href="https://framagit.org/yphil/petrolette/-/merge_requests/2">pull request</a> rapidement acceptée corrige ce dernier point.</p>
<h2 id="toc-création-du-paquet-yunohost">Création du paquet YunoHost</h2>
<p>YunoHost propose une <a href="https://yunohost.org/en/packaging_apps_start">documentation</a> plutôt bien fournie pour créer un nouveau paquet. Un <a href="https://github.com/YunoHost/example_ynh">dépôt d’exemple</a> est aussi disponible comme base de travail. </p>
<h3 id="toc-larchitecture">L’architecture</h3>
<p>Un paquet YunoHost est une collection de scripts bash associés à des templates de configuration suivant une architecture bien définie. À la racine, un fichier <code>manifest.json</code>, un dossier <code>scripts</code> et un dossier de configuration. Un dossier <code>sources</code> peut être ajouté contenant d’éventuels correctif mais n’est pas utile dans notre cas.</p>
<pre><code>├── check_process
├── conf
│ ├── app.src
│ ├── nginx.conf
│ └── systemd.service
├── issue_template
├── LICENSE
├── manifest.json
├── README_fr.md
├── README.md
└── scripts
├── backup
├── _common.sh
├── install
├── remove
├── restore
└── upgrade
</code></pre>
<h3 id="toc-manifestjson">manifest.json</h3>
<p>C’est la définition du paquet, il comprend les informations comme le nom, la description et la licence de l’application ainsi que les informations demandées lors de l’installation. </p>
<p>Dans notre cas, l’application ne s’installe qu’à la racine d’un domaine, donc on demande simplement le domaine où installer l’application et si celle-ci doit être accessible publiquement.</p>
<pre><code>{
"name": "Petrolette",
"id": "petrolette",
"packaging_format": 1,
"description": {
"en": "The news reader that doesn't know you",
"fr": "La page d'actu qui ne sait rien de toi"
},
"url": "https://framagit.org/yphil/petrolette",
"version": "1.2.5~ynh1",
"license": "GPL-3.0-only",
"maintainer": [{
"name": "oiseauroch.",
"email": "xxx@xx.xx"
}],
"requirements": {
"yunohost": ">= 4.1.0"
},
"multi_instance": true,
"services": [
"nginx"
],
"arguments": {
"install" : [
{
"name": "domain",
"type": "domain",
"example": "domain.org"
},
{
"name": "is_public",
"type": "boolean",
"default": true,
"help" : {
"fr" : "Cette page sera accessible par n'importe qui. En revanche, la configuration reste personnelle",
"en" : "The page will be accessible by anyone."
}
}
]
}
}
</code></pre>
<h3 id="toc-le-dossier-de-configuration">Le dossier de configuration</h3>
<p>Celui-ci contient au moins un fichier <code>app.src</code> contenant l’adresse et le checksum de l’application. Il contient aussi les templates de configuration. YunoHost utilise nginx comme reverse-proxy et DBus pour le lancement des applications. Il faut donc au minimum un template pour nginx et un pour systemd.</p>
<h3 id="toc-les-scripts">Les scripts</h3>
<p>Écrits en bash, les scripts permettent d’effectuer les opérations (installation, suppression, sauvegarde…) sur l’application. Afin de simplifier la vie du mainteneur et de normaliser ces opérations, YunoHost mets à disposition de nombreux <a href="https://yunohost.org/en/packaging_apps_helpers">helper</a>.</p>
<p>Pour notre script <code>install</code> par exemple, on va dans un premier temps sourcer notre helper ainsi que ceux de YunoHost et s’assurer de retourner dans un état stable en cas d’erreur.</p>
<pre><code>source _common.sh
source /usr/share/yunohost/helpers
# Exit if an error occurs during the execution of the script
ynh_abort_if_errors
</code></pre>
<p>Ensuite, on récupère les arguments du manifest. Ceux-ci sont nommés par convention <code>$YNH_APP_ARG_NOM-DANS-LE-MANIFEST</code>. On définit aussi le chemin de l’application pour l’instant en dur étant donné qu’il ne peut s'installer qu’à la racine. Les variables <code>domaine, is_public, app et path_url</code> sont aussi des conventions qu’il convient de respecter parce qu’elles sont recherchées par défaut dans certains helpers.</p>
<pre><code>domain=$YNH_APP_ARG_DOMAIN
is_public=$YNH_APP_ARG_IS_PUBLIC
app=$YNH_APP_INSTANCE_NAME
path_url="/"
</code></pre>
<p>Vient après la définition du dossier de l’application appelé <code>final_path</code> lui aussi par convention. YunoHost m’indique que pour une application possédant un serveur web, le chemin est par défaut <code>/opt/yunohost/$app</code>. Cette opération étant la première à pouvoir prendre du temps, on indique un message de log qui sera visible pendant d’installation.</p>
<pre><code>ynh_script_progression --message="Validating installation parameters..."
final_path=/opt/yunohost/$app
test ! -e "$final_path" || ynh_die --message="This path already contains a folder"
# Register (book) web path
ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url
</code></pre>
<p>Yunohost stocke les informations d’installation des applications dans le dossier <code>/home/yunohost.conf</code> sous forme de yaml. Bien entendu, on n’édite pas nous-mêmes ces fichiers, mais on passe par d’autres helpers.</p>
<pre><code>ynh_script_progression --message="Storing installation settings..."
ynh_app_setting_set --app=$app --key=domain --value=$domain
ynh_app_setting_set --app=$app --key=path_url --value=$path_url
</code></pre>
<p>YunoHost utilise un utilisateur différent pour chaque app installée, créons-le.</p>
<pre><code># Create a system user
ynh_system_user_create --username=$app --home_dir=$final_path
</code></pre>
<p>Viennent les parties plus spécifiques à notre application. Notre application utilise son propre serveur web, donc on cherche un port disponible (deux dans notre cas) puis on installe les dépendances. Pétrolette se base sur nodejs qui est une dépendance fréquente. YunoHost propose donc un helper spécifique pour gérer les différentes versions de node et appeler la bonne pour chaque application.</p>
<pre><code># Find an available port
port=$(ynh_find_port --port=8001)
https_port=$(ynh_find_port --port=8002)
ynh_app_setting_set --app=$app --key=port --value=$port
ynh_app_setting_set --app=$app --key=https_port --value=$https_port
ynh_install_nodejs --nodejs_version=$NODEJS_VERSION
</code></pre>
<p>Nous en sommes à l’installation proprement dite. Pétrolette utilise bower qui stocke des informations dans le répertoire de l’utilisateur courant. L’installation étant réalisée en root, il faut changer son répertoire pour stocker ces informations dans le répertoire de l’application.</p>
<pre><code>ynh_app_setting_set --app=$app --key=final_path --value=$final_path
ynh_setup_source --dest_dir="$final_path"
pushd $final_path
# use custom home value to avoid bower storing values in root and have right errors
TMP_HOME=$HOME
HOME=$(pwd)
ynh_use_nodejs
ynh_npm install
HOME=$TMP_HOME
popd
chown -R $app:$app $final_path
chmod -R o-rwx $final_path
</code></pre>
<p>Pour finir, on s’occupe de l’intégration à YunoHost. On applique le template de Nginx et D-bus et on l’intègre au portail captif. C’est là qu’on est heureux d’avoir respecté les conventions pour les noms de variables, on a ainsi qu’à lister nos variables spécifiques à remplacer.</p>
<pre><code>ynh_add_nginx_config
yunohost service add $app --description="The news reader that doesn't know you" --log="/home/yunohost.app/${app}/storage/logs/petrolette.log"
ynh_add_systemd_config --others_var="port ynh_node_load_PATH"
ynh_systemd_action --service_name=$app --action=start --log_path=systemd
if [ $is_public -eq 1 ]
then
# unprotected_uris allows SSO credentials to be passed anyway.
ynh_permission_update --permission="main" --add="visitors"
fi
ynh_systemd_action --service_name=nginx --action=reload
</code></pre>
<p>Notre script est terminé. Les autres scripts suivent le même principe. On remarque que, dans notre cas, une grande partie de notre script est générique. On se dit donc qu’une bonne partie est encore automatisable mais toutes les applications ne sont pas aussi simples à installer et le projet s’améliore continuellement sur ce point. </p>
<h2 id="toc-ajout-au-catalogue">Ajout au catalogue</h2>
<p>Maintenant que notre paquet est fait, il serait bon qu’il apparaisse dans la liste de YunoHost. Pour cela, on lance une pull request sur le dépôt <a href="https://github.com/YunoHost/apps">yunohost/apps</a> avec les informations concernant notre application. On peut aussi demander à intégrer notre application à l’organisation YunoHost-Apps.</p>
<pre><code> "Petrolette": {
"branch": "master",
"revision": "HEAD",
"url": "https://github.com/YunoHost-Apps/petrolette_ynh",
"state": "working"
}
</code></pre>
<h2 id="toc-lintégration-continue">L’intégration continue</h2>
<p>Afin d’assurer une certaine qualité des applications, YunoHost a mis en place un système d’intégration continue. Celui-ci teste un certain nombre de scénarios : (installation, suppression, sauvegarde, restauration, installation dans un sous-dossier…) pour valider le bon fonctionnement de notre application. Cependant, certaines applications ne supportent pas tous les tests lancés par l’intégration continue. On écrit donc un fichier <code>check_process</code> qui spécifie quels tests doivent être effectués.</p>
<p>Voici notre liste de tests :</p>
<pre><code>;; Test complet
; Checks
pkg_linter=1
setup_sub_dir=0
setup_root=1
setup_nourl=0
setup_private=1
setup_public=1
upgrade=1
backup_restore=1
multi_instance=1
port_already_use=0
change_url=0
</code></pre>
<p>Une intégration continue de test est disponible et peut être lancée via un commentaire <code>!testme</code> dans une pull request. L’intégration continue de production est quant à elle automatiquement lancée et mise à jour le vendredi.</p>
</div><div><a href="https://linuxfr.org/news/creer-le-paquet-petrolette-pour-yunohost.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/123988/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/creer-le-paquet-petrolette-pour-yunohost#comments">ouvrir dans le navigateur</a>
</p>
oiseaurochXavier TeyssierYsabeau 🧶 🧦Benoît Sibaudpalm123https://linuxfr.org/nodes/123988/comments.atom