Flache Git-Fetch-Regression in discourse_docker

Hallo,

Ein neuester Commit in docker_discourse unterbricht die Möglichkeit, ein Tag (z. B. v2.6.0) im Wert von version: in app.yml anzugeben. Dies ist nützlich, um ältere Versionen von Discourse zu installieren, etwa für Testzwecke.

Das Problem tritt wie folgt auf, wenn man version: v2.6.0 angibt und e2eb085714dfcf2aa0117b0f2fdf39b762b0e18d verwendet:

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 -- : 

Anstelle der erwarteten Ausgabe beim Verwenden des unmittelbar vorherigen Commits:

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

Ich würde das nicht direkt als Fehler bezeichnen, aber wir möchten Anweisungen bereitstellen, wie man alte Versionen von Discourse installiert, auch wenn dies eine komplexere Vorlage oder Ähnliches erfordert.

@Falco untersucht dies.

Ich stimme zu, dass die Tiefe konfigurierbar sein sollte, vielleicht über eine Umgebungsvariable, wobei standardmäßig „shallow

Ich denke, das Problem liegt hier darin, dass die Tags beim Checkout lokal nicht bekannt sind, ähnlich wie im folgenden (nicht mit Discourse zusammenhängenden) Issue:

Die Ausführung von git fetch --all sollte das Problem lösen, aber ich weiß nicht, wie stark sich dies auf die Größe des Images auswirken könnte (es sei denn, eine andere Anweisung löscht später die nicht verwendeten Referenzen).

Doch ich denke, git clone --depth 1 https://github.com/discourse/discourse.git --branch=$version würde es lösen, da --branch sowohl für Branches als auch für Tags funktioniert. Ich habe es jedoch noch nicht getestet und weiß nicht, ob es einen Grund dafür gibt, dass der Clone derzeit den master-Branch verwendet.

Bei git clone --depth 1 https://github.com/discourse/discourse.git --branch=v2.6.0 beträgt die Größe des gesamten Ordners 212 MB, und der darin enthaltene .git-Ordner hat 46 MB. Daher denke ich, dass das in Ordnung ist.

Das verdoppelt die Größe des Repositorys :slightly_frowning_face:

Das Problem ist, dass ich zum Zeitpunkt des Image-Builds nicht weiß, welchen Branch Sie in Zukunft verwenden möchten.

Das aktuelle Setup wurde geändert, um die Image-Größe zu verringern. Dadurch wurde die komprimierte Größe des Images um 250 MB (25 %) reduziert, was ein großer Gewinn ist. Es funktioniert einwandfrei bei der Verwendung normaler Branches wie stable, beta oder tests-passed.

Als Workaround können Sie, wenn Sie zu einem Tag wechseln möchten, Folgendes in Ihre app.yml-Datei einfügen:

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

Eine weitere Möglichkeit besteht darin, einen base_image-Schlüssel auf oberster Ebene der app.yml-Datei hinzuzufügen, dessen Wert ein älteres Basis-Image ist. Da wir nicht einmal versuchen, die Kompatibilität sicherzustellen, dass neue Images ältere Discourse-Versionen ausführen können, kann dies erforderlich sein, wenn Sie weit genug zurückgehen.

Du hast recht, zu diesem Zeitpunkt kennen wir die Version nicht. Es scheint, dass das Basis-Image den aktuellen Version-Branch plus den „tests-passed“-Branch verwendet, wobei der Branch den Commit zum Zeitpunkt des Image-Builds enthält.

Würde die derzeitige Vorgehensweise nicht zu langsameren Neubuilds führen, selbst wenn der „tests-passed“-Branch verwendet wird?

Betrachte einfach folgende Anweisungen:

Im Basis-Image:

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

In web.template.yml

git reset --hard
git clean -f
git remote set-branches --add origin master
git pull
...

Wenn git pull aufgerufen wird, wird das gesamte Repository gezogen, was mehrere Minuten dauern kann, da zuvor nur ein flaches Clone (shallow clone) durchgeführt wurde. Du kannst versuchen, die oben genannten Anweisungen lokal auszuführen und es selbst zu testen.

