Change language

rp-registry

Zweck

Das Register der Module und Lösungen: was existiert, woraus die einzelnen Lösungen bestehen
und die Bytes selbst. Es beantwortet zwei Lesern, die sonst nichts gemeinsam haben, ihre Fragen. Ptah
fragt nach einem Index und anschließend nach Objekten anhand ihres Digests, ohne jemals einen Namen zu erfahren,
und überprüft jedes Byte, das es erhält. Das Portal und der Chat stellen die umgekehrte Frage — welche Lösungen existieren, was würde diese hier liefern, was benötigt sie zuerst.

Beides lebt auf einem Dienst, weil ein Katalog, der Module benennt, die der Objektspeicher
nicht enthält, genau der Fehler ist, den dies verhindern soll, und dies nur dort überprüft werden kann, wo
beide Hälften sichtbar sind.

Verantwortungsgrenze

rp-registry berührt niemals einen Cluster. Es veröffentlicht einen Katalog und stellt Bytes bereit;
die Umwandlung einer Auswahl in eine laufende Plattform erfolgt durch lm-kubernetes, das Solution
Custom Resources schreibt, und deren Abgleich ist Aufgabe von ptah. Diese Trennung bedeutet, dass eine
Registry viele Cluster bedienen kann, ohne Zugangsdaten für einen von ihnen zu besitzen.

Speicherung

Zwei Speicher, bewusst nicht mehr.

objects ist ein einzelner KV-Speicher, der unter zwei Präfixen zwei Arten von Werten enthält:
Modul-Bytes anhand des Digests (obj) und Lösungsdokumente nach Layer und Namen (sol).
Beide werden anhand eines exakten Schlüssels vollständig gelesen, sind also dieselbe Art von Speicher, die zweimal verwendet wird. KVStore erkennt anhand eines Headers, den es selbst schreibt, Binärdaten und JSON, sodass hier keines der beiden Präfixe dekodiert werden muss.

catalog ist SQL, weil es sowohl den veränderlichen als auch den abzufragenden Teil enthält: welches Artefakt derzeit welchem Digest zugeordnet ist und in welchem Layer. Bytes sind unveränderlich und über ihren Inhalt adressiert, benötigen also keine Tabelle; Namen ändern sich bei jeder Veröffentlichung und werden nach Layer, nach Typ und layerübergreifend abgefragt.

Die veröffentlichte Zuordnung wird nicht gespeichert. Sie ist eine Faltung über layers und modules,
die bei jeder Anfrage berechnet wird, und ihr Digest ist die revision. Sie zu speichern würde eine
zweite Kopie der Wahrheit erzeugen, die genau dann veraltet ist, wenn gerade eine Veröffentlichung stattgefunden hat
und ein Cluster fragt, warum es sie nicht sehen kann.

Layer

Ein Layer ist die Ausgabe eines einzelnen Builds. converged veröffentlicht seine Module, club veröffentlicht
seine eigenen und deklariert extends: ["converged"], und die Zuordnung, die jeder Consumer liest, wird aus allen
Layern zusammengesetzt — ein Produkt-Layer kommt nach der Basis, die er erweitert, sodass ein Modul, das er
bewusst ersetzt, gewinnt. Die Veröffentlichungsreihenfolge spielt keine Rolle mehr, und kein Build kann Namen löschen,
die er nicht selbst erstellt hat.

Eine Veröffentlichung ersetzt einen Layer vollständig, statt ihn zusammenzuführen: Eine Veröffentlichung ist die
vollständige Ausgabe dieses Layers, daher muss ein Name, den der neue Build nicht mehr erzeugt, verschwinden. Ein Zusammenführen würde ihn weiterhin auf Bytes zeigen lassen, die nichts mehr baut.

Bereitstellung der Bytes

ensureObjectCached gibt einen Valkey-Schlüssel zurück, nicht das Objekt. Die Bytes werden im begrenzten
Cache materialisiert und von dort vom ui gelesen. Das ist dieselbe Übergabe, die die Galerie für Bilder verwendet,
und zwar aus demselben Grund: Ein Modul kann bis zu 2 MiB groß sein, und eine Antwort mit der Nutzlast würde es
bei jedem Cache-Miss durch storage → ms → ui leiten, über einen Kanal, der für Anfragen gedacht ist.

Die beiden Routen, die ein Cluster verwendet — /registry/index.json und /registry/<digest> —
werden vom ui-Host des Clubs bereitgestellt, nicht von diesem Dienst
(club/core/frontend/landing/src/ptah-registry.ts). ptah spricht einfaches HTTP und nichts anderes,
also muss etwas mit einer HTTP-Schnittstelle für ihn antworten, und das ist das ui; das Basis-Image bleibt außen vor,
weil ein Produkt ohne Registry nichts bereitzustellen hat. Die Routen sind anonym, weil die Authentizität auf dem
Digest beruht: ptah überprüft jedes Byte, das es erhält, gegen den Digest, den es angefordert hat, sodass ein
Shared Secret etwas hinzuzufügen hätte, das verteilt und widerrufen werden muss, ohne eine Garantie hinzuzufügen.

Ein Digest, den kein Layer benennt, wird nicht bereitgestellt, selbst wenn die Bytes gespeichert sind. Objekte ohne
Namen sind entweder Überreste einer unterbrochenen Veröffentlichung oder etwas, das ein Aufrufer erraten hat, und ihre
Bereitstellung würde dies zu einem offenen Blob-Speicher machen.

Grenzen

Ein Objekt ist auf 2 MiB begrenzt. Echte Module sind mehrere Dutzend Kilobyte groß — der gesamte
Backend-Satz von converged ist komprimiert etwa 0,44 MiB groß — und ptah lehnt alles über
64 MiB ab, sodass dieser Wert deutlich unter beiden Grenzen liegt. Das ist keine Optimierung: Die Registry
soll Community-Module aufnehmen, und ein Upload in der Größe eines Container-Images bedeutet, dass jemand das falsche Artefakt veröffentlicht hat.

Objekte werden genau so gespeichert, wie sie eintreffen. Die Registry komprimiert und dekomprimiert weder:
Modul-Bundles sind brotli, Workflow-Quellen sind unverarbeitet, weil centimanus sie selbst ausführt, und der Digest
umfasst in beiden Fällen die gespeicherten Bytes. Jede erneute Kodierung würde die Inhaltsadressierung an dem einen
Hop beschädigen, den sie schützen soll.

Quelle

modules/repositories/rp-registry