feat: publish a rendered tree per definition schema - #32
Merged
Merged
Conversation
A definition here reaches every install within a day whatever version of lerd is running, and the path it arrives on is one the binary computes for itself. A binary already in the field cannot be taught a new one, so the unprefixed path has to keep meaning what those binaries expect, and anything a newer lerd understands has to reach it some other way. Definitions are now authored once under sources/ in the newest schema. A schema file states only what changed since the one before it and how to render a document back down, and CI publishes a tree for each: the unprefixed path is schema 1, read by everything up to 1.35.0, and schema/2/ is read by 1.36.0 and later. Most of the delta is keys an older binary ignores anyway, so rendering them away only makes the published tree mean what it says. One is not cosmetic. Schema 2 serves a dashboard through a proxy that strips the upstream's framing headers, and schema 1 opens the dashboard URL directly in an iframe, so a UI that refuses framing renders a blocked panel. A dashboard that only works behind that proxy is therefore dropped when rendering to schema 1, and the service installs and serves its port with no dashboard card rather than a dead one. The guard learned to tell a rendered removal from a real one, and a second job fails a pull request whose published trees no longer match the sources.
Every definition rendered the same in both trees was being stored in both, with each icon stored twice more on top. The client tries its bases in order and a 404 falls straight through without a retry, so a definition a schema does not change can simply be absent from that schema's tree and be served from the one below it. A schema above the oldest now carries only the definitions whose render differs, plus its own complete index, since the index is one file and has to list everything. Icons are schema independent and live in the legacy tree alone. Four of twenty seven presets differ today, so the second tree is five files rather than forty three.
…blished Making the legacy tree an artifact meant rewriting all of it, and re-serialising a definition strips the comments explaining it and makes every install re-download a file whose meaning never moved. A definition whose downgrade changes nothing is now copied from its source byte for byte, so only the four presets that actually lose a schema 2 key are rewritten, and the rest keep the bytes they were published with.
Every preset was being authored under sources/ and copied into the published tree, so twenty three of twenty seven existed twice for no reason: their two schemas render the same. A definition now lives in services/ and is published as it stands. It gains a source only when a key a newer lerd reads would be wrong to publish to an older one, and then the source is the one authored copy and both trees are rendered from it. Four presets qualify today. The index is treated the same way. It is hand maintained and does not always match a projection of the YAML, so regenerating it wholesale would push those differences out as a change nobody asked for. Only the entries a render owns are rewritten.
A source directory held the full fidelity copy of every diverging definition, and the schema 2 tree held the same document again. The two were the same file, one of them formatted by the renderer. There is one authored copy now, and it lives in the highest schema tree the definition needs: services/ for one needing nothing newer, schema/N/services/ for one carrying a key that would be wrong to publish to an older binary. Every tree below renders down from it, so the same document is never stored twice.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A definition here reaches every install within a day whatever version of lerd is running, and the path it arrives on is one the binary computes for itself. A binary already in the field cannot be taught a new one, so the unprefixed path has to keep meaning what those binaries expect, and anything a newer lerd understands has to reach it some other way. That is the gap this closes.
Definitions are authored once under sources/ in the newest schema. A schema file states only what changed since the one before it and how to render a document back down, and CI publishes a tree for each: the unprefixed path is schema 1, which is what everything up to 1.35.0 fetches, and schema/2/ is what 1.36.0 and later fetch.
Most of the schema 2 delta is keys an older binary ignores anyway, so rendering them away only makes the published tree mean what it says. One is not cosmetic, and it is the reason for the whole thing. Schema 2 serves a dashboard through a proxy at /_svc// that deletes the upstream's X-Frame-Options and strips frame-ancestors from its CSP. Schema 1 has no such proxy and opens the dashboard URL directly in an iframe, so an upstream that refuses framing, which is every upstream that needs the strip flag, renders a blocked panel. A dashboard that only works behind the proxy is therefore dropped when rendering down, and a 1.35 install gets a service that runs and serves its port with no dashboard card, rather than one that looks broken.
Checked against the solr preset, which is the case that prompted this: rendered to schema 1 it carries no dashboard, rendered to schema 2 it carries the dashboard and the strip flag. The render is semantically lossless for every source, and of the presets published today only four differ for schema 1, each losing only keys 1.35.0 never had a field for.
The guard learned to tell a rendered removal from a real one, and still fails a genuine one. A second job fails a pull request whose published trees have drifted from the sources.
The binary half is lerd-env/lerd#1912, which asks for its own schema first and falls back to the unprefixed path, so these can merge in either order.