FreshRSS : Retrouver une interface épurée grâce au MutationObserver

Étant en train de faire de nombreux changements dans mon homelab, tant du côté de l’infrastructure que des outils, en passant par la sauvegarde. Je m’attarde aujourd’hui sur un point annexe rencontré lors de la migration de mon instance FreshRSS.

Bien occupé par d’autres préoccupations ces dernières années, la mise à jour de certains services commençaient à prendre du retard. En migrant FreshRSS, j’en ai profité pour mettre l’outil à jour et partir sur la dernière version en date. Rien à redire, l’outil fonctionne toujours aussi bien, fait ce qu’on lui demande et réponds à mes besoins pour le suivi de flux RSS. Par contre, un petit changement dans l’UX/UI m’a très vite contrarié.

Désormais, FreshRSS organise toutes les entrées par date et regroupe donc les flux par jour, avec un entête de séparation. Si ce changement ne se sent pas particulièrement en consultant le flux principal contenant les entrées de tous mes flux RSS, le résultat est plutôt perturbant lorsqu’on consulte le détail d’un flux RSS en particulier. La page devient alors une alternance entre entête de date et entrée de flux. La majeure partie des flux que je consulte publient très rarement plus d’une entrée par jour. Ma page se remplie d’entête de date qui constitue la moitié du contenu de la page et dont je n’ai pas l’utilité.

Bref, direction GitHub pour confirmer qu’un changement a eu lieu et savoir si un contournement ou une option de configuration existe. Bingo, deux issues existent:

Avant de passer à la solution que j’ai mise en place pour arriver à quelque chose de satisfaisant, voici la situation irritante en images.

Avant, un flux n’avait que trois entêtes: « Today », « Yesterday » et « Before yesterday ».

Et désormais, avec une entête par jour, on obtient quelque chose comme cela:

Quelle est donc la solution, me direz-vous ?

Les discussions sur GitHub proposent d’activer l’extension « User CSS » et d’ajouter la règle suivante:

 .transition {
    display: none;
 }

Ce qui a pour effet de faire disparaître toutes les entêtes. C’est mieux, mais insuffisant à mon goût. J’ai vraiment l’impression de perdre en lisibilité, car je ne peux plus distinguer les entrées récentes (les deux derniers jours) des entrées plus anciennes. En continuant d’expérimenter avec des règles CSS plus complexes pour tenter d’arriver à une présentation me convenant, j’aperçois un bouton permettant d’activer l’extension « User JS ». Ayant passé de nombreuses années à expérimenter et construire des solutions avec du JS, un début d’idée commence à germer dans mon esprit. Avec l’aide d’un MutationObserver pour intercepter les changements du DOM, je devrais être en mesure de détecter l’ajout des entêtes dans le DOM et de ne garder que les trois premières, retrouvant ainsi une présentation proche de la version historique à laquelle je suis habitué.

Après quelques itérations, voici donc le code que j’utilise:

const labels = ['Today', 'Yesterday', 'Before yesterday'];
let transitionCount = 0;

function processTransition(el) {
  const i = transitionCount++;
  if (i >= 3) {
    el.style.display = 'none';
  } else {
    const link = el.querySelector('.transition-value a:first-child');
    if (link) {
      link.textContent = labels[i];
    }
  }
}

const main = document.querySelector('main');
main.querySelectorAll('.transition').forEach(processTransition);

const observer = new MutationObserver((mutations) => {
  for (const mutation of mutations) {
    for (const node of mutation.addedNodes) {
      if (node.nodeType !== 1) {
        continue;
      }
      if (node.classList?.contains('transition')) {
        processTransition(node);
      } else {
        node.querySelectorAll?.('.transition').forEach(processTransition);
      }
    }
  }
});

observer.observe(main, { childList: true, subtree: true });

Ce qui nous donne le résultat suivant:

