diff --git a/docs/updates.md b/docs/updates.md index f874157..515c254 100644 --- a/docs/updates.md +++ b/docs/updates.md @@ -18,6 +18,28 @@ Er zijn twee losse onderdelen: 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. +### 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 | Kanaal | Ziet | Voorbeeld | diff --git a/server-up/app.py b/server-up/app.py index 33c2534..9a24850 100644 --- a/server-up/app.py +++ b/server-up/app.py @@ -388,6 +388,7 @@ def api_update(): res.update({ "can_apply": st["can_apply"], "apply_reason": st["reason"], + "apply_mode": st.get("mode", ""), "image": st["image"], "previous_tag": st["previous_tag"], "channels": list(updater.CHANNELS), diff --git a/server-up/core/selfupdate.py b/server-up/core/selfupdate.py index d515550..6c0f42b 100644 --- a/server-up/core/selfupdate.py +++ b/server-up/core/selfupdate.py @@ -98,28 +98,40 @@ def status() -> dict: """Kan deze installatie zichzelf bijwerken, en zo niet: waarom niet?""" info = inspect_self() repo = image_repo(info) - res = {"can_apply": False, "reason": "", "image": repo, + res = {"can_apply": False, "reason": "", "mode": "", "image": repo, "current_image": info.get("image", ""), "working_dir": info.get("working_dir", ""), "service": info.get("service", ""), "previous_tag": (cfg.load().get("UPDATE_PREVIOUS_TAG") or "")} if not info: + res["mode"] = "no-container" res["reason"] = ("De eigen container is niet te vinden via de " "Docker-socket. Draait Server Up wel in Docker?") return res if not info.get("working_dir"): + res["mode"] = "no-compose" res["reason"] = ("Deze container is niet met docker compose gestart " "(geen compose-labels), dus bijwerken vanuit de " "interface kan niet.") return res if not repo: + res["mode"] = "unknown" res["reason"] = "Geen image bekend om bij te werken." return res if "/" not in repo: - res["reason"] = (f"Het image '{repo}' komt niet uit een registry. Stel " - "UPDATE_IMAGE in op bv. git.example.com/bes-r/server-up " - "en draai vanaf een registry-image.") + # Lokaal gebouwd image. Meestal is dat geen probleem maar juist de + # opzet: de server bouwt zelf na een push naar Git. De knop is bedoeld + # 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 + res["mode"] = "registry" res["can_apply"] = True return res diff --git a/server-up/templates/index.html b/server-up/templates/index.html index aba2f0d..ae4b7c7 100644 --- a/server-up/templates/index.html +++ b/server-up/templates/index.html @@ -670,10 +670,14 @@ tailwind.config = { +

- - + class="text-xs flex items-start gap-1.5" + :class="update.apply_mode === 'local-build' ? 'text-t2 dark:text-t2-dark' : 'text-wr'"> + +

diff --git a/tests/test_selfupdate.py b/tests/test_selfupdate.py index 0ec85bd..0214b6b 100644 --- a/tests/test_selfupdate.py +++ b/tests/test_selfupdate.py @@ -53,10 +53,33 @@ def test_status_ok_bij_registry_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") st = su.status() 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):