Unify trunk on main: initialization → main #3
@@ -39,17 +39,22 @@ test:
|
||||
build:
|
||||
CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o mesh-host ./cmd/mesh-host
|
||||
|
||||
# A host for a real machine, carrying a real bundle: make host BUNDLE=path/to/substrate.lock
|
||||
# A host for a real machine, carrying a real bundle:
|
||||
# make host SYSTEM=arch BUNDLE=path/to/substrate.lock
|
||||
#
|
||||
# The bundle replaces the one for SYSTEM, because its contents are per operating system —
|
||||
# package names and unit names differ (novox/hq ADR 0005).
|
||||
host:
|
||||
@test -n "$(BUNDLE)" || { echo "BUNDLE= is required; a host with no bundle cannot raise a first node"; exit 1; }
|
||||
@test -f "$(BUNDLE)" || { echo "no such bundle: $(BUNDLE)"; exit 1; }
|
||||
@cp internal/bundle/substrate.lock internal/bundle/substrate.lock.default
|
||||
@cp "$(BUNDLE)" internal/bundle/substrate.lock
|
||||
@test -f internal/bundle/substrate-$(SYSTEM).lock || { echo "no bundle slot for SYSTEM=$(SYSTEM)"; exit 1; }
|
||||
@cp internal/bundle/substrate-$(SYSTEM).lock internal/bundle/substrate-$(SYSTEM).lock.default
|
||||
@cp "$(BUNDLE)" internal/bundle/substrate-$(SYSTEM).lock
|
||||
@CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o mesh-host ./cmd/mesh-host; \
|
||||
status=$$?; \
|
||||
mv internal/bundle/substrate.lock.default internal/bundle/substrate.lock; \
|
||||
mv internal/bundle/substrate-$(SYSTEM).lock.default internal/bundle/substrate-$(SYSTEM).lock; \
|
||||
exit $$status
|
||||
@echo "built carrying $(BUNDLE)"
|
||||
@echo "built for $(SYSTEM) carrying $(BUNDLE)"
|
||||
|
||||
clean:
|
||||
rm -f mesh-host
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Examples
|
||||
|
||||
## `substrate-first-node.lock`
|
||||
|
||||
What an Arch machine must be before a mesh exists — the first steps of the bootstrap in
|
||||
[novox/hq `07-the-substrate.md`](https://git.novox.be/novox/hq): a container runtime, a store
|
||||
running, and the control plane's database created inside it.
|
||||
|
||||
**It stops there**, and the file says why: loading the control plane's schema and starting the
|
||||
control plane are the next two steps, and there is no control plane yet. A bundle naming one
|
||||
would be a bundle that cannot be applied.
|
||||
|
||||
Build a host carrying it:
|
||||
|
||||
```
|
||||
make host SYSTEM=arch BUNDLE=examples/substrate-first-node.lock
|
||||
```
|
||||
|
||||
**The image reference has to be replaced before this is useful.** It is written as
|
||||
`REGISTRY/postgres@DIGEST` because the digest belongs to whatever registry serves it — in the
|
||||
lab, one the scenario raises, which reports its digests when it comes up. That is not a
|
||||
placeholder to be tidied away: a bundle is built *for a target*, and which registry that target
|
||||
pulls from is part of the target.
|
||||
|
||||
Verified end to end in a lab machine with no route out: five resources applied, idempotent on a
|
||||
second run, and `mesh` present in the store afterwards.
|
||||
@@ -0,0 +1,57 @@
|
||||
// substrate-arch.lock — what an Arch machine must be before a mesh exists.
|
||||
//
|
||||
// The first three steps of the bootstrap (novox/hq 03-DESIGN/01-to-be/07-the-substrate.md).
|
||||
// Steps four and five — load the control plane's schema, start the control plane — are absent
|
||||
// because the control plane does not exist yet. A bundle that named it would be a bundle that
|
||||
// cannot be applied.
|
||||
//
|
||||
// PINNED BY DIGEST, and the digest is not decoration: a tag can be made to point at a different
|
||||
// image, and this file is applied on a machine with no mesh to ask about anything.
|
||||
//
|
||||
// The store's data is a NAMED VOLUME rather than a directory on the machine. A directory the
|
||||
// host creates is owned by root, and the database runs as somebody else inside the container —
|
||||
// so it could not write, and the container crash-looped. A named volume lets the image set up
|
||||
// its own ownership, which is what it is for. It also outlives the container, which is what you
|
||||
// want for the thing holding the mesh's state.
|
||||
{
|
||||
"declaration": 1,
|
||||
"resources": [
|
||||
{
|
||||
"id": "container-runtime",
|
||||
"type": "package",
|
||||
"package": "docker"
|
||||
},
|
||||
{
|
||||
"id": "container-runtime-running",
|
||||
"type": "service",
|
||||
"unit": "docker.service",
|
||||
"state": "running",
|
||||
"boot": "enabled"
|
||||
},
|
||||
{
|
||||
"id": "store",
|
||||
"type": "container",
|
||||
"name": "mesh-store",
|
||||
"image": "REGISTRY/postgres@DIGEST",
|
||||
"env": {
|
||||
"POSTGRES_PASSWORD": "bootstrap",
|
||||
"PGDATA": "/var/lib/postgresql/data/pgdata"
|
||||
},
|
||||
"volumes": ["mesh-store-data:/var/lib/postgresql/data"]
|
||||
},
|
||||
{
|
||||
"id": "store-ready",
|
||||
"type": "action",
|
||||
"in": "mesh-store",
|
||||
"command": ["sh", "-c", "for i in $(seq 1 60); do pg_isready -U postgres >/dev/null 2>&1 && exit 0; sleep 1; done; exit 1"],
|
||||
"verify": ["pg_isready", "-U", "postgres"]
|
||||
},
|
||||
{
|
||||
"id": "control-plane-database",
|
||||
"type": "action",
|
||||
"in": "mesh-store",
|
||||
"command": ["sh", "-c", "psql -U postgres -c 'CREATE DATABASE mesh'"],
|
||||
"verify": ["sh", "-c", "psql -U postgres -lqt | cut -d'|' -f1 | grep -qw mesh"]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// substrate-alpine.lock — the pinned tier-1 descriptor the ALPINE host carries.
|
||||
//
|
||||
// Per system, because its CONTENTS are: this one names apk packages and OpenRC services where
|
||||
// the arch bundle names pacman packages and systemd units (novox/hq ADR 0060).
|
||||
// the arch bundle names pacman packages and systemd units (novox/hq ADR 0005).
|
||||
//
|
||||
// Empty on purpose. What belongs here is the closure for a one-node mesh, and that is not
|
||||
// yet known: novox/hq research 012 asks what the minimum actually is, and research 011 is
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// The substrate is a container runtime, a store and the control plane (novox/hq
|
||||
// 07-the-substrate.md). An android host implements `file`, `directory` and `action` and refuses
|
||||
// `package`, `container` and `service` (ADR 0060) — so every step of the bootstrap is a shape it
|
||||
// `package`, `container` and `service` (ADR 0005) — so every step of the bootstrap is a shape it
|
||||
// does not have. No amount of filling this in changes that.
|
||||
//
|
||||
// **A partial host can JOIN a mesh and cannot BE the first node.** That is a real distinction
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// substrate-arch.lock — the pinned tier-1 descriptor the ARCH host carries.
|
||||
//
|
||||
// Per system, because its CONTENTS are: package names, unit names and service names all differ
|
||||
// (novox/hq ADR 0060). The mechanism is shared; what it names is not.
|
||||
// (novox/hq ADR 0005). The mechanism is shared; what it names is not.
|
||||
//
|
||||
// Empty on purpose. What belongs here is the closure for a one-node mesh, and that is not
|
||||
// yet known: novox/hq research 012 asks what the minimum actually is, and research 011 is
|
||||
|
||||
Reference in New Issue
Block a user