|
|
|
@@ -148,3 +148,75 @@ makes the drift worse while hiding it.
|
|
|
|
|
| Nothing is announced that was not made | A build made to fail announces nothing, and the catalogue's graph is unchanged afterwards. |
|
|
|
|
|
| A build keeps what it was told | A catalogue started after a build asks for what it missed and receives the manifest and the artifacts stood on, not a summary. |
|
|
|
|
|
| The toolchain is the mesh's, not the author's | Changing the toolchain makes every module built against it stale, and each names what moved. |
|
|
|
|
|
|
|
|
|
|
## The whole surface, in one place
|
|
|
|
|
|
|
|
|
|
**A reference, and it is kept true by a test rather than by care.** A table like this goes stale the
|
|
|
|
|
day somebody adds a field, so `mesh-catalog/modules/showcase` is a module that uses all of it, and
|
|
|
|
|
`TestTheShowcaseModuleIsAValidManifest` fails when it stops doing so. Read the module when this
|
|
|
|
|
disagrees with it.
|
|
|
|
|
|
|
|
|
|
### What a module declares
|
|
|
|
|
|
|
|
|
|
| field | is |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `module`, `version`, `slug` | its identity; the slug is the short name generated names are built from |
|
|
|
|
|
| `capabilities` | what a machine must have for this to run there |
|
|
|
|
|
| `provides` | **the shared seat** — several modules may fill one capability and coexist |
|
|
|
|
|
| `claims` | **the exclusive seat** — two modules claiming one thing in a scope cannot both be assigned there |
|
|
|
|
|
| `serves` | what a consumer must know to connect. The mesh fills in the assigned port ([ADR 0038](../../02-DECISIONS/0038-the-mesh-assigns-the-port.md)) |
|
|
|
|
|
| `requires` | what must be provided by something on the same node |
|
|
|
|
|
| `binds` | where the mesh writes what a requirement resolved to |
|
|
|
|
|
| `secrets` | where the mesh seals the credential for a requirement |
|
|
|
|
|
| `own-secrets` | secrets that are the module's own — a superuser, a broker account |
|
|
|
|
|
| `emits` / `consumes` | the event graph: 1:many, broadcast, no credential |
|
|
|
|
|
| `listens` | the port **its own software** uses, and from where. Filtering is computed from these |
|
|
|
|
|
| `contributes` / `receives` | values one module adds to another's configuration, and the other half |
|
|
|
|
|
| `accesses` | operator-owned paths it may use and must not own ([ADR 0051](../../02-DECISIONS/0051-shared-data-is-the-operators.md)) |
|
|
|
|
|
| `certificate` | a certificate for a name it serves |
|
|
|
|
|
| `grants` | credentials it must create for its consumers |
|
|
|
|
|
| `filtering` | rules beyond its own ports |
|
|
|
|
|
| `computed` | marks a module the control plane generates rather than an author writing |
|
|
|
|
|
| `build.artifacts` | what it produces |
|
|
|
|
|
|
|
|
|
|
### What it builds
|
|
|
|
|
|
|
|
|
|
| kind | is |
|
|
|
|
|
|---|---|
|
|
|
|
|
| `bundle` | its own code, compiled by the toolchain its language implies, then packed |
|
|
|
|
|
| `archive` | a directory, packed as it stands |
|
|
|
|
|
| `image` | built from a Dockerfile — for software that needs a particular base |
|
|
|
|
|
| `upstream` | somebody else's image, mirrored and pinned by a digest this mesh assigned |
|
|
|
|
|
|
|
|
|
|
### What it puts on a machine
|
|
|
|
|
|
|
|
|
|
| resource | is | a module may |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| `directory` | a directory with a mode and an owner | ✅ |
|
|
|
|
|
| `file` | literal content, with `${bound:…}` and `${secret:…}` filled in | ✅ |
|
|
|
|
|
| `user` | a login | ✅ |
|
|
|
|
|
| `access` | a pre-existing path it may use and must not own | ✅ |
|
|
|
|
|
| `archive` | files fetched by digest and unpacked | ✅ |
|
|
|
|
|
| `package` | a package that must be present | ✅ |
|
|
|
|
|
| `network` | a named container network | ✅ |
|
|
|
|
|
| `container` | an image, in three modes | ✅ |
|
|
|
|
|
| `process` | **its own code**, in three modes | ✅ |
|
|
|
|
|
| `service` | an **existing** unit put into a state | for software shipping its own unit |
|
|
|
|
|
| `action` | a command to run | ❌ **refused** — [ADR 0005](../../02-DECISIONS/0005-the-node-host.md) |
|
|
|
|
|
|
|
|
|
|
**The two at the bottom are the interesting rows.** `action` is refused outright: the link may not
|
|
|
|
|
carry a command, so a module needing something done ships a program that reconciles — which is what
|
|
|
|
|
a run-once `process` is. `service` installs no unit by design, which is right for software that
|
|
|
|
|
ships one and wrong for code the mesh built, which has no unit until the mesh writes it.
|
|
|
|
|
|
|
|
|
|
### How its code runs, and what that code can be
|
|
|
|
|
|
|
|
|
|
| mode | is | | shape | loaded by |
|
|
|
|
|
|---|---|---|---|---|
|
|
|
|
|
| *(default)* | a unit restarted when it exits | | tools | a tool host, over the broker |
|
|
|
|
|
| `run-once` | run to completion; what follows is gated on it | | event consumer | the same host, reacting |
|
|
|
|
|
| `schedule` | a timer; a missed fire happens when the machine returns | | provisioner | invoked when a consumer is granted |
|
|
|
|
|
| | | | a process | the machine's supervisor |
|
|
|
|
|
|
|
|
|
|
**Tools, hooks and consumers are not further modes**, which is the test of whether three is the
|
|
|
|
|
right number: they are loaded by a tool host, and a tool host is a process that stays up.
|
|
|
|
|