<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>@mbarberot 🐿️</title>
  <link href="https://mbarberot.gitlab.io/feed.xml" rel="self"/>
  <link href="https://mbarberot.gitlab.io/"/>
  <updated>2023-10-25T12:00:00Z</updated>
  <id>https://mbarberot.gitlab.io/</id>
  <author>
    <name>Mathieu Barberot</name>
  </author>
  
  <entry>
    <title>Installer un Raspberry Pi avec Docker</title>
    <link href="/posts/install-raspberry-pi-with-docker/"/>
    <updated>2019-04-08T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/install-raspberry-pi-with-docker/</id>
    <content type="html">&lt;p&gt;Après avoir bien pris la poussière, j&#39;ai enfin décidé de (re)faire quelque chose de mon Raspberry Pi.
A l&#39;origine, le Pi a été développé pour libérer le pouvoir créatif, mais j&#39;ai toujours été rebuté par la maintenance d&#39;un serveur Linux et le bazar que générait l&#39;installation des bases de données, serveurs et autres outils.&lt;/p&gt;
&lt;p&gt;Heureusement, maintenant nous avons les conteneurs ! Ils sont parfait pour expérimenter tout un tas de choses sans polluer la machine.
J&#39;ai donc choisi d&#39;utiliser une distribution &lt;em&gt;Raspbian Lite&lt;/em&gt; sans interface graphique, sur laquelle je vais installer Docker. Mon but est d&#39;avoir un OS aussi dépouillé que possible de n&#39;installer que des conteneurs contenant les applicatifs désirés.&lt;/p&gt;
&lt;h2&gt;Sources&lt;/h2&gt;
&lt;p&gt;Pour cette installation, je me suis aidé de plusieurs articles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://linuxhandbook.com/raspberry-pi-headless-setup&quot;&gt;Raspberry PI Headless Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.alexellis.io/getting-started-with-docker-on-raspberry-pi&quot;&gt;Get Started with Docker on Raspberry PI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Matériel&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;un Raspberry Pi (version 2, B+)&lt;/li&gt;
&lt;li&gt;une carte mémoire (SD Card)&lt;/li&gt;
&lt;li&gt;de l&#39;équipement réseau (câble RJ45, switch)&lt;/li&gt;
&lt;li&gt;un autre ordinateur sous Linux (Mint)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1/ Préparation de la carte mémoire&lt;/h2&gt;
&lt;h3&gt;Formattage&lt;/h3&gt;
&lt;p&gt;Tout d&#39;abord on va préparer la carte, et il faut commencer par la formatter.
Pour cela, on insère la carte dans le lecteur. Si comme moi, vous n&#39;en avez pas un d&#39;intégré à votre PC, un adapteur USB fera très bien l&#39;affaire.
Puis, j&#39;ai utilisé l&#39;utilitaire graphique &lt;em&gt;Disks&lt;/em&gt; de Linux Mint pour trouver la carte parmis les supports de stockage et ensuite pour la formatter via le menu.&lt;/p&gt;
&lt;p&gt;Notez bien chemin de la carte mémoire, ça sera utile plus tard. Pour moi, il s&#39;agissait de &lt;code&gt;/dev/sdc&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Téléchargement de Raspbian&lt;/h3&gt;
&lt;p&gt;Rien de sorcier, voici la page des téléchargements : &lt;a href=&quot;https://www.raspberrypi.org/downloads/raspbian&quot;&gt;Raspberry Pi Downloads&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Installation de Raspbian&lt;/h3&gt;
&lt;p&gt;Pour installer Raspbian, il suffit de copier le contenu de l&#39;archive téléchargée sur la carte mémoire. Pour cela, j&#39;ai utilisé l&#39;utilitaire &lt;code&gt;dd&lt;/code&gt;, qui prend en paramètre, entre autre le chemin de ma carte mémoire que j&#39;avais pris le soin de noter auparavant.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;unzip&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2018&lt;/span&gt;-06-27-raspbian-stretch-lite.zip
    &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dd&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/dev/sdc &lt;span class=&quot;token assign-left variable&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;fsyncp&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Un peu de configuration&lt;/h3&gt;
