Unify trunk on main: initialization → main #3
@@ -39,17 +39,22 @@ test:
|
|||||||
build:
|
build:
|
||||||
CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o mesh-host ./cmd/mesh-host
|
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:
|
host:
|
||||||
@test -n "$(BUNDLE)" || { echo "BUNDLE= is required; a host with no bundle cannot raise a first node"; exit 1; }
|
@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; }
|
@test -f "$(BUNDLE)" || { echo "no such bundle: $(BUNDLE)"; exit 1; }
|
||||||
@cp internal/bundle/substrate.lock internal/bundle/substrate.lock.default
|
@test -f internal/bundle/substrate-$(SYSTEM).lock || { echo "no bundle slot for SYSTEM=$(SYSTEM)"; exit 1; }
|
||||||
@cp "$(BUNDLE)" internal/bundle/substrate.lock
|
@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; \
|
@CGO_ENABLED=0 go build -ldflags="$(LDFLAGS)" -o mesh-host ./cmd/mesh-host; \
|
||||||
status=$$?; \
|
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
|
exit $$status
|
||||||
@echo "built carrying $(BUNDLE)"
|
@echo "built for $(SYSTEM) carrying $(BUNDLE)"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f mesh-host
|
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.
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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.
|
// 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
|
// **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.
|
// 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
|
// 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
|
// 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
|
// yet known: novox/hq research 012 asks what the minimum actually is, and research 011 is
|
||||||
|
|||||||
Reference in New Issue
Block a user