An example may not name an image nothing builds
Found by reading the manifests rather than by running them. Two of the provisioner images the examples name had no way to be produced: the object store's had a Dockerfile and no target, and Keycloak's did not exist at all — no image, no Dockerfile, no program. A module naming an image nothing produces resolves, plans, pushes and stops on the machine at `docker pull`, which is the fault arriving as far from its cause as it can get. The object store's target is added. Keycloak's provisioner is removed from its manifest, because writing a manifest for a program that does not exist is the same mistake as the .env files: it parses, it resolves, and it could never work. That makes keycloak's manifest true about today — a server the mesh runs, with its database and its admin credential — and it makes the gap loud. Keycloak no longer claims to provide oidc-client, so a consumer asking for one is refused at plan time by name, rather than resolving cleanly and never having a client created. The check covers only images beginning `mesh-`. Postgres and the rest come from a registry and are somebody else's to build; what this bounds is the set this repository is responsible for and might forget.
This commit is contained in:
@@ -53,6 +53,17 @@ provisioner-image:
|
||||
@echo
|
||||
@docker image inspect $(PROVISIONER_IMAGE) --format 'built {{.RepoTags}} {{.Size}} bytes'
|
||||
|
||||
# The object store's provisioner, for the same reason: a bucket and a policy are not files, and
|
||||
# the mesh cannot make them -- it discarded the credential it would have to use.
|
||||
OBJECTSTORE_IMAGE ?= mesh-provision-objectstore:$(VERSION)
|
||||
OBJECTSTORE_DEV_TAG ?= mesh-provision-objectstore:development
|
||||
|
||||
objectstore-image:
|
||||
docker build -f examples/objectstore-provisioner/Dockerfile \
|
||||
-t $(OBJECTSTORE_IMAGE) -t $(OBJECTSTORE_DEV_TAG) .
|
||||
@echo
|
||||
@docker image inspect $(OBJECTSTORE_IMAGE) --format 'built {{.RepoTags}} {{.Size}} bytes'
|
||||
|
||||
# The proxy that turns a route grant into traffic reaching a workload.
|
||||
PROXY_IMAGE ?= mesh-route-proxy:$(VERSION)
|
||||
PROXY_DEV_TAG ?= mesh-route-proxy:development
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"binds": {"postgres-database": "/var/lib/keycloak/database.json"},
|
||||
"secrets": {"postgres-database": "/var/lib/keycloak/database.secret"},
|
||||
|
||||
"provides": [{"name": "oidc-client", "scope": "mesh"}],
|
||||
"capabilities": ["container-runtime"],
|
||||
|
||||
"listens": [
|
||||
@@ -17,18 +16,10 @@
|
||||
"why": "anything the mesh runs that authenticates a person"}
|
||||
],
|
||||
|
||||
"serves": {
|
||||
"oidc-client": {"port": 8080, "realm": "mesh", "scheme": "http"}
|
||||
},
|
||||
|
||||
"receives": {"oidc-client": "/var/lib/keycloak/grants/mesh.json"},
|
||||
"grants": {"oidc-client": "/var/lib/keycloak/grants"},
|
||||
|
||||
"own-secrets": {"admin": "/var/lib/keycloak/admin.secret"},
|
||||
|
||||
"resources": [
|
||||
{"id": "state", "type": "directory", "path": "/var/lib/keycloak", "mode": "0700"},
|
||||
{"id": "grants", "type": "directory", "path": "/var/lib/keycloak/grants", "mode": "0700"},
|
||||
|
||||
{"id": "admin-env", "type": "file", "path": "/var/lib/keycloak/admin.env", "mode": "0600",
|
||||
"content": "KEYCLOAK_ADMIN=admin\nKEYCLOAK_ADMIN_PASSWORD=${secret:admin}\n"},
|
||||
@@ -45,22 +36,6 @@
|
||||
"env": {"KC_DB": "postgres", "KC_HTTP_ENABLED": "true", "KC_HEALTH_ENABLED": "true"},
|
||||
"env-file": ["/var/lib/keycloak/admin.env", "/var/lib/keycloak/database.env"],
|
||||
"ports": ["8080:8080"],
|
||||
"restart-on": ["admin-env", "database-env"]},
|
||||
|
||||
{"id": "provisioner", "type": "container", "name": "mesh-provision-keycloak",
|
||||
"image": "mesh-provision-keycloak@sha256:0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"network": "keycloak",
|
||||
"env": {
|
||||
"GRANTS": "/var/lib/keycloak/grants",
|
||||
"MESH_KEYCLOAK_URL": "http://keycloak:8080",
|
||||
"MESH_KEYCLOAK_REALM": "mesh",
|
||||
"MESH_KEYCLOAK_ADMIN": "admin",
|
||||
"MESH_KEYCLOAK_ADMIN_PASSWORD_FILE": "/run/secrets/admin"
|
||||
},
|
||||
"volumes": [
|
||||
"/var/lib/keycloak/grants:/var/lib/keycloak/grants:ro",
|
||||
"/var/lib/keycloak/admin.secret:/run/secrets/admin:ro"
|
||||
],
|
||||
"restart-on": ["grants", "admin-env"]}
|
||||
"restart-on": ["admin-env", "database-env"]}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -462,3 +462,46 @@ func declareOnItsOwn(t *testing.T, shelf map[string]catalogue.Manifest,
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Every image an example names is one this repository builds.
|
||||
//
|
||||
// A manifest naming an image nothing produces is a module that resolves, plans, pushes, and stops
|
||||
// on the machine at `docker pull` — the fault arriving as far from its cause as it can get. Two of
|
||||
// these were found by reading the manifests rather than by running them: the object store's
|
||||
// provisioner had a Dockerfile and no target, and Keycloak's did not exist at all.
|
||||
//
|
||||
// Only the mesh's own images are checked. `postgres`, `redis` and the rest come from a registry
|
||||
// and are somebody else's to build; what this bounds is the set this repository is responsible
|
||||
// for and might forget.
|
||||
func TestEveryImageTheExamplesNameIsOneThisRepositoryBuilds(t *testing.T) {
|
||||
makefile, err := os.ReadFile(filepath.Join("..", "..", "Makefile"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
found, _ := filepath.Glob("*.json")
|
||||
var checked int
|
||||
for _, name := range found {
|
||||
for _, r := range read(t, name).Resources {
|
||||
image, ok := r["image"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
repository, _, _ := strings.Cut(image, "@")
|
||||
if !strings.HasPrefix(repository, "mesh-") {
|
||||
continue
|
||||
}
|
||||
checked++
|
||||
if !strings.Contains(string(makefile), repository+":") {
|
||||
t.Errorf(
|
||||
"%s names the image %q and nothing in this repository builds one. A module "+
|
||||
"naming an image that does not exist resolves, plans, pushes, and stops "+
|
||||
"on the machine at `docker pull`",
|
||||
name, repository)
|
||||
}
|
||||
}
|
||||
}
|
||||
if checked == 0 {
|
||||
t.Fatal("no example names an image this repository builds, so this proves nothing")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user