&lt;p&gt;Par défaut, SSH sera désactivé et ce sera facheux lorsqu&#39;on voudra prendre la main à distance sur le Pi. Pour l&#39;activer, il suffit de créer un fichier vide dans la partiion de &lt;em&gt;boot&lt;/em&gt; sur la carte mémoire.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mount&lt;/span&gt; /dev/sdc1 /mnt &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;umask&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;000
&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; /mnt/ssh&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2/ Lancement !&lt;/h2&gt;
&lt;p&gt;La carte mémoire est prête. Il est temps d&#39;insérer la carte, brancher le Pi au réseau et l&#39;allumer.
Une fois démarré, j&#39;ai tiré parti de ma box internet (Livebox) pour assigner une IP statique et un nom (&lt;code&gt;backupserver&lt;/code&gt;) au Pi depuis l&#39;interface d&#39;administration, puis je l&#39;ai redémarré pour qu&#39;il prenne en compte les changements.&lt;/p&gt;
&lt;p&gt;La configuration réseau terminée, on peut se connecter en SSH en utilisant les identifiants par défaut : &lt;code&gt;pi&lt;/code&gt; / &lt;code&gt;raspberry&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; pi@backupserver&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pour des raisons évidentes, on va en profiter pour changer tout de suite le mot de passe :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;passwd&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3/ Installation de Docker&lt;/h2&gt;
&lt;p&gt;Docker supporte désormais les architectures ARM. On va donc pouvoir l&#39;installer assez facilement sur le Pi !&lt;/p&gt;
&lt;h3&gt;Preconfiguration&lt;/h3&gt;
&lt;p&gt;Avant de pouvoir installer Docker, un peu de configuration est nécessaire.
Tout d&#39;abord, il faut définir le &lt;em&gt;hostname&lt;/em&gt; dans les fichiers suivants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/hosts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/etc/hostname&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ensuite, on va modifier le fichier &lt;code&gt;/boot/config.txt&lt;/code&gt; pour modifier ou ajouter la ligne suivante :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;gpu_mem&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Installer Docker&lt;/h3&gt;
&lt;p&gt;Docker s&#39;installe très facilement via la commande proposée sur le site officiel :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-sSL&lt;/span&gt; https://get.docker.com &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Configurer Docker&lt;/h3&gt;
&lt;p&gt;Dans mon cas, j&#39;ai envie que Docker se lance toujours au démarrage du Pi, c&#39;est pourquoi je configure &lt;em&gt;systemd&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl &lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et pour des raisons pratiques, on peut également configurer notre utilisateur pour lui permettre d&#39;utiliser Docker sans avoir systématiquement besoin de &lt;em&gt;sudo&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;usermod&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-aG&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; pi&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On peut maintenant redémarrer le Pi une nouvelle (et dernière) fois.&lt;/p&gt;
&lt;h2&gt;Profit&lt;/h2&gt;
&lt;p&gt;Le Raspberry Pi est désormais prêt à recevoir des conteneurs !&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Serveur de backup : Samba</title>
    <link href="/posts/samba-server/"/>
    <updated>2019-04-09T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/samba-server/</id>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Cet article fait suite à celui de l&#39;installation sur un Raspberry Pi d&#39;une distribution Raspbian Lite (sans UI) et de Docker. Vous pouvez retrouver cet article &lt;a href=&quot;/posts/install-raspberry-pi-with-docker&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sans grande originalité, j&#39;ai donc décidé de transformer mon Pi en serveur de fichier pour faire mes sauvegardes et accéder à mes données depuis n&#39;importe quelle PC du réseau local. Le &amp;quot;challenge&amp;quot; sera de le faire uniquement avec des conteneurs !&lt;/p&gt;
&lt;p&gt;Dans cette première partie, nous allons voir comment faire la partie partage avec Samba.&lt;/p&gt;
&lt;h2&gt;Matériel&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;un Raspberry Pi avec Docker&lt;/li&gt;
&lt;li&gt;un disque dur externe en USB&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1/ Connecter le disque dur externe&lt;/h2&gt;
&lt;p&gt;Tout d&#39;abord on va brancher le disque en USB sur le Pi. Etant formatté en NTFS pour pouvoir l&#39;utiliser avec Windows, le Pi est capable de le monter nativement mais uniquement en lecture seule.&lt;/p&gt;
&lt;p&gt;Pour pouvoir déposer des fichiers sur le disque dur, on va devoir le monter différement. Pour cela nous allons avoir besoin du paquet &lt;code&gt;ntfs-3g&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ntfs-3g&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ensuite, on va devoir trouver le disque dur. Pour cela, je regarde habituellement dans &lt;code&gt;/dev/disk&lt;/code&gt;. Dans mon cas, le disque dur était &lt;code&gt;/dev/dsb&lt;/code&gt;.
Je peux alors le monter via la commande :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mount&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; rw,uid&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;,gid&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;,umask&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;0077 &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-t&lt;/span&gt; ntfs-3g &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    /dev/sdb /media/share&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-t ntfs-3g&lt;/code&gt; indique le format de la partition, ici nous sommes en NTFS avec le paquet installé précédemment&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-o&lt;/code&gt; permet de donner des options
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;uid=1000,gid=1000&lt;/code&gt; indique quel utilisateur aura accès au disque dur. On peut trouver les &lt;code&gt;uid&lt;/code&gt; et &lt;code&gt;gid&lt;/code&gt; dans le fichier &lt;code&gt;/etc/passwd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;umask=0077&lt;/code&gt; est un &lt;em&gt;chmod&lt;/em&gt; inversé. Ici, je donne un accès en lecture et écriture.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2/ Lancer Samba avec Docker&lt;/h2&gt;
&lt;p&gt;Pas besoin de réinventer la roue, un conteneur Samba existe déjà sur Docker Hub : &lt;a href=&quot;https://github.com/dperson/samba&quot;&gt;dperson/samba&lt;/a&gt;.
Le conteneur dispose d&#39;un script permettant de facilement configurer les utilisateurs et partages.&lt;/p&gt;
&lt;p&gt;Voici la commande que j&#39;ai utilisé :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; samba &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /media/share:/mnt/share &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;--network&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	dperson/samba:armhf &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;interfaces = 192.168.1.150&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;myuser;mypassword&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Share;/mnt/share;yes;no;no;myuser;myuser&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	&lt;span class=&quot;token parameter variable&quot;&gt;-w&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;workgroup&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Je vous laisse regarder la &lt;a href=&quot;https://github.com/dperson/samba/blob/master/README.md&quot;&gt;documentation&lt;/a&gt; qui explique bien ce que font les options &lt;code&gt;-u&lt;/code&gt;, &lt;code&gt;-s&lt;/code&gt; et &lt;code&gt;-w&lt;/code&gt; pour me concentrer plutôt sur les autres options.&lt;/p&gt;
&lt;p&gt;D&#39;une part pour Docker :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--network host&lt;/code&gt; permet au conteneur de se comporter au niveau réseau comme s&#39;il était directement sur la machine hôte&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;D&#39;autre par pour le conteneur :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-n&lt;/code&gt; pour démarrer NMDB qui permet de publier les partages, sans quoi le partage n&#39;était pas visible sur les PC de mon réseau&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-g &amp;quot;interfaces = &amp;lt;pi&#39;s IP&amp;gt;&amp;quot;&lt;/code&gt; qui indique quelle IP doit utiliser NMDB sans quoi il utilise une interface interne au conteneur&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3/ Améliorations&lt;/h2&gt;
&lt;h3&gt;Monter automatiquement le disque dur au démarrage du Pi&lt;/h3&gt;
&lt;p&gt;Comme nous avons fait le montage en ligne de commande, il sera perdu au prochain redémarrage. Pour éviter cela, nous allons l&#39;ajouter dans &lt;code&gt;/etc/fstab&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tout d&#39;abord, il faut trouver l&#39;UID du disque dur :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; blkid
&lt;span class=&quot;token comment&quot;&gt;# [...]&lt;/span&gt;
/dev/sdb &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;LABEL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MyBackup&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1E3BEA7C1AEA5087&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;TYPE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ntfs&quot;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;PARTUUID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;00015c12-01&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# [...]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ensuite, on peut modifier &lt;code&gt;/etc/fstab&lt;/code&gt; pour ajouter une ligne contenant les mêmes informations que la commande de &lt;em&gt;mount&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# &amp;lt;uid&gt; &amp;lt;mount point&gt; &amp;lt;format&gt; &amp;lt;options&gt; &amp;lt;dump&gt; &amp;lt;pass&gt;&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;UUID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1E3BEA7C1AEA5087&quot;&lt;/span&gt; /media/share	ntfs-3g	&lt;span class=&quot;token assign-left variable&quot;&gt;uid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;,guid&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;,umask&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;0077	&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;	&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Lancer automatiquement Samba au démarrage du Pi&lt;/h3&gt;
&lt;p&gt;Dans la commande Docker, remplacer &lt;code&gt;-rm&lt;/code&gt; par &lt;code&gt;--restart=always&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Profit&lt;/h2&gt;
&lt;p&gt;Le partage Samba devrait être accessible depuis la section &amp;quot;Réseau&amp;quot; de l&#39;explorateur de fichier.
Si ce n&#39;est pas le cas, vous pouvez également utiliser le chemin suivant : &lt;code&gt;smb://192.168.1.150&lt;/code&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Quelques astuces</title>
    <link href="/posts/tips/"/>
    <updated>2019-04-10T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/tips/</id>
    <content type="html">&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gitlab.com/-/snippets/1794631&quot;&gt;Vérifier si du XML a des caractères interdits&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
  <entry>
    <title>Serveur d&#39;impression</title>
    <link href="/posts/cups-server/"/>
    <updated>2020-08-17T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/cups-server/</id>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Cet article fait suite à celui de l&#39;installation sur un Raspberry Pi d&#39;une distribution Raspbian Lite (sans UI) et de Docker. Vous pouvez retrouver cet article &lt;a href=&quot;/posts/install-raspberry-pi-with-docker&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ici encore, on ne fait pas dans l&#39;original. Vous trouverez facilement bon nombre de tutoriels pour transformer un Raspberry Pi en serveur d&#39;impression. Mais là encore, on va le faire avec un conteneur.&lt;/p&gt;
