Duidelijker maken waarom de updateknop uit staat bij een zelfgebouwd image
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 41s
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 41s
Op een server die zelf bouwt (SU_IMAGE leeg, zoals de dev-server na een deploy-run) draait het image als 'server-up:<versie>'. Zonder registry-pad valt er niets op te halen, dus de knop staat uit. De melding verwees alleen naar UPDATE_IMAGE, terwijl het juiste antwoord daar is: die server werkt al bij via Git. - status() geeft nu een 'mode' terug (registry / local-build / no-compose / no-container) en de melding bij local-build noemt beide routes: pushen naar de branch of de deploy-workflow starten, en als alternatief SU_IMAGE. - De UI toont dat geval als informatie in plaats van als waarschuwing; het is de normale opzet, geen storing. - docs/updates.md: tabel met de twee manieren van bijwerken en de waarschuwing om ze niet door elkaar te gebruiken op dezelfde server, omdat de deploy-workflow en de updateknop allebei SU_TAG in .env schrijven. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
This commit is contained in:
parent
a1fb5f5a8f
commit
576ee17a61
5 changed files with 70 additions and 8 deletions
|
|
@ -18,6 +18,28 @@ Er zijn twee losse onderdelen:
|
||||||
Je hebt ze allebei nodig voor de updateknop. Alleen detectie werkt ook prima —
|
Je hebt ze allebei nodig voor de updateknop. Alleen detectie werkt ook prima —
|
||||||
dan zie je een melding en werk je bij met een git-tag, zoals voorheen.
|
dan zie je een melding en werk je bij met een git-tag, zoals voorheen.
|
||||||
|
|
||||||
|
### Twee manieren van bijwerken — kies er één per server
|
||||||
|
|
||||||
|
| | Hoe je bijwerkt | Knop in de interface |
|
||||||
|
|---|---|---|
|
||||||
|
| **Git-gestuurd** (`SU_IMAGE` leeg) | Push naar de branch, de deploy-workflow bouwt en herstart | Uit, met uitleg |
|
||||||
|
| **Registry** (`SU_IMAGE` gezet) | Knop "Nu bijwerken", of een tag pushen | Aan |
|
||||||
|
|
||||||
|
Een server die zelf bouwt kán niet uit een registry bijwerken: het image
|
||||||
|
`server-up:0.5.40-beta` heeft geen registry-pad, dus er is niets om op te halen.
|
||||||
|
De interface meldt dat en verwijst naar de Git-route. **Dat is geen storing** —
|
||||||
|
zo is een dev-server die na elke push opnieuw bouwt precies bedoeld.
|
||||||
|
|
||||||
|
> **Gebruik ze niet door elkaar op dezelfde server.** De deploy-workflow schrijft
|
||||||
|
> `SU_TAG` in `.env`, en de updateknop doet dat ook. Werk je in de interface bij
|
||||||
|
> naar 0.5.50 en pusht daarna iemand naar die branch, dan zet de workflow
|
||||||
|
> `SU_TAG` terug naar wat de branch bevat. Voor een server die aan een branch
|
||||||
|
> hangt is dat juist goed — git is daar de bron — maar verwacht dan geen effect
|
||||||
|
> van de knop.
|
||||||
|
>
|
||||||
|
> In de praktijk: **dev-server op Git**, en de registry-route voor productie of
|
||||||
|
> voor installaties die geen toegang tot je repository hebben.
|
||||||
|
|
||||||
### Kanalen
|
### Kanalen
|
||||||
|
|
||||||
| Kanaal | Ziet | Voorbeeld |
|
| Kanaal | Ziet | Voorbeeld |
|
||||||
|
|
|
||||||
|
|
@ -388,6 +388,7 @@ def api_update():
|
||||||
res.update({
|
res.update({
|
||||||
"can_apply": st["can_apply"],
|
"can_apply": st["can_apply"],
|
||||||
"apply_reason": st["reason"],
|
"apply_reason": st["reason"],
|
||||||
|
"apply_mode": st.get("mode", ""),
|
||||||
"image": st["image"],
|
"image": st["image"],
|
||||||
"previous_tag": st["previous_tag"],
|
"previous_tag": st["previous_tag"],
|
||||||
"channels": list(updater.CHANNELS),
|
"channels": list(updater.CHANNELS),
|
||||||
|
|
|
||||||
|
|
@ -98,28 +98,40 @@ def status() -> dict:
|
||||||
"""Kan deze installatie zichzelf bijwerken, en zo niet: waarom niet?"""
|
"""Kan deze installatie zichzelf bijwerken, en zo niet: waarom niet?"""
|
||||||
info = inspect_self()
|
info = inspect_self()
|
||||||
repo = image_repo(info)
|
repo = image_repo(info)
|
||||||
res = {"can_apply": False, "reason": "", "image": repo,
|
res = {"can_apply": False, "reason": "", "mode": "", "image": repo,
|
||||||
"current_image": info.get("image", ""),
|
"current_image": info.get("image", ""),
|
||||||
"working_dir": info.get("working_dir", ""),
|
"working_dir": info.get("working_dir", ""),
|
||||||
"service": info.get("service", ""),
|
"service": info.get("service", ""),
|
||||||
"previous_tag": (cfg.load().get("UPDATE_PREVIOUS_TAG") or "")}
|
"previous_tag": (cfg.load().get("UPDATE_PREVIOUS_TAG") or "")}
|
||||||
if not info:
|
if not info:
|
||||||
|
res["mode"] = "no-container"
|
||||||
res["reason"] = ("De eigen container is niet te vinden via de "
|
res["reason"] = ("De eigen container is niet te vinden via de "
|
||||||
"Docker-socket. Draait Server Up wel in Docker?")
|
"Docker-socket. Draait Server Up wel in Docker?")
|
||||||
return res
|
return res
|
||||||
if not info.get("working_dir"):
|
if not info.get("working_dir"):
|
||||||
|
res["mode"] = "no-compose"
|
||||||
res["reason"] = ("Deze container is niet met docker compose gestart "
|
res["reason"] = ("Deze container is niet met docker compose gestart "
|
||||||
"(geen compose-labels), dus bijwerken vanuit de "
|
"(geen compose-labels), dus bijwerken vanuit de "
|
||||||
"interface kan niet.")
|
"interface kan niet.")
|
||||||
return res
|
return res
|
||||||
if not repo:
|
if not repo:
|
||||||
|
res["mode"] = "unknown"
|
||||||
res["reason"] = "Geen image bekend om bij te werken."
|
res["reason"] = "Geen image bekend om bij te werken."
|
||||||
return res
|
return res
|
||||||
if "/" not in repo:
|
if "/" not in repo:
|
||||||
res["reason"] = (f"Het image '{repo}' komt niet uit een registry. Stel "
|
# Lokaal gebouwd image. Meestal is dat geen probleem maar juist de
|
||||||
"UPDATE_IMAGE in op bv. git.example.com/bes-r/server-up "
|
# opzet: de server bouwt zelf na een push naar Git. De knop is bedoeld
|
||||||
"en draai vanaf een registry-image.")
|
# voor installaties die een kant-en-klaar image uit een registry halen.
|
||||||
|
res["mode"] = "local-build"
|
||||||
|
res["reason"] = (
|
||||||
|
f"Deze installatie draait op een zelfgebouwd image ('{repo}') en "
|
||||||
|
"werkt dus bij via je eigen build- of deploy-proces — bij een "
|
||||||
|
"Forgejo-opzet: pushen naar de branch, of de deploy-workflow "
|
||||||
|
"handmatig starten. Wil je hier tóch de knop gebruiken, laat de "
|
||||||
|
"server dan vanaf een registry-image draaien (SU_IMAGE in .env, "
|
||||||
|
"zie docs/updates.md).")
|
||||||
return res
|
return res
|
||||||
|
res["mode"] = "registry"
|
||||||
res["can_apply"] = True
|
res["can_apply"] = True
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -670,10 +670,14 @@ tailwind.config = {
|
||||||
</div>
|
</div>
|
||||||
<!-- Waarom de knop niet bruikbaar is (geen registry-image, geen
|
<!-- Waarom de knop niet bruikbaar is (geen registry-image, geen
|
||||||
compose-labels, …) — anders staat er alleen een dode knop. -->
|
compose-labels, …) — anders staat er alleen een dode knop. -->
|
||||||
|
<!-- Bij een zelfgebouwd image is dit geen storing maar de opzet:
|
||||||
|
dan is Git de weg om bij te werken, niet deze knop. -->
|
||||||
<p x-show="update.update_available && !update.can_apply"
|
<p x-show="update.update_available && !update.can_apply"
|
||||||
class="text-xs text-wr flex items-start gap-1.5">
|
class="text-xs flex items-start gap-1.5"
|
||||||
<span class="mdi mdi-alert-outline shrink-0"></span>
|
:class="update.apply_mode === 'local-build' ? 'text-t2 dark:text-t2-dark' : 'text-wr'">
|
||||||
<span><span x-text="update.apply_reason"></span> <span x-text="t('update_cannot_apply')"></span></span>
|
<span class="mdi shrink-0"
|
||||||
|
:class="update.apply_mode === 'local-build' ? 'mdi-information-outline' : 'mdi-alert-outline'"></span>
|
||||||
|
<span x-text="update.apply_reason"></span>
|
||||||
</p>
|
</p>
|
||||||
<p x-show="update.error" class="text-xs text-er" x-text="update.error"></p>
|
<p x-show="update.error" class="text-xs text-er" x-text="update.error"></p>
|
||||||
<p x-show="update.checked_at" class="text-[11px] text-dm dark:text-dm-dark">
|
<p x-show="update.checked_at" class="text-[11px] text-dm dark:text-dm-dark">
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,33 @@ def test_status_ok_bij_registry_image(su, monkeypatch):
|
||||||
|
|
||||||
|
|
||||||
def test_status_weigert_lokaal_gebouwd_image(su, monkeypatch):
|
def test_status_weigert_lokaal_gebouwd_image(su, monkeypatch):
|
||||||
|
"""Een zelfgebouwd image is geen storing maar de normale opzet bij een
|
||||||
|
server die na een push zelf bouwt; de melding moet dat ook zeggen."""
|
||||||
_fake_inspect(su, monkeypatch, image="server-up:latest")
|
_fake_inspect(su, monkeypatch, image="server-up:latest")
|
||||||
st = su.status()
|
st = su.status()
|
||||||
assert st["can_apply"] is False
|
assert st["can_apply"] is False
|
||||||
assert "registry" in st["reason"]
|
assert st["mode"] == "local-build"
|
||||||
|
assert "zelfgebouwd" in st["reason"]
|
||||||
|
assert "deploy" in st["reason"] # wijst naar de Git-route
|
||||||
|
assert "SU_IMAGE" in st["reason"] # én naar het alternatief
|
||||||
|
|
||||||
|
|
||||||
|
def test_status_modus_bij_registry_image(su, monkeypatch):
|
||||||
|
_fake_inspect(su, monkeypatch)
|
||||||
|
assert su.status()["mode"] == "registry"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("overrides,modus", [
|
||||||
|
({"working_dir": ""}, "no-compose"),
|
||||||
|
])
|
||||||
|
def test_status_modi(su, monkeypatch, overrides, modus):
|
||||||
|
_fake_inspect(su, monkeypatch, **overrides)
|
||||||
|
assert su.status()["mode"] == modus
|
||||||
|
|
||||||
|
|
||||||
|
def test_status_modus_zonder_container(su, monkeypatch):
|
||||||
|
monkeypatch.setattr(su, "inspect_self", lambda: {})
|
||||||
|
assert su.status()["mode"] == "no-container"
|
||||||
|
|
||||||
|
|
||||||
def test_status_weigert_zonder_compose_labels(su, monkeypatch):
|
def test_status_weigert_zonder_compose_labels(su, monkeypatch):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue