Put the store's tools in a module beside it, since the store's module may not build (ADR 0251)
This commit is contained in:
+19
-12
@@ -44,7 +44,10 @@ registry, and pruning of unused images on a machine — each a dry run unless as
|
||||
in three steps ([ADR 0246](0246-a-seats-new-verb-is-promised-before-it-is-required.md)), and the
|
||||
store has one holder and no second in view. Not now; the tools can be promoted when a second holder
|
||||
exists.
|
||||
2. **The store module's own tools, in Go.** Chosen. They replace the TypeScript client nothing builds.
|
||||
2. **A module's own tools, in Go, on the machine that holds the store.** Chosen. Not the store module
|
||||
itself: a module that provides the artifact store may not build an artifact, because building
|
||||
publishes to the store, so the tools are a second module, `artifact-store-tools`, assigned beside the
|
||||
store. The store module's unbuilt TypeScript client goes.
|
||||
3. *The controller's verbs.* The controller holds the records but not the store's files; the store may
|
||||
move to a machine the controller is not on. Rejected for everything except what only the records can
|
||||
answer.
|
||||
@@ -52,7 +55,7 @@ registry, and pruning of unused images on a machine — each a dry run unless as
|
||||
**For what the store tools read.** The store's door lists repositories and tags, but not a manifest no
|
||||
tag names — and since the mesh pins by digest, that is almost every manifest. Only the store's files
|
||||
list them, with each blob's size. So the tools read the store's own files, read-only, through the
|
||||
store's own container, and read each manifest's content through the door. The registry's own
|
||||
store's own container, manifests' content included. The registry's own
|
||||
`garbage-collect --dry-run` was weighed and rejected as the source: it says what is unmarked, but not
|
||||
how large, and not what letting go of a manifest would free.
|
||||
|
||||
@@ -84,29 +87,33 @@ decides.
|
||||
|
||||
## Decision
|
||||
|
||||
**1. The store module answers for the store, with four tools of its own.** The distribution module,
|
||||
holder of `mesh-artifact-store`, serves a Go bundle in place of its unbuilt TypeScript:
|
||||
**1. A module beside the store answers for it, with four tools.** The module `artifact-store-tools`,
|
||||
assigned to the machine that holds `mesh-artifact-store`, serves a Go bundle. The store module itself
|
||||
cannot carry it, because a module providing the artifact store may not build an artifact; and the
|
||||
tools are named for the artifact store, because *store* alone is the database server:
|
||||
|
||||
- `store_repositories` — every repository, its tags, how many manifests it holds and its size;
|
||||
- `store_usage` — the store's size, the largest repositories, what blobs are shared, and what the
|
||||
- `artifact_store_repositories` — every repository, its tags, how many manifests it holds and its size;
|
||||
- `artifact_store_usage` — the store's size, the largest repositories, what blobs are shared, and what the
|
||||
store's nightly collector would free now;
|
||||
- `store_references` — what the records say of each manifest the store holds (below), and what the
|
||||
- `artifact_store_references` — what the records say of each manifest the store holds (below), and what the
|
||||
records keep that the store does not hold;
|
||||
- `store_collect` — a dry run unless `dry_run` is false; a real run needs `why`.
|
||||
- `artifact_store_collect` — a dry run unless `dry_run` is false; a real run needs `why`.
|
||||
|
||||
The tools read the store's files through the store's own container and only read them. The first three
|
||||
change nothing; `store_collect` changes nothing either, unless it is a real run, and then only by asking
|
||||
The tools read the store's files, manifests included, through the store's own container and only read
|
||||
them. The first three
|
||||
change nothing; `artifact_store_collect` changes nothing either, unless it is a real run, and then only by asking
|
||||
the controller (point 3).
|
||||
|
||||
**2. The records are asked, never copied.** A new controller verb, `artifacts`, answers every
|
||||
reference the mesh recorded making, with its state: *kept* because a definition names it, *kept*
|
||||
because it belongs to one of the five most recent builds of a module the mesh holds, *eligible* (made,
|
||||
not kept, not yet let go), or — when asked — *collected*. `store_references` sets that beside what the
|
||||
not kept, not yet let go), or — when asked — *collected*. `artifact_store_references` sets that beside what the
|
||||
store holds and says, for every manifest, one of:
|
||||
|
||||
- **kept**, with the reason;
|
||||
- **a holder of a kept archive** (the manifest that keeps an archive's blob, [issue 253](../04-ISSUES/253-the-stores-collector-would-delete-every-archive-the-mesh-keeps/00-report.md));
|
||||
- **eligible**, or a holder of an eligible archive;
|
||||
- **let go of, yet present** — the controller recorded letting it go and the store still holds it;
|
||||
- **a named document** — something the controller keeps under a tag (to-be 45 §9);
|
||||
- **unrecorded** — no record names it.
|
||||
|
||||
@@ -116,7 +123,7 @@ record.** ADR 0189 §3 stands as written.
|
||||
**3. Collecting on demand is the same sweep, asked by a person.** A new controller verb, `collect`,
|
||||
says what the sweep would let go of, and does it only with `confirm` and a `why`. A real run holds every
|
||||
kept archive before it lets anything go, exactly as the sweep after a build does; it is bounded by a
|
||||
count and a time, says what it left; and it is recorded as a hand-act with its `why`. `store_collect`'s
|
||||
count and a time, says what it left; and it is recorded as a hand-act with its `why`. `artifact_store_collect`'s
|
||||
dry run adds what only the store knows: how many bytes the nightly collector would free once those
|
||||
manifests are gone, beside what it would free tonight anyway. Its real run asks `collect`. Bytes are
|
||||
still reclaimed by the nightly collector, because only it runs with the store held still.
|
||||
|
||||
@@ -3,7 +3,7 @@ layer: to-be
|
||||
status: in-progress
|
||||
code:
|
||||
- mesh-controller cmd/mesh-controller (the verbs artifacts, collect and images)
|
||||
- mesh-catalog modules/distribution (the store's tools)
|
||||
- mesh-catalog modules/artifact-store-tools (the store's tools), modules/distribution (its unbuilt code removed)
|
||||
- mesh-catalog modules/gitea (package retention)
|
||||
- mesh-catalog modules/docker (image pruning)
|
||||
updated: 2026-10-08
|
||||
@@ -28,9 +28,10 @@ extending [ADR 0189](../../02-DECISIONS/0189-the-store-keeps-what-the-records-na
|
||||
controller (records)
|
||||
artifacts ──┐ collect ──┐ images ──┐
|
||||
│ │ │
|
||||
store module ─────┴─────────────┘ │
|
||||
(store_repositories, store_usage, │
|
||||
store_references, store_collect) │
|
||||
┌─────────────────┴─────────────┘ │
|
||||
artifact-store-tools │
|
||||
(artifact_store_repositories, _usage, │
|
||||
_references, _collect) │
|
||||
│ reads the store's files │
|
||||
│ through its own container │
|
||||
▼ │
|
||||
@@ -52,7 +53,8 @@ extending [ADR 0189](../../02-DECISIONS/0189-the-store-keeps-what-the-records-na
|
||||
The store keeps each blob once, named by its digest, with its size on disk. Each repository lists the
|
||||
manifests it holds (every one, whether a tag names it or not), its tags, and the layers it may serve.
|
||||
The tools list those files through the store's own container, read-only, and read each manifest's
|
||||
content through the store's door. Nothing is written.
|
||||
content the same way. Nothing is written. The tools are their own module, `artifact-store-tools`,
|
||||
assigned to the machine that holds the store: the store's module may not build an artifact itself.
|
||||
|
||||
From that, a manifest *marks* its own blob, its configuration and each layer, and an index marks the
|
||||
manifests it lists. The store's nightly collector removes every blob no manifest marks. The tools work
|
||||
@@ -60,15 +62,15 @@ the same mark, so their numbers are the collector's.
|
||||
|
||||
### What each tool answers
|
||||
|
||||
- **`store_repositories`** — each repository with its tags, its manifest count and its size: the sum of
|
||||
- **`artifact_store_repositories`** — each repository with its tags, its manifest count and its size: the sum of
|
||||
the blobs its manifests mark. A blob shared by two repositories is counted in each, and the answer
|
||||
says so.
|
||||
- **`store_usage`** — the store's total size; the largest repositories; the bytes in blobs that more
|
||||
- **`artifact_store_usage`** — the store's total size; the largest repositories; the bytes in blobs that more
|
||||
than one repository marks; and the bytes in blobs no manifest marks, which is what the nightly
|
||||
collector frees next.
|
||||
- **`store_references`** — for every manifest, one state (below), counted and sized by repository, and
|
||||
- **`artifact_store_references`** — for every manifest, one state (below), counted and sized by repository, and
|
||||
listed when one repository is asked about. Then what the records keep that the store does not hold.
|
||||
- **`store_collect`** — the dry run: what the controller would let go of, and how many bytes the nightly
|
||||
- **`artifact_store_collect`** — the dry run: what the controller would let go of, and how many bytes the nightly
|
||||
collector would free once those are gone. A real run with `dry_run` false and a `why` asks the
|
||||
controller's `collect`, and answers what it did.
|
||||
|
||||
@@ -80,6 +82,7 @@ the same mark, so their numbers are the collector's.
|
||||
| kept — recent build | one of the five most recent builds of a module the mesh holds | no |
|
||||
| holder of a kept archive | the manifest that keeps a kept archive's blob | no |
|
||||
| eligible | the mesh made it and keeps it for no reason | yes, through the controller |
|
||||
| let go of, yet present | the controller recorded letting it go, and the store still holds it | no — said, for a person to look at |
|
||||
| holder of an eligible archive | the manifest that keeps an eligible archive's blob | yes, with its archive |
|
||||
| named document | a manifest the controller keeps under a tag (to-be 45 §9) | no |
|
||||
| unrecorded | no record names it | no — counted and sized only |
|
||||
|
||||
Reference in New Issue
Block a user