&lt;h2&gt;Matériel&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;un Raspberry Pi avec Docker&lt;/li&gt;
&lt;li&gt;une imprimante et son câble USB&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1/ Connecter l&#39;imprimante&lt;/h2&gt;
&lt;p&gt;Brancher l&#39;imprimante au Pi via son câble USB et allumer l&#39;imprimante.
Normalement elle sera détectée automatiquement par l&#39;OS.&lt;/p&gt;
&lt;h2&gt;2/ Installer CUPS&lt;/h2&gt;
&lt;p&gt;CUPS est un serveur d&#39;impression. Il est trés répandu et est compatible avec tous les OS.
Mon but étant de garder le système aussi minimal que possible, on va s&#39;éviter les installations et configurations de CUPS en passant par Docker.&lt;/p&gt;
&lt;p&gt;Voici la commande que j&#39;ai utilisé :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; cups &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;631&lt;/span&gt;:631 &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /var/run/dbus:/var/run/dbus &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /dev/bus/usb:/dev/bus/usb &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;ADMIN_PASSWORD&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;MyCUPSP@ssw0rd &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--privileged&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--net&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;host &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;unless-stopped &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    ydkn/cups:latest&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A noter :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--net=host&lt;/code&gt; permet au conteneur de se comporter au niveau réseau comme s&#39;il était directement sur la machine hôte. C&#39;est nécessaire car sans cela, l&#39;interface d&#39;administration ne serait disponible que depuis le Raspberry Pi et pas depuis un autre PC du réseau.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v /var/run/dbus:...&lt;/code&gt; et &lt;code&gt;-v /dev/bus/usb:...&lt;/code&gt; permettent l&#39;accès à l&#39;imprimante conectée en USB depuis le conteneur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour le reste, je vous laisse aller regarder la documentation de &lt;a href=&quot;https://docs.docker.com/&quot;&gt;Docker&lt;/a&gt; et de &lt;a href=&quot;https://hub.docker.com/r/ydkn/cups&quot;&gt;l&#39;image CUPS&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;3/ Ajouter l&#39;imprimante dans CUPS&lt;/h2&gt;
&lt;p&gt;Une fois le conteneur lancé, on peut aller sur l&#39;interface de CUPS, à savoir : l&#39;ip de votre Pi (&lt;code&gt;ip addr show&lt;/code&gt;) sur le port 631. Chez moi cela donne &lt;code&gt;http://192.168.1.150:631&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Depuis cette interface, on va pouvoir aller dans la section &amp;quot;Administration&amp;quot;, puis &amp;quot;Trouver de nouvelles imprimantes&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/posts/cups-server/images/cups-config-admin.jpg&quot; alt=&quot;Interface d&#39;administation de CUPS&quot;&gt;&lt;/p&gt;
&lt;p&gt;CUPS nous demande de s&#39;authentifier et on arrive sur la page suivante pour choisir l&#39;imprimante.
CUPS a détecté mon imprimante, je peux directement l&#39;ajouter.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/posts/cups-server/images/cups-config-choix-imprimante.jpg&quot; alt=&quot;Choisir l&#39;imprimante&quot;&gt;&lt;/p&gt;
&lt;p&gt;Ensuite, CUPS nous demande quelques informations pour décrire l&#39;imprimante :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/posts/cups-server/images/cups-config-description-imprimante.jpg&quot; alt=&quot;Description de l&#39;imprimante&quot;&gt;&lt;/p&gt;
&lt;p&gt;On choisit ensuite la marque de l&#39;imprimante :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/posts/cups-server/images/cups-config-choix-marque.jpg&quot; alt=&quot;Choix de la marque de l&#39;imprimante&quot;&gt;&lt;/p&gt;
&lt;p&gt;Puis le modèle :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/posts/cups-server/images/cups-config-choix-modele.jpg&quot; alt=&quot;Choix du modèle de l&#39;imprimante&quot;&gt;&lt;/p&gt;
&lt;p&gt;Vous pourrez ensuite ajouter de options d&#39;impression ou prendre la configration par défaut.&lt;/p&gt;
&lt;p&gt;Pour vérifier si l&#39;imprimante est bien fonctionnelle, vous pouvez aller dans &amp;quot;Imprimantes&amp;quot;, choisir l&#39;imprimante que vous venez d&#39;ajouter, puis dans le menu déroulant &amp;quot;Maintenance&amp;quot;, choisissez &amp;quot;Imprimez une page de test&amp;quot;&lt;/p&gt;
&lt;h2&gt;4/ Profit&lt;/h2&gt;
&lt;p&gt;Lorsque vous ajouterez une nouvelle imprimante réseau sur votre PC, l&#39;OS devrait automatiquement la trouver.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Serveur DLNA</title>
    <link href="/posts/dlna-server/"/>
    <updated>2020-08-19T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/dlna-server/</id>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Cet article fait suite à celui de la mise en place de Samba sur un Raspberry Pi avec Docker. Vous pouvez retrouver cet article &lt;a href=&quot;/posts/samba-server&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Disposant d&#39;une TV connectée, j&#39;ai rapidement découvert qu&#39;elle pouvait lire des vidéos via le réseau. Pour cela, elle utilise le standard DLNA. On va donc voir ici comment mettre en place un serveur compatible DLNA sur le Raspberry Pi. Et comme pour les précédents articles, on va utiliser Docker !&lt;/p&gt;
