Régression de `git fetch` peu profonde dans discourse_docker

Bonjour,

A recent commit in docker_discourse breaks the ability to specify a tag (for instance v2.6.0) in the version: value of app.yml. This is useful to install older versions of discourse, for test purposes.

The problem shows like this when specifying version: v2.6.0 when using e2eb085714dfcf2aa0117b0f2fdf39b762b0e18d

I, [2020-12-05T10:59:38.848743 #1]  INFO -- : > cd /var/www/discourse && git remote set-branches origin v2.6.0
I, [2020-12-05T10:59:38.852600 #1]  INFO -- : 
I, [2020-12-05T10:59:38.852639 #1]  INFO -- : > cd /var/www/discourse && git fetch --depth 1 origin v2.6.0
From https://github.com/discourse/discourse
 * tag                 v2.6.0     -> FETCH_HEAD
I, [2020-12-05T10:59:41.405163 #1]  INFO -- : 
I, [2020-12-05T10:59:41.405307 #1]  INFO -- : > cd /var/www/discourse && git checkout v2.6.0
error: pathspec 'v2.6.0' did not match any file(s) known to git
I, [2020-12-05T10:59:41.411796 #1]  INFO -- : 

Instead of the expected output when using the commit just before that one.

I, [2020-12-05T11:22:14.717910 #1]  INFO -- : > cd /var/www/discourse && git fetch origin v2.6.0
From https://github.com/discourse/discourse
 * tag                     v2.6.0     -> FETCH_HEAD
I, [2020-12-05T11:22:15.672616 #1]  INFO -- : 
I, [2020-12-05T11:22:15.672683 #1]  INFO -- : > cd /var/www/discourse && git checkout v2.6.0
Note: checking out 'v2.6.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at d6121249d3 Version bump to v2.6.0
7 « J'aime »

Je ne qualifierais pas cela d’un bug à proprement parler, mais nous souhaitons proposer des instructions pour installer d’anciennes versions de Discourse, même si cela implique un modèle plus complexe ou autre chose.

@Falco mène l’enquête.

7 « J'aime »

Je suis d’accord pour dire que la profondeur devrait être configurable, peut-être via une variable d’environnement, avec une valeur par défaut de « shallow » ; mais configurable avec une simple variable d’environnement.

1 « J'aime »

Je pense que le problème ici est que les tags ne sont pas connus localement lors de la récupération (checkout), comme dans le problème suivant (non lié à Discourse) :

L’exécution de git fetch --all devrait résoudre le problème, mais je ne sais pas dans quelle mesure cela pourrait augmenter la taille de l’image (sauf si une autre instruction efface les références inutilisées plus tard).

Cela dit, je pense que git clone --depth 1 https://github.com/discourse/discourse.git --branch=$version résoudrait le problème, car l’option branch permet de gérer à la fois les branches et les tags. Cependant, je ne l’ai pas testé et je ne sais pas s’il y a une raison pour laquelle le clone utilise (actuellement) la branche master.

En exécutant git clone --depth 1 https://github.com/discourse/discourse.git --branch=v2.6.0, la taille totale du dossier est de 212 Mo, et le dossier .git à l’intérieur fait 46 Mo, donc je pense que c’est acceptable.

Cela double la taille du dépôt :slightly_frowning_face:

Le problème est qu’au moment de la construction de l’image, je ne sais pas quelle branche vous voudrez à l’avenir.

La configuration actuelle a été modifiée pour réduire la taille de l’image, ce qui a permis de diminuer la taille compressée de 250 Mo (25 %), ce qui est un gain considérable. Cela fonctionne bien lors de l’utilisation de branches normales telles que stable et beta ou tests-passed.

Comme solution de contournement, si vous souhaitez basculer vers un tag, vous pouvez appliquer ceci à votre fichier app.yml :

hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
+    - exec:
+        cd: $home
+        cmd:
+          - git fetch --depth=1 origin tag v2.5.0 --no-tags
+          - git checkout v2.5.0

Une autre solution de contournement consiste à ajouter une clé base_image au niveau supérieur de app.yml avec la valeur d’une image de base plus ancienne. Puisque nous ne cherchons même pas à maintenir la compatibilité des nouvelles images capables d’exécuter d’anciennes versions de Discourse, cela peut être nécessaire si vous revenez suffisamment loin dans le temps.

9 « J'aime »

Vous avez raison, à ce moment-là, nous ne connaissons pas la version. Il semble que l’image de base utilise la version actuelle + la branche tests-passed, bien que la branche contienne le commit au moment où l’image a été construite.

La méthode actuelle ne conduirait-elle pas à des reconstructions plus lentes, même lorsque la branche tests-passed est utilisée ?

Considérez simplement les instructions suivantes :

Dans l’image de base :

git clone --depth 1 https://github.com/discourse/discourse.git
cd discourse/
git remote set-branches --add origin tests-passed

Dans web.template.yml

git reset --hard
git clean -f
git remote set-branches --add origin master
git pull
...
Lorsque `git pull` est appelé, **l'intégralité du dépôt est téléchargée**, ce qui peut prendre plusieurs minutes, car seul un clone partiel (shallow clone) avait été effectué auparavant. Vous pouvez essayer d'exécuter uniquement les instructions ci-dessus localement pour le vérifier. Je ne dis pas qu'il est préférable d'avoir l'intégralité du dépôt dans l'image de base, mais le code dans `web.template.yml` s'exécute à chaque reconstruction, même si seul un plugin a été ajouté ou si une modification a été apportée dans `app.yml`. Ce que je fais habituellement dans mes projets (non-Discourse), c'est de créer une nouvelle image pour chaque nouvelle version, mais cela pourrait ne pas être réalisable pour vous (compte tenu de votre méthode actuelle). N'avez-vous pas remarqué une augmentation du temps de reconstruction ? (ou peut-être que cela n'est pas si important par rapport au temps total de reconstruction dans la plupart des cas)

Mise à jour

J’ai à nouveau testé les étapes ci-dessus et elles étaient rapides. Je suppose que lors de la première tentative, j’ai exécuté une autre commande qui a modifié l’arbre Git, ce qui a fini par entraîner le téléchargement de tout lors de l’exécution de git pull.

2 « J'aime »

En êtes-vous vraiment sûr ?

➜  discoursesmall git:(6a42acbf) docker run --rm -it discourse/base:2.0.20201125-2246
root@b481d11669ba:/# cd /var/www/discourse/
root@b481d11669ba:/var/www/discourse# du -sh .                                                     
774M    . 
root@b481d11669ba:/var/www/discourse# git pull
...
root@b481d11669ba:/var/www/discourse# du -sh .                                                                
778M    . 
5 « J'aime »

@lucasbasquerotto vous avez raison de souligner que le git pull n’est pas strictement nécessaire ; nous l’avons supprimé ici

Cela devrait permettre aux autres branches (ou forks) de mieux fonctionner avec discourse_docker à l’avenir :slight_smile:

5 « J'aime »

Oui, je vois qu’il effectue un fetch puis un checkout sur la bonne branche après le pull, donc je pense que le git pull n’est pas nécessaire (je ne l’ai pas testé, cependant).

Pour les tags, il semble que je doive encore les récupérer séparément, mais cela semble réalisable. De plus, les branches sont plus couramment utilisées, donc les tags devraient plutôt constituer un cas particulier.

1 « J'aime »

Peut-on raisonnablement supposer que l’option version dans le fichier de configuration standalone.yml n’a aucun effet ?

Cela a toujours un effet, mais il ne peut désormais être défini que sur des branches.

3 « J'aime »

Je rencontre la même erreur. J’utilisais la version 2.5.1.

Suite à cela, je rencontre l’erreur suivante :

I, [2020-12-31T11:50:24.701475 #1]  INFO -- : > cd /var/www/discourse && find /var/www/discourse ! -user discourse -exec chown discourse {} \+
chown: impossible de résoudre '/var/www/discourse/public/plugins/styleguide' : Aucun fichier ou dossier de ce type

La reconstruction ne fonctionne pas. Une aide serait la bienvenue ?

Essayez d’ajouter la clé mentionnée et d’utiliser une image plus ancienne depuis discourse/base - Docker Image

2 « J'aime »

Cela ne fonctionne pas car cela se produit après le code qui échoue car il ne peut pas récupérer la version. Ce qui a fonctionné, c’est de créer un fichier version.template.yml à côté de web.template.yml avec le contenu suivant :

params:
  home: /var/www/discourse

run:
  - exec:
      cd: $home
      hook: code
      cmd:
        - git fetch --tags

Ensuite, incluez ce fichier dans containers/app.yml, avant web.template.yml, comme ceci :

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/version.template.yml"
  - "templates/web.template.yml"

Pour que cela fonctionne, vous ne devriez pas utiliser la clé de niveau supérieur version dans votre fichier app.yml, mais seulement ce nouveau code. En faisant cela, cela ne échoue pas.

3 « J'aime »

Merci pour ces précisions : c’est exactement la partie qui me manquait. Pour ceux qui sont confus comme je l’étais, voici comment obtenir une balise de version (release tag) de Discourse :

  • S’assurer que le paramètre version n’est pas défini dans app.yml, par exemple :
    params:
      db_default_text_search_config: "pg_catalog.english"
      #  version: stable
    
  • Ajouter du code pour vérifier la version souhaitée vers la fin de app.yml, par exemple :
    hooks:
      after_code:
        - exec:
            cd: $home/plugins
            cmd:
              - git clone https://github.com/discourse/docker_manager.git
    +    - exec:
    +        cd: $home
    +        cmd:
    +          - git fetch --depth=1 origin tag v2.5.0 --no-tags
    +          - git checkout v2.5.0
    

Lors de l’exécution de ./launcher rebuild app, voici ce qui se passe :

  • La version par défaut (c’est-à-dire la branche test_passed) est vérifiée.
  • La balise v2.5.0 est récupérée et vérifiée, remplaçant ainsi efficacement la version précédente.
1 « J'aime »

This topic was automatically closed 0 minutes after the last reply. New replies are no longer allowed.