Ich sage nicht, dass es besser ist, das gesamte Repository im Basis-Image zu haben, aber der Code in web.template.yml wird bei jedem Neubuild ausgeführt, selbst wenn nur ein Plugin hinzugefügt oder eine Einstellung in app.yml geändert wurde. Was ich normalerweise in meinen (nicht-Discourse-)Projekten mache, ist, für jede neue Version ein neues Image zu erstellen. Das ist für dich jedoch möglicherweise nicht machbar (unter Berücksichtigung deiner aktuellen Vorgehensweise).

Hast du keine Zunahme der Neubuild-Zeit bemerkt? (Oder ist dieser Anstieg im Vergleich zur gesamten Neubuild-Zeit in den meisten Fällen nicht so groß?)

Update

Ich habe die oben genannten Schritte erneut getestet, und sie waren schnell. Ich vermute, ich habe beim ersten Versuch eine weitere Anweisung ausgeführt, die den Git-Baum verändert hat, und habe am Ende versucht, alles zu ziehen, als ich git pull ausgeführt habe.

Bist du dir da sicher?

➜  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    . 

@lucasbasquerotto Du hast recht, dass der git pull nicht zwingend erforderlich ist. Wir haben ihn hier entfernt.

Das sollte es anderen Branches (oder Forks) zukünftig ermöglichen, besser mit discourse_docker zusammenzuarbeiten :slight_smile:

Ja, ich sehe, dass nach dem Pull ein Fetch und dann ein Checkout im richtigen Branch durchgeführt wird. Daher denke ich, dass git pull nicht notwendig ist (ich habe es jedoch noch nicht getestet).

Bei Tags scheint es, als müsste ich sie separat abrufen, aber das sollte machbar sein. Da Branches häufiger verwendet werden, sollten Tags eher ein Randfall sein.

Kann man davon ausgehen, dass die Version-Option in der Konfigurationsdatei standalone.yml keine Wirkung hat?

Es hat immer noch eine Wirkung, kann aber jetzt nur noch für Branches festgelegt werden.

Ich erhalte denselben Fehler. Ich habe Version 2.5.1 verwendet.

Daraufhin erhalte ich folgenden Fehler:

I, [2020-12-31T11:50:24.701475 #1]  INFO -- : > cd /var/www/discourse && find /var/www/discourse ! -user discourse -exec chown discourse {} \+
chown: kann '/var/www/discourse/public/plugins/styleguide' nicht auflösen: Datei oder Verzeichnis nicht gefunden

Der Neuaufbau funktioniert nicht. Hilft jemand?

Versuchen Sie, den genannten Schlüssel hinzuzufügen und ein älteres Image von discourse/base - Docker Image zu verwenden.

Das funktioniert nicht, weil dies nach dem Code auftritt, der fehlschlägt, weil er die Version nicht abrufen kann. Was funktionierte, war die Erstellung einer version.template.yml neben web.template.yml mit folgendem Inhalt:

params:
  home: /var/www/discourse

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

Fügen Sie diese Datei dann in containers/app.yml vor web.template.yml wie folgt ein:

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

Damit das funktioniert, solltest du den version-Schlüssel auf oberster Ebene in deiner app.yml nicht verwenden, sondern nur diesen neuen Code. Auf diese Weise tritt kein Fehler auf.

Danke für die Klärung: Das ist genau der Teil, der mir fehlte. Für alle, die aus demselben Grund verwirrt sind wie ich: Ein Release-Tag von Discourse kann wie folgt abgerufen werden:

  • Stellen Sie sicher, dass der Parameter version in app.yml nicht gesetzt ist, zum Beispiel:
    params:
      db_default_text_search_config: "pg_catalog.english"
      #  version: stable
    
  • Fügen Sie am Ende von app.yml Code hinzu, um die gewünschte Version auszuchecken, zum Beispiel:
    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
    

Beim Ausführen von ./launcher rebuild app passiert Folgendes:

  • Die Standard-version (d. h. der test_passed-Zweig) wird ausgecheckt.
  • Das v2.5.0-Tag wird abgerufen und ausgecheckt, wodurch die vorherige Version effektiv ersetzt wird.