&lt;h2&gt;C&#39;est quoi un serveur DLNA&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;DLNA définit un standard d&#39;interopérabilité permettant la lecture, le partage et le contrôle d&#39;appareils multimédia indépendamment de leur marque ou de leur nature. (source : &lt;a href=&quot;https://fr.wikipedia.org/wiki/Digital_Living_Network_Alliance&quot;&gt;Wikipedia&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On va utiliser ici le serveur &lt;a href=&quot;https://doc.ubuntu-fr.org/minidlna&quot;&gt;MiniDLNA&lt;/a&gt; pour sa simplicité : &lt;em&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_philosophy&quot;&gt;make each program do one thing well&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Materiel&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;un Raspberry Pi avec Docker&lt;/li&gt;
&lt;li&gt;un disque dur externe en USB&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1/ Pré-requis&lt;/h2&gt;
&lt;p&gt;Le disque dur est branché au Pi et on dispose d&#39;un point de montage.
Si besoin, la marche à suivre est indiqué dans l&#39;article mentionné ci-dessus.&lt;/p&gt;
&lt;h2&gt;2/ Installer le serveur MiniDLNA&lt;/h2&gt;
&lt;p&gt;Voici la commande que j&#39;ai utilisé :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; dlna &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--net&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;host &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--user&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;unless-stopped &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /media/share/videos:/media/videos &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;MINIDLNA_MEDIA_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/media/videos &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;MINIDLNA_FRIENDLY_NAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;MyDLNA &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    vladgh/minidlna&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--user=1000&lt;/code&gt; permet de lancer le conteneur en utilisant l&#39;utilisateur ayant l&#39;uid &lt;code&gt;1000&lt;/code&gt;, ce user est celui qui dispose des droits sur le point de montage &lt;code&gt;/media/share&lt;/code&gt;. On peut trouver l&#39;uid d&#39;un utilisateur en inspectant le fichier &lt;code&gt;/etc/passwd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-v /media/share/videos:...&lt;/code&gt; permet de monter une partie du disque dur dans le conteneur. Ensuite, on utilise &lt;code&gt;-e MINIDLNA_MEDIA_DIR=/media/videos&lt;/code&gt; pour indiquer à MiniDLNA quel dossier utiliser.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-e MINIDLNA_FRIENDLY_NAME=...&lt;/code&gt; permet de définir le nom qui apparaitra sur le réseau.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour les autres options, je vous laisse regarder la documentation de &lt;a href=&quot;https://docs.docker.com/&quot;&gt;Docker&lt;/a&gt; et de l&#39;image &lt;a href=&quot;https://github.com/vladgh/docker_base_images/tree/master/minidlna&quot;&gt;vladgh/minidlna&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;3/ Vérification&lt;/h2&gt;
&lt;p&gt;Vous pouvez aller inspecter les logs pour vérifier que le démarrage du serveur s&#39;est bien déroulé.
Pour cela, utilisez la commande suivante :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; logs dlna&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans ces logs, vous devriez voir apparaitre un section indiquant sur le serveur a bien pris en compte les dossiers que vous lui avez indiqué :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Scanning /media/videos
Scanning /media/videos finished &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;235&lt;/span&gt; files&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et une section indiquant que le serveur est bien démarré :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Starting MiniDLNA version &lt;span class=&quot;token number&quot;&gt;1.2&lt;/span&gt;.1.
HTTP listening on port &lt;span class=&quot;token number&quot;&gt;8200&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4/ Profit&lt;/h2&gt;
&lt;p&gt;Votre TV connectée devrait automatiquement découvrir le serveur et pourra lire les fichiers vidéos (ou audio) que vous aurez mis à disposition.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Serveur de numérisation</title>
    <link href="/posts/xsane-server/"/>
    <updated>2020-08-19T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/xsane-server/</id>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Cet article fait suite à celui de l&#39;installation sur un Raspberry Pi d&#39;une distribution Raspbian Lite (sans UI) et de Docker. Vous pouvez retrouver cet article &lt;a href=&quot;/posts/install-raspberry-pi-with-docker&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Après avoir installé un serveur d&#39;impression dans &lt;a href=&quot;/posts/cups-server&quot;&gt;un article précédent&lt;/a&gt;, nous allons maintenant voir comment également mettre le scanner à disposition sur le réseau, et là encore avec Docker pour minimiser le nombre d&#39;action à réaliser sur le Pi.&lt;/p&gt;