On constate immédiatement que l’information est bien plus condensée et qu’il y a, à mon goût, moins d’espace perdu. Je me rends compte en écrivant ces lignes, que les labels que j’utilise ne correspondent toutefois plus vraiment. En effet, dans mon exemple avec le flux xkcd, les deux entrées les plus récentes ont été reçues le lendemain de leur publication, mais à deux jours d’intervalles. Mon affichage « Aujourd’hui » (« Today ») et « Hier » (« Yesterday »), est donc inexacte, mais correspond en tout cas à un regroupement qui me convient. Après réflexion, je m’oriente donc vers un découpage « Latest », « Previous » et « Older ».

Pour avoir utilisé cette solution au quotidien depuis maintenant plusieurs semaines, je suis tout à fait satisfait du résultat. Bien sûr, il y a parfois quelques clignotements dans l’interface, le temps que le code s’exécute et que les entêtes soient cachées ou que leur titre change, mais rien qui ne soit gênant.

[Ansible] Liste des valeurs disponibles pour ansible_os_family

Petit pense-bête, pour éviter de perdre plusieurs dizaines de minutes à retrouver la liste des valeurs possibles pour la variable ansible_os_family dans ansible, après plusieurs semaines ou mois sans pratiquer.

La liste est par là:
ansible/ansible/module_utils/facts/system/distribution.py#L511

Erreur 401 à l’installation d’une dépendance depuis le registre privé de GitHub avec npm v7

Au quotidien, sur l’une des briques logicielles sur laquelle je travaille, nous avons dans les dépendances de notre projet Node, une bibliothèque partagée à partir du registre privé de GitHub. Après une mise à jour de npm de la version 6 à la version 7, j’ai commencé à voir apparaître des erreurs 401 à l’exécution de la commande npm install. Ayant d’autres sujets plus urgents à traiter, nous avons donc pris la décision de rester sur la version 6 de npm.

Quelques mois après, avec le passage de Node 16 en version LTS et la publication de npm version 8, je me suis penché une nouvelle fois sur la question. En changeant la syntaxe de mon fichier .npmrc et en utilisant le nouveau format de token GitHub déployé il y a plusieurs semaines, les erreurs ont fini par disparaître. Voici donc la syntaxe utilisée:

//npm.pkg.github.com/:_authToken=ghp_xxxxxxxxxxxxxxxxxxxx
@scope:registry=https://npm.pkg.github.com

J’ai été devancé alors que je m’apprêtais à partager la disparition des erreurs avec cette configuration dans le ticket de bug dédié, où nous apprenons que cette correction fonctionne correctement pour les versions 6, 7 et 8 de npm.

Utiliser buildah dans Cloud Build

L’astuce consiste en l’utilisation d’une image buildah officielle, disponible à l’adresse quay.io/buildah/stable. Je distingue trois étapes dans mon build: la construction de l’image, la récupération de la clef de chiffrement depuis le Secret Manager et enfin, le stockage dans le Container Registry. Ce qui nous donne donc la configuration ci-dessous.

Construction de l’image

# Build image with buildah
- id: 'build'
  name: 'quay.io/buildah/stable'
  args: ['buildah', 'bud', '-t', 'mon-image', '.']
  volumes:
    - name: varlibcontainers
      path: '/var/lib/containers'

Récupération de la clef

# Get public key from secret manager
- id: 'get public key'
  name: gcr.io/cloud-builders/gcloud
  entrypoint: 'bash'
  args: [ '-c', "gcloud secrets versions access latest --secret=pub-key --format='get(payload.data)' | tr '_-' '/+' | base64 -d > pub-key.pem" ]

Stockage de l’image

# Push image with buildah
- id: 'push'
  name: 'quay.io/buildah/stable'
  args: ['buildah', 'push', '--encryption-key', 'jwe:./pub-key.pem', 'mon-image', 'eu.gcr.io/$PROJECT_ID/mon-image']
  volumes:
    - name: varlibcontainers
      path: '/var/lib/containers'

Note

Précisons que ce Cloud Build est déclenché en cas de push sur une branche particulière d’un dépôt git, ici hébergé chez GitHub et connecté à la GCP. Ce dépôt contient bien entendu un fichier Dockerfile à sa racine.