&lt;h2&gt;Sources&lt;/h2&gt;
&lt;p&gt;Pour cette installation, je me suis aidé de plusieurs articles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://samhobbs.co.uk/2014/07/raspberry-pi-print-scanner-server&quot;&gt;Raspberry Pi Print &amp;amp; Scanner Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.framboise314.fr/scanner-a-distance-avec-le-raspberry-pi/&quot;&gt;Scanner à distance avec le Raspberry Pi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Matériel&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;un Rapsberry Pi avec Docker&lt;/li&gt;
&lt;li&gt;une imprimante et son câble USB&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1/ Connecter le scanner&lt;/h2&gt;
&lt;p&gt;Brancher le scanner au Pi via son câble USB et allumer le scanner.
Normalement il sera automatiquement détecté&lt;/p&gt;
&lt;p&gt;Dans mon cas, je dispose d&#39;une imprimante/scanner tout-en-un. L&#39;appareil est déjà branché au Pi depuis l&#39;installation du serveur d&#39;impression.&lt;/p&gt;
&lt;h2&gt;2/ Installer Sane&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.sane-project.org/&quot;&gt;Sane&lt;/a&gt; est un serveur de numérisation. Il dispose de plusieurs clients pour être utilisable sur les différents OS existants.
Hélas, peu d&#39;images existent pour Raspberry Pi, on va donc créer notre propre image.&lt;/p&gt;
&lt;p&gt;Pour cela, allez sur &lt;a href=&quot;https://gitlab.com/mbarberot/docker-saned&quot;&gt;mbarberot/docker-saned&lt;/a&gt; et suivez les instructions du README pour créer l&#39;image.&lt;/p&gt;
&lt;p&gt;Ensuite, voici la commande que j&#39;ai utilisé :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; sane &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /var/run/dbus:/var/run/dbus &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /dev/bus/usb:/dev/bus/usb &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt;:10000 &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10001&lt;/span&gt;:10001 &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6566&lt;/span&gt;:6566 &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--privileged&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--net&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;host &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;unless-stopped &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    sane:latest&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-v /var/run/dbus:...&lt;/code&gt; et &lt;code&gt;-v /dev/bus/usb:...&lt;/code&gt; permettent l&#39;accès à l&#39;imprimante conectée en USB depuis le conteneur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour le reste, je vous laisse aller regarder la documentation de &lt;a href=&quot;https://docs.docker.com/&quot;&gt;Docker&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;3/ Profit&lt;/h2&gt;
&lt;p&gt;Le scanner devrait être accessible depuis le réseau.
Le site de &lt;a href=&quot;http://www.sane-project.org/sane-frontends.html&quot;&gt;Sane&lt;/a&gt; dispose d&#39;une page référençant les différents clients.&lt;/p&gt;
&lt;p&gt;Pour ma part, j&#39;ai opté pour :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://doc.ubuntu-fr.org/simple-scan&quot;&gt;Simple Scan&lt;/a&gt; sous Linux, il s&#39;agit de l&#39;utilitaire installé par défaut sous Linux Mint et il fonctionne parfaitement avec Sane.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sanetwain.ozuzo.net/&quot;&gt;SaneTwain&lt;/a&gt; sous Windows, c&#39;est rustique mais ça fonctionne bien.&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
  <entry>
    <title>Dépendences transitives et “unresolved requirement” error dans Liferay</title>
    <link href="/posts/2022-06-29-dependences-transitives-et-unresolved-requirement-error-dans-liferay/"/>
    <updated>2022-06-29T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/2022-06-29-dependences-transitives-et-unresolved-requirement-error-dans-liferay/</id>
    <content type="html">&lt;p&gt;Avec le passage à OSGi, la gestion du classpath ajoute son lot de surprise. Ainsi, on peut voir apparaitre l’erreur suivant lors du déploiement d’un module :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Could not resolve module: com.mbarberot.module.lorem &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2008&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;_  
		Unresolved requirement: Import-Package: org.foo.utils_&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans la plupart des cas, &lt;code&gt;org.foo.utils&lt;/code&gt; est le package d’une dépendance ajoutée au module. Par défaut, OSGi va aller chercher ce package dans sa liste de package qui provient des différents &lt;code&gt;Export-Package&lt;/code&gt; des modules déployés. Il faut donc lui signifier qu’il s’agit en fait d’un package qu’il doit aller chercher au sein de notre module. Pour cela, nous pouvons ajouter cette instruction au &lt;code&gt;bnd.bnd&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Private-Package: &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    org.foo.*&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hélas, c’est alors qu’une nouvelle erreur peut survenir :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Could not resolve module: com.mbarberot.module.lorem &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2008&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;_  
		Unresolved requirement: Import-Package: org.bar.annotations_&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pourtant, nulle trace de ce package dans le code ! Il s’agit en fait d’un package utilisé dans &lt;code&gt;org.foo&lt;/code&gt; car OSGi va venir également regarder les dépendances transitives !&lt;/p&gt;
&lt;p&gt;Hélas, dans ce cas, ajouter le package dans &lt;code&gt;Private-Package&lt;/code&gt; ne fonctionnera pas car ce n’est pas notre propre code qui vient importer ce package.&lt;/p&gt;
&lt;p&gt;Dans ce cas, on peut venir blacklister ce package dans la partie &lt;code&gt;Import-Package&lt;/code&gt; dans le &lt;code&gt;bnd.bnd&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Private-Package: &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    org.foo.*
Import-Package: &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;org.bar.*, &lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;
	  *&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Attention à ne pas oublier le wildcard en dernier, sans quoi OSGi n’ira plus chercher aucun package et ne trouvera aucune classe appartenant aux dépendances “provided” : Liferay, vos autres modules, ...&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Une entrée dans le menu utilisateur qui exécute du Javascript</title>
    <link href="/posts/2022-06-29-une-entree-dans-le-menu-utilisateur-qui-execute-du-javascript/"/>
    <updated>2022-06-29T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/2022-06-29-une-entree-dans-le-menu-utilisateur-qui-execute-du-javascript/</id>
    <content type="html">&lt;p&gt;Pour cela, on va créer un module de base :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;blade create &lt;span class=&quot;token parameter variable&quot;&gt;--template&lt;/span&gt; api my-portlet-entry&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On retouche le &lt;code&gt;bnd.bnd&lt;/code&gt; pour ne rien exporter :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Bundle-Name: My Portlet Entry
Bundle-SymbolicName: fr.mbarberot.myportlet.menu.entry
Bundle-Version: &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0
-metatype: *
-plugin.metatype: com.liferay.ant.bnd.metatype.MetatypePlugin&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On supprime le code généré et on ajoute notre composant :&lt;/p&gt;
&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    immediate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    property &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;token comment&quot;&gt;// 1️⃣&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;product.navigation.personal.menu.entry.order:Integer=100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;product.navigation.personal.menu.group:Integer=100&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    service &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonalMenuEntry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ClickMePersonalMenuEntry&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonalMenuEntry&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 2️⃣ &lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ResourceBundle&lt;/span&gt; resourceBundle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 
				&lt;span class=&quot;token class-name&quot;&gt;ResourceBundleUtil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBundle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
					&lt;span class=&quot;token string&quot;&gt;&quot;content.Language&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
					&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getClassLoader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getLabel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Locale&lt;/span&gt; locale&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LanguageUtil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resourceBundle&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;click-me&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPortletURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;HttpServletRequest&lt;/span&gt; httpServletRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// 3️⃣&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;javascript:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; 
						&lt;span class=&quot;token string&quot;&gt;&quot;function showDialog() {&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
	            &lt;span class=&quot;token string&quot;&gt;&quot;jQuery(&#39;.click-me-dialog&#39;).click();&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;};&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
            &lt;span class=&quot;token string&quot;&gt;&quot;showDialog();&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Voici les points clés de ce code :&lt;/p&gt;
&lt;p&gt;Premièrement (1️⃣), les &lt;code&gt;properties&lt;/code&gt; indiquent à quel endroit notre entrée de menu se placera au sein de ce menu. Ici, ce sera le premier item&lt;/p&gt;
&lt;p&gt;Ensuite (2️⃣), on utilise directement l’interface &lt;code&gt;PersonalMenuEntry&lt;/code&gt; pour avoir la main sur la méthode &lt;code&gt;getPortletURL&lt;/code&gt; et on doit également implémenter la méthode &lt;code&gt;getLabel&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Enfin (3️⃣), la chaîne de caractères qui sera retournée de &lt;code&gt;getPortletURL&lt;/code&gt; sera directement placée dans le &lt;code&gt;href&lt;/code&gt; de l’item du menu. On peut donc lui indiquer du javascript comme dans l’exemple.&lt;/p&gt;
&lt;p&gt;A noter cependant : si la méthode retourne des données, le lien effectuera un changement de page ! Il faut donc bien faire attention à ne rien retourner. Ainsi, on ne peut pas directement utiliser la méthode jQuery car ses méthodes retourneront toujours un résultat ou &lt;code&gt;this&lt;/code&gt; (pour pouvoir faire une chaîne d’appel), d’où la syntaxe utilisée dans l’exemple.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Déplacement en Camel Case avec IdeaVim</title>
    <link href="/posts/2022-08-19-deplacement-en-camel-case-avec-ideavim/"/>
    <updated>2022-08-19T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/2022-08-19-deplacement-en-camel-case-avec-ideavim/</id>
    <content type="html">&lt;p&gt;Si comme moi, vous travaillez sur un langage dont la convention de nommage est le CamelCase et que vous utilisez les motions de Vim, vous avez peut-être également eu cette frustration de ne pas pouvoir sauter d’un “mot” à l’autre dans un nom de variable ou de classe.&lt;/p&gt;
&lt;p&gt;L’alternative que j’ai utilisée pendant des mois est la suivante :&lt;/p&gt;
&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Goal : Change &quot;Foo&quot; with &quot;Bar&quot; in a CamelCase word&lt;/span&gt;
&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;caret&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SomeAwesomeFooService&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Place the caret at Foo : &quot;fF&quot; ou &quot;/Foo&amp;lt;Enter&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;SomeAwesome&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;caret&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;FooService&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Change the Foo part : &quot;ctS&quot; and then type &quot;Bar&amp;lt;Enter&gt;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;SomeAwesomeBarService&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette méthode est assez efficace mais parfois juste frustrante de devoir indiquer spécifiquement les lettres majuscules dans les commandes. J’aimerais avoir une commande intuitive que l’on puisse taper avec le minimum de réflexion comme peuvent l’être les commandes &lt;code&gt;w, b, e&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Après quelques recherches, voici ce que j’ai pu réussir à mettre en place :&lt;/p&gt;
&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Goal : change &quot;Foo&quot; with &quot;Bar&quot; in a CamelCase word&lt;/span&gt;
&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;caret&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SomeAwesomeFooService&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Move the caret to the next &quot;word&quot; inside CamelCase : &quot;&amp;lt;leader&gt;w&quot;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;caret&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AwesomeFooService&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Again : &quot;&amp;lt;leader&gt;w&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Of course, I could have used &quot;2&amp;lt;leader&gt;w&quot; directly&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;SomeAwesome&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;caret&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;FooService&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Change the Foo part : &quot;c&amp;lt;leader&gt;w&quot; and then type &quot;Bar&amp;lt;Enter&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;SomeAwesomeBarService&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et voici comment le mettre en place avec quelques lignes de configurations dans le &lt;code&gt;.ideavimrc&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;let&lt;/span&gt; mapleader &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt;

&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt; Camelcase motion
&quot; Can be used with dw, cw, yb, etc
noremap &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;leader&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;w &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;w
noremap &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;leader&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;e &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;w
noremap &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;leader&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;b &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;b&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vous pouvez mettre la touche que vous voulez dans le &lt;code&gt;mapleader&lt;/code&gt;. Ce sera la touche représentée par &lt;code&gt;&amp;lt;leader&amp;gt;&lt;/code&gt; dans la suite du fichier.&lt;/p&gt;
&lt;p&gt;Comme vous pouvez le voir, j’utilise la touche espace qui est facilement accessible depuis le pouce et me permet de taper la suite de la commande avec mes autres doigts.&lt;/p&gt;
&lt;p&gt;A noter :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://youtrack.jetbrains.com/issue/VIM-1984/Support-CamelCaseMotionvim-plugin&lt;/li&gt;
&lt;li&gt;https://stackoverflow.com/questions/71631159/ideavim-move-between-words-in-camel-case-word&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
  <entry>
    <title>Filtering avec Gradle</title>
    <link href="/posts/2023-03-29-filtering-avec-gradle/"/>
    <updated>2023-03-29T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/2023-03-29-filtering-avec-gradle/</id>
    <content type="html">&lt;h1&gt;La problématique&lt;/h1&gt;
&lt;p&gt;J’ai plusieurs vues et chacune d’entre-elles possède un fichier Javascript qui lui est dédié. Pour le charger, j’utilise la taglib &lt;code&gt;liferay-util&lt;/code&gt; afin d’injecter le fichier à la fin de la page :&lt;/p&gt;
&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- views/foo.jsp --&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- ... --&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;liferay-util:&lt;/span&gt;html-bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/o/foo-portlet/js/foo.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;liferay-util:&lt;/span&gt;html-bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lors du déploiement du module, aucun problème, tout fonctionne comme prévu. En revanche, lors des déploiements suivants, Liferay a mis en cache le fichier, et mes nouveaux développements ne sont pas pris en compte, et cela devient rapidement une source de frustration et une perte de temps.&lt;/p&gt;
&lt;h1&gt;Solutions étudiées&lt;/h1&gt;
&lt;h2&gt;Désactiver le “fast-load”&lt;/h2&gt;
&lt;p&gt;Mon premier réflexe a été de désactiver cette option via le fichier de configuration &lt;code&gt;portal-ext.properties&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;theme.js.fast.load=false&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hélas, cela ne fonctionne pas avec les fichiers injectés de cette manière.&lt;/p&gt;
&lt;h2&gt;Vider la cache depuis l’interface d’administration&lt;/h2&gt;
&lt;p&gt;Étonnamment, cette méthode ne semble pas fonctionner dans mon cas de figure, et de toute manière c’est rapidement fastidieux de devoir aller vider la cache après chaque déploiement.&lt;/p&gt;
&lt;h2&gt;Utiliser la configuration du portlet&lt;/h2&gt;
&lt;p&gt;Une autre manière est d’utiliser la configuration du portlet. En effet Liferay gère bien mieux l’invalidation du cache de cette manière, car il ajoute lui-même un timestamp lors de l’injection du fichier dans la page :&lt;/p&gt;
&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    immediate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    property &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;com.liferay.portlet.footer-portlet-javascript=/js/foo.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    service &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Portlet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyPortlet&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MVCPortlet&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Encore hélas, cette solution ne convient pas à mon cas de figure, car elle injectera tous les fichiers, quelque soit la vue et je ne veux charger que le fichier nécessaire à chaque vue.&lt;/p&gt;
&lt;h2&gt;Modifier le nom du fichier Javascript&lt;/h2&gt;
&lt;p&gt;Vu que Liferay se base sur le nom du fichier, on peut facilement contourner le cache en changeant le nom du fichier avant chaque déploiement. Réaliser cette opération manuellement nécessite d’une part de renommer le fichier, puis de mettre le nouveaux nom dans le fichier JSP, ce qui devient rapidement fastidieux.&lt;/p&gt;
&lt;h2&gt;Utiliser Gradle pour générer un suffixe automatiquement&lt;/h2&gt;
&lt;p&gt;Avec Maven, on dispose d’un mécanisme de &lt;code&gt;Filtering&lt;/code&gt; qui permet de remplacer des tokens particuliers placés dans les fichiers du projet par des valeurs indiquées dans la configuration du build. Gradle dispose également de cette fonctionnalité, et nous allons pouvoir l’utiliser pour ajouter automatiquement un suffixe aux imports des scripts.
Ce token particulier est une simple chaîne de caractères entourées d’un &lt;code&gt;@&lt;/code&gt; de part et d’autre. Voici ce que cela donne dans mon exemple :&lt;/p&gt;
&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;liferay-util:&lt;/span&gt;html-bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/o/foo-portlet/js/foo-@timestamp@.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;liferay-util:&lt;/span&gt;html-bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Une fois les fichiers JSP prêts, il faut désormais configurer Gradle.&lt;/p&gt;
&lt;p&gt;Tout d’abord, on va créer une variable avec la valeur du suffixe :&lt;/p&gt;
&lt;pre class=&quot;language-groovy&quot;&gt;&lt;code class=&quot;language-groovy&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; timestamp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;v1&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On va ensuite activer le &lt;code&gt;Filtering&lt;/code&gt; en configurant la tâche &lt;code&gt;processResources&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-groovy&quot;&gt;&lt;code class=&quot;language-groovy&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; org&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;apache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tools&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ant&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filters&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReplaceTokens

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

processResources &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    filter ReplaceTokens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tokens&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;timestamp&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; timestamp
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On va ajouter une nouvelle tâche pour ajouter automatiquement le suffixe aux fichiers Javascript :&lt;/p&gt;
&lt;pre class=&quot;language-groovy&quot;&gt;&lt;code class=&quot;language-groovy&quot;&gt;task cacheBusting &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Copy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    with copySpec &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;src/main/resources&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            include &lt;span class=&quot;token string&quot;&gt;&#39;**/*.js&#39;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;(.*)&#92;&#92;.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&#92;$1-&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;.js&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;buildDir&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/resources/main&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En l’état, les fichiers Javascript sont copiés deux fois, l’une par notre tâche avec les suffixe, et l’autre par &lt;code&gt;processResources&lt;/code&gt; sans le suffixe. On va donc lui retirer ces fichiers :&lt;/p&gt;
&lt;pre class=&quot;language-groovy&quot;&gt;&lt;code class=&quot;language-groovy&quot;&gt;processResources &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;exclude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;**/*.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enfin, on va brancher notre tâche &lt;code&gt;cacheBusting&lt;/code&gt; au sein du processus de build Gradle :&lt;/p&gt;
&lt;pre class=&quot;language-groovy&quot;&gt;&lt;code class=&quot;language-groovy&quot;&gt;task cacheBusting &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Copy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;dependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;processResources&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

jar &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;dependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cacheBusting&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Configuration finale&lt;/h2&gt;
&lt;pre class=&quot;language-groovy&quot;&gt;&lt;code class=&quot;language-groovy&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; org&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;apache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tools&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ant&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filters&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReplaceTokens
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; timestamp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;v1&quot;&lt;/span&gt;&lt;/span&gt;

processResources &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// replace @timestamp@ with the defined value in every resource files&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// note : it uses Ant under the hood&lt;/span&gt;
    filter ReplaceTokens&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tokens&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;timestamp&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; timestamp
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// do not process js files to let cacheBusting task handle them&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;exclude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;**/*.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// handle js files with this new task to rename them with the timestamp&lt;/span&gt;
task cacheBusting &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Copy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    with copySpec &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;src/main/resources&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            include &lt;span class=&quot;token string&quot;&gt;&#39;**/*.js&#39;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;(.*)&#92;&#92;.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&#92;$1-&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;.js&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;into&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;buildDir&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/resources/main&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;dependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;processResources&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

jar &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;dependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cacheBusting&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// insert the task into the gradle lifecycle&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Résultat&lt;/h2&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;build
├── resources
│   └── main
│       ├── content
│       │   └── Language.properties
│       └── META-INF
│           └── resources
│               ├── css
│               │   └── main.scss
│               ├── images
│               │   └── foo.jpg
│               ├── init.jsp
│               ├── js
│               │   ├── bar-v1.js
│               │   ├── baz-v1.js
│               │   └── foo-v1.js
│               └── views
│                   ├── bar.jsp
│                   ├── baz.jsp
│                   └── foo.jsp
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- foo.jsp --&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- ... --&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;liferay-util:&lt;/span&gt;html-bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/o/foo-portlet/js/foo-v1.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;liferay-util:&lt;/span&gt;html-bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title>Installer Blade CLI</title>
    <link href="/posts/2023-10-25-installer-blade-cli/"/>
    <updated>2023-10-25T12:00:00Z</updated>
    <id>https://mbarberot.gitlab.io/posts/2023-10-25-installer-blade-cli/</id>
    <content type="html">&lt;p&gt;Tout d’abord : &lt;a href=&quot;https://help.liferay.com/hc/en-us/articles/360017885232-Installing-Blade-CLI-&quot;&gt;la documentation officielle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un lien vous mènera sur SourceForge.&lt;/p&gt;
&lt;p&gt;Choisir la dernière version stable :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-1.png&quot; alt=&quot;Le site de téléchargement de Blade CLI&quot;&gt;&lt;/p&gt;
&lt;p&gt;Choisir ensuite l’exécutable sans le DevStudio et en fonction de votre OS :&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;La suite du site de téléchargement de Blade CLI&quot;&gt;&lt;/p&gt;
&lt;p&gt;Enfin : suivre la documentation officielle qui indique les options à choisir pendant l’installation.&lt;/p&gt;
&lt;p&gt;Attention, sous Windows, vous pourrez avoir l’erreur suivante :&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Error running C:/Program Files/&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;./bin/java.exe-jar 
&lt;span class=&quot;token string&quot;&gt;&quot;C:/Program Files (x86)&#92;...&lt;span class=&quot;token entity&quot; title=&quot;&#92;b&quot;&gt;&#92;b&lt;/span&gt;iz.a.Qute.jpm.run.jar&quot;&lt;/span&gt; 
&lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; init: Error &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;. Failed to run platform init, &lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt; code &lt;span class=&quot;token parameter variable&quot;&gt;-2137483648&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Elle survient lorsqu’il manque une clé de registre qui est normalement créée lors de l’installation du JDK. Si vous avez installé votre JDK manuellement, utilisez un installeur à la place.
Vous devriez trouver toutes les versions sur la site de la fondation Eclipse : &lt;a href=&quot;https://adoptium.net/&quot;&gt;Adoptium&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
</feed>
