Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79f44386d2 | ||
|
|
80df1b6361 | ||
|
|
816cf96459 | ||
|
|
3f05df5d1a |
@@ -23,10 +23,10 @@ func TestModuleCheckRefusesAnIdentityThatOverflowsWhatItRequires(t *testing.T) {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
objects := write("objects", `{"module":"objects","version":"1",
|
objects := write("objects", `{"module":"objects","version":"1",
|
||||||
"provides":[{"name":"s3-bucket","scope":"mesh","identity":{"max":20,"in":"an S3 access key"}}],
|
"provides":[{"name":"s3-bucket","scope":"mesh","identity":{"max":20,"in":"an S3 access key"},"credential":{"form":"pair"}}],
|
||||||
"receives":{"s3-bucket":"/var/lib/mesh/objects/mesh.json"}}`)
|
"receives":{"s3-bucket":"/var/lib/mesh/objects/mesh.json"}}`)
|
||||||
resolver := write("resolver", `{"module":"resolver","version":"1",
|
resolver := write("resolver", `{"module":"resolver","version":"1",
|
||||||
"provides":[{"name":"wildcard-resolution","scope":"mesh","identity":false}]}`)
|
"provides":[{"name":"wildcard-resolution","scope":"mesh","identity":false,"credential":{"form":"none"}}]}`)
|
||||||
album := write("photoalbum", `{"module":"photoalbum","version":"1","requires":["s3-bucket"]}`)
|
album := write("photoalbum", `{"module":"photoalbum","version":"1","requires":["s3-bucket"]}`)
|
||||||
nm := write("networkmanager", `{"module":"networkmanager","version":"1","requires":["wildcard-resolution"]}`)
|
nm := write("networkmanager", `{"module":"networkmanager","version":"1","requires":["wildcard-resolution"]}`)
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,9 @@ func TestANeedIsIssuedToItsHolderOnlyWhereTheProviderIsMovedAndItsSoftwareIssues
|
|||||||
offer := catalogue.Offer{Name: "gitea-read", Scope: catalogue.ScopeMesh}
|
offer := catalogue.Offer{Name: "gitea-read", Scope: catalogue.ScopeMesh}
|
||||||
if issued {
|
if issued {
|
||||||
offer.Credential = &catalogue.OfferCredential{IssuedBy: catalogue.IssuedBySoftware, Tool: "gitea_agent_token"}
|
offer.Credential = &catalogue.OfferCredential{IssuedBy: catalogue.IssuedBySoftware, Tool: "gitea_agent_token"}
|
||||||
|
} else {
|
||||||
|
// A login of each consumer's own, said: an offer naming no form has no credential (mesh-sdk 6b8c694).
|
||||||
|
offer.Credential = &catalogue.OfferCredential{Form: catalogue.CredentialFormPair}
|
||||||
}
|
}
|
||||||
return catalogue.Manifest{Module: "gitea", Version: "1", Moved: moved, Provides: []catalogue.Offer{offer}}
|
return catalogue.Manifest{Module: "gitea", Version: "1", Moved: moved, Provides: []catalogue.Offer{offer}}
|
||||||
}
|
}
|
||||||
@@ -216,8 +219,10 @@ func TestANeedIsIssuedToItsHolderOnlyWhereTheProviderIsMovedAndItsSoftwareIssues
|
|||||||
// marked moved; another module is not.
|
// marked moved; another module is not.
|
||||||
func TestTheModuleHoldingTheVaultSeatCountsAsMovedForItsConsumers(t *testing.T) {
|
func TestTheModuleHoldingTheVaultSeatCountsAsMovedForItsConsumers(t *testing.T) {
|
||||||
vault := catalogue.Manifest{Module: "mesh-vault", Version: "1", Claims: []catalogue.Claim{{Name: "mesh-vault", Scope: catalogue.ScopeMesh}},
|
vault := catalogue.Manifest{Module: "mesh-vault", Version: "1", Claims: []catalogue.Claim{{Name: "mesh-vault", Scope: catalogue.ScopeMesh}},
|
||||||
Provides: []catalogue.Offer{{Name: "secret", Scope: catalogue.ScopeMesh}}}
|
Provides: []catalogue.Offer{{Name: "secret", Scope: catalogue.ScopeMesh,
|
||||||
other := catalogue.Manifest{Module: "mesh-vault", Version: "1", Provides: []catalogue.Offer{{Name: "secret", Scope: catalogue.ScopeMesh}}}
|
Credential: &catalogue.OfferCredential{Form: catalogue.CredentialFormPair}}}}
|
||||||
|
other := catalogue.Manifest{Module: "mesh-vault", Version: "1", Provides: []catalogue.Offer{{Name: "secret", Scope: catalogue.ScopeMesh,
|
||||||
|
Credential: &catalogue.OfferCredential{Form: catalogue.CredentialFormPair}}}}
|
||||||
if got := needOf(t, map[string]catalogue.Manifest{"mesh-vault": vault}, "mesh-vault", "gitea", "secret"); !got.IssuedToHolder || !got.ProviderMoved {
|
if got := needOf(t, map[string]catalogue.Manifest{"mesh-vault": vault}, "mesh-vault", "gitea", "secret"); !got.IssuedToHolder || !got.ProviderMoved {
|
||||||
t.Errorf("the vault's consumer is not answered by a moved provider: %+v", got)
|
t.Errorf("the vault's consumer is not answered by a moved provider: %+v", got)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module github.com/novox/mesh-controller
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029233535-78c9ec881771
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030001116-2da0de75c3f0
|
||||||
github.com/jackc/pgx/v5 v5.10.0
|
github.com/jackc/pgx/v5 v5.10.0
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
git.novox.be/novox/mesh-host v0.0.0-20261018171808-9d9e3a46c4f5 h1:E5stfIeCN6uYgA9TCv+4K8JgaURg3zQppvUgJLaDMP4=
|
git.novox.be/novox/mesh-host v0.0.0-20261018171808-9d9e3a46c4f5 h1:E5stfIeCN6uYgA9TCv+4K8JgaURg3zQppvUgJLaDMP4=
|
||||||
git.novox.be/novox/mesh-host v0.0.0-20261018171808-9d9e3a46c4f5/go.mod h1:4wyoCr6IIIIarEUuROThWDj7DAvJvIidqMjWcpSnOwE=
|
git.novox.be/novox/mesh-host v0.0.0-20261018171808-9d9e3a46c4f5/go.mod h1:4wyoCr6IIIIarEUuROThWDj7DAvJvIidqMjWcpSnOwE=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029233535-78c9ec881771 h1:Tt16HJk8JZRce1i3JzzDSNdCWOrv7dw8FQ/bckNQ5Ig=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030001116-2da0de75c3f0 h1:lKU3HjNXGiVbLW2hUgFjU/TMTUYMlNnnmZxG5T7biQA=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261029233535-78c9ec881771/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030001116-2da0de75c3f0/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
|||||||
Vendored
+2
-2
@@ -7,9 +7,9 @@ The copy carries the catalogue's private details: domains, first names in module
|
|||||||
private addresses. That is acceptable while mesh-controller is private; if it ever goes public, this copy is
|
private addresses. That is acceptable while mesh-controller is private; if it ever goes public, this copy is
|
||||||
a second place to clean besides the catalogue itself.
|
a second place to clean besides the catalogue itself.
|
||||||
|
|
||||||
mesh-catalog 3a1017f5594217092a654dd1e2d72226766bc16a modules/*/module.json, modules/*/files, modules/*/templates, predefined.json
|
mesh-catalog 8ae8e88dddc86c646de4d1be35919d109ab4c779 modules/*/module.json, modules/*/files, modules/*/templates, predefined.json
|
||||||
mesh-host 9d9e3a46c4f5943cfffb413d962ce48b75e2fd39 examples/foundation-first-node.lock
|
mesh-host 9d9e3a46c4f5943cfffb413d962ce48b75e2fd39 examples/foundation-first-node.lock
|
||||||
mesh-sdk 78c9ec8817710eae7f1a068aef68924293fdef59 conformance/events/module-event.json
|
mesh-sdk 2da0de75c3f0087cff9c2f5ef789ca6dc3c59045 conformance/events/module-event.json
|
||||||
|
|
||||||
To move them, from this repository's root, with the two repositories checked out beside it:
|
To move them, from this repository's root, with the two repositories checked out beside it:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
${seat:mesh-artifact-store:reach}
|
||||||
+46
-11
@@ -1,26 +1,52 @@
|
|||||||
{
|
{
|
||||||
"module": "artifact-store-tools",
|
"module": "artifact-store-tools",
|
||||||
"version": "1",
|
"version": "1",
|
||||||
|
"claims": [
|
||||||
|
{
|
||||||
|
"name": "mesh-artifact-sweep",
|
||||||
|
"scope": "mesh",
|
||||||
|
"serves": [
|
||||||
|
"artifacts",
|
||||||
|
"held",
|
||||||
|
"collect",
|
||||||
|
"mirrors",
|
||||||
|
"images"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requires": [
|
||||||
|
"artifact-store"
|
||||||
|
],
|
||||||
"invokes": [
|
"invokes": [
|
||||||
"seat:mesh-controller.artifacts",
|
"seat:mesh-hand-acts.hand-act",
|
||||||
"seat:mesh-controller.collect",
|
|
||||||
"mesh-catalog.catalog_modules",
|
"mesh-catalog.catalog_modules",
|
||||||
"mesh-catalog.catalog_module"
|
"mesh-catalog.catalog_module"
|
||||||
],
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-delivery-assigner.wants",
|
||||||
|
"mesh-delivery-builder.builds",
|
||||||
|
"mesh-delivery-builder.build-log",
|
||||||
|
"mesh-delivery-indexer.manifests",
|
||||||
|
"node-engine.have",
|
||||||
|
"mesh-controller.lease"
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
"findings"
|
||||||
|
],
|
||||||
"tools": [
|
"tools": [
|
||||||
"artifact_store_repositories",
|
"artifact_store_repositories",
|
||||||
"artifact_store_usage",
|
"artifact_store_usage",
|
||||||
"artifact_store_references",
|
"artifact_store_references",
|
||||||
"artifact_store_collect"
|
"artifact_store_collect"
|
||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"older-store-names": {
|
"older-store-names": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The names the artifact store had before, as host names or host:port separated by spaces, or none when it had no other. artifact_store_references reads every definition under these as well as under the store's current name, so an image a definition pins under one is said to be named by a definition (novox/hq issue 323).",
|
"description": "The names the artifact store had before, as host names or host:port separated by spaces, or none when it had no other. artifact_store_references reads every definition under these as well as under the store's current name, so an image a definition pins under one is said to be named by a definition (novox/hq issue 323).",
|
||||||
"pattern": "none|[A-Za-z0-9.:-]+( [A-Za-z0-9.:-]+)*",
|
"pattern": "none|[A-Za-z0-9.:-]+( [A-Za-z0-9.:-]+)*",
|
||||||
"default": "none"
|
"default": "none"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"resources": [
|
"resources": [
|
||||||
{
|
{
|
||||||
"id": "state",
|
"id": "state",
|
||||||
@@ -36,6 +62,14 @@
|
|||||||
"mode": "0600",
|
"mode": "0600",
|
||||||
"trusted": false,
|
"trusted": false,
|
||||||
"template": "files/store-names"
|
"template": "files/store-names"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "store-address",
|
||||||
|
"type": "file",
|
||||||
|
"path": "${dir:state}/store-address",
|
||||||
|
"mode": "0600",
|
||||||
|
"trusted": false,
|
||||||
|
"template": "files/store-address"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"build": {
|
"build": {
|
||||||
@@ -52,7 +86,8 @@
|
|||||||
],
|
],
|
||||||
"env": {
|
"env": {
|
||||||
"MESH_ARTIFACT_STORE_CONTAINER": "mesh-registry",
|
"MESH_ARTIFACT_STORE_CONTAINER": "mesh-registry",
|
||||||
"MESH_ARTIFACT_STORE_NAMES_FILE": "${dir:state}/store-names"
|
"MESH_ARTIFACT_STORE_NAMES_FILE": "${dir:state}/store-names",
|
||||||
|
"MESH_ARTIFACT_STORE_ADDRESS_FILE": "${dir:state}/store-address"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "rootless-image-build",
|
"name": "rootless-image-build",
|
||||||
"reach": "machine"
|
"reach": "machine",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"resources": [
|
"resources": [
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
"disk_filesystems",
|
"disk_filesystems",
|
||||||
"disk_folders",
|
"disk_folders",
|
||||||
"disk_devices",
|
"disk_devices",
|
||||||
"cpu_top"
|
"cpu_top",
|
||||||
|
"disk_readings",
|
||||||
|
"disk_measure"
|
||||||
],
|
],
|
||||||
"build": {
|
"build": {
|
||||||
"artifacts": [
|
"artifacts": [
|
||||||
@@ -23,5 +25,16 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"state": [
|
||||||
|
"readings"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-config.resolved",
|
||||||
|
"mesh-delivery-assigner.placement",
|
||||||
|
"mesh-delivery-builder.builds",
|
||||||
|
"mesh-delivery-indexer.manifests",
|
||||||
|
"mesh-delivery-indexer.modules",
|
||||||
|
"node-engine.have"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "artifact-store",
|
"name": "artifact-store",
|
||||||
"scope": "mesh"
|
"scope": "mesh",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"claims": [
|
"claims": [
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
# Written by the mesh (module dnsmasq, novox/hq issue 348). Replaced on every push.
|
# Written by the mesh (module dnsmasq, novox/hq issue 348). Replaced on every push.
|
||||||
#
|
#
|
||||||
# The resolver binds its addresses once, at start (bind-interfaces), so it starts only once this
|
# The resolver binds its addresses once, at start (bind-interfaces), so it starts only once this
|
||||||
# machine's private address is there: it waits up to 80 seconds for it, and a start that found it
|
# machine's private address is there: a start that finds it missing fails after at most two seconds and
|
||||||
# missing is tried again every ten seconds rather than left failed.
|
# is tried again every ten seconds (Restart=on-failure, no start limit) until the tunnel has brought it.
|
||||||
|
# It does not order itself After= or Wants= network-online.target, and its wait is short: the packaged
|
||||||
|
# unit is Before= network-online.target and nss-lookup.target, and the tunnel is ordered after them, so
|
||||||
|
# a long wait would hold the tunnel back and a drop-in ordering would be a cycle (issue 1126).
|
||||||
[Unit]
|
[Unit]
|
||||||
After=network-online.target
|
|
||||||
Wants=network-online.target
|
|
||||||
StartLimitIntervalSec=0
|
StartLimitIntervalSec=0
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStartPre=/usr/bin/sh -c 'for i in $(seq 1 80); do ip -4 -o addr show to ${machine:address} | grep -q . && exit 0; sleep 1; done; echo "${machine:address} is not on this machine" >&2; exit 1'
|
ExecStartPre=/usr/bin/sh -c 'for i in $(seq 1 2); do ip -4 -o addr show to ${machine:address} | grep -q . && exit 0; sleep 1; done; echo "${machine:address} is not on this machine" >&2; exit 1'
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=10s
|
RestartSec=10s
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
{
|
{
|
||||||
"name": "wildcard-resolution",
|
"name": "wildcard-resolution",
|
||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": false
|
"identity": false,
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"requires": [
|
"requires": [
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"privileged"
|
"privileged"
|
||||||
],
|
],
|
||||||
"invokes": [
|
"invokes": [
|
||||||
"seat:mesh-controller.images"
|
"seat:mesh-artifact-sweep.images"
|
||||||
],
|
],
|
||||||
"claims": [
|
"claims": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
],
|
],
|
||||||
"emits": [
|
"emits": [
|
||||||
"repo.created",
|
"repo.created",
|
||||||
|
"repo.writable",
|
||||||
"issue.opened",
|
"issue.opened",
|
||||||
"pull.merged",
|
"pull.merged",
|
||||||
"pull.updated",
|
"pull.updated",
|
||||||
@@ -181,6 +182,12 @@
|
|||||||
"trusted": true,
|
"trusted": true,
|
||||||
"default": {}
|
"default": {}
|
||||||
},
|
},
|
||||||
|
"check-gates-merge": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether gitea_merge_pull_request judges mesh/check before it merges. True (the default): a head merges only on a passing mesh/check judged against the trunk's head (ADR 0447, ADR 0534 §4). False (the operator, 2026-10-25 22:56: \"run the check locally only, but not as a gate, it loses us too much time\"): a head the operator's Approve names in approved_heads merges whatever its mesh/check says (pending, failed, missing or judged on an older trunk); a head that moved, a branch no rule guards and a merge git refuses are still refused. Set together with mesh-delivery-gate's check-gates-merge.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
"main-mergers": {
|
"main-mergers": {
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"description": "The forge logins that may merge into main beside the tools' account, on every repository of the organisation (ADR 0534 §2): the operator's own, so the operator can always merge by hand at the forge. The tools' account is always on main's merge whitelist; no agent's account belongs here.",
|
"description": "The forge logins that may merge into main beside the tools' account, on every repository of the organisation (ADR 0534 §2): the operator's own, so the operator can always merge by hand at the forge. The tools' account is always on main's merge whitelist; no agent's account belongs here.",
|
||||||
@@ -316,7 +323,8 @@
|
|||||||
"takes-config": [
|
"takes-config": [
|
||||||
"url",
|
"url",
|
||||||
"keep-main-rules",
|
"keep-main-rules",
|
||||||
"main-mergers"
|
"main-mergers",
|
||||||
|
"check-gates-merge"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -391,6 +399,7 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "npm-package-registry",
|
"name": "npm-package-registry",
|
||||||
|
"credential": {"form": "pair"},
|
||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": {
|
"identity": {
|
||||||
"max": 40,
|
"max": 40,
|
||||||
@@ -399,6 +408,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "git",
|
"name": "git",
|
||||||
|
"credential": {"form": "none"},
|
||||||
"scope": "mesh"
|
"scope": "mesh"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -411,6 +421,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "forge-account",
|
"name": "forge-account",
|
||||||
|
"credential": {"form": "none"},
|
||||||
"scope": "mesh"
|
"scope": "mesh"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -537,6 +548,7 @@
|
|||||||
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
|
"MESH_GITEA_ADMIN_PASSWORD_FILE": "${dir:state}/admin.secret",
|
||||||
"MESH_GITEA_ORIGINS_FILE": "${dir:mesh-state}/origins",
|
"MESH_GITEA_ORIGINS_FILE": "${dir:mesh-state}/origins",
|
||||||
"MESH_GITEA_SSH_PORT": "222",
|
"MESH_GITEA_SSH_PORT": "222",
|
||||||
|
"MESH_GITEA_HOST_KEY_FILE": "${dir:data}/ssh/ssh_host_ed25519_key.pub",
|
||||||
"MESH_FORGE_HOST_FILE": "/etc/gitea/forge-host"
|
"MESH_FORGE_HOST_FILE": "/etc/gitea/forge-host"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -554,11 +566,14 @@
|
|||||||
"announced"
|
"announced"
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
"mesh-controller.assignments",
|
"mesh-provisioner.plans",
|
||||||
|
"mesh-provisioner.provisions",
|
||||||
"ssh-client.keys",
|
"ssh-client.keys",
|
||||||
"mesh-build-go.keys",
|
"mesh-build-go.keys",
|
||||||
"mesh-build-node.keys",
|
"mesh-build-node.keys",
|
||||||
"mesh-build-image.keys",
|
"mesh-build-image.keys",
|
||||||
"mesh-delivery-checker.owed"
|
"mesh-delivery-checker.owed",
|
||||||
|
"mesh-delivery-indexer.modules",
|
||||||
|
"mesh-delivery-gate.source"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "go-toolchain",
|
"name": "go-toolchain",
|
||||||
"reach": "machine"
|
"reach": "machine",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"resources": [
|
"resources": [
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": {
|
"identity": {
|
||||||
"in": "an InfluxDB v1 authorization"
|
"in": "an InfluxDB v1 authorization"
|
||||||
|
},
|
||||||
|
"credential": {
|
||||||
|
"form": "pair"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# Written by the mesh's kernel module (systemd-modules-load reads it at boot).
|
||||||
|
# tun: buildah's network for a RUN line (pasta) and every other user-space tunnel open /dev/net/tun.
|
||||||
|
# Loaded at boot, so an upgrade that removes the running kernel's modules cannot keep it out later.
|
||||||
|
tun
|
||||||
@@ -100,6 +100,25 @@
|
|||||||
"id": "linux-lts-headers",
|
"id": "linux-lts-headers",
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"package": "linux-lts-headers"
|
"package": "linux-lts-headers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "modules-load",
|
||||||
|
"type": "file",
|
||||||
|
"path": "/etc/modules-load.d/mesh-kernel.conf",
|
||||||
|
"mode": "0644",
|
||||||
|
"template": "files/modules-load.conf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "modules-keep",
|
||||||
|
"type": "package",
|
||||||
|
"package": "kernel-modules-hook"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "modules-cleanup",
|
||||||
|
"type": "service",
|
||||||
|
"unit": "linux-modules-cleanup.service",
|
||||||
|
"state": "stopped",
|
||||||
|
"boot": "enabled"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"build": {
|
"build": {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "oidc-client",
|
"name": "oidc-client",
|
||||||
|
"credential": {"form": "pair"},
|
||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": {
|
"identity": {
|
||||||
"max": 255,
|
"max": 255,
|
||||||
@@ -240,6 +241,7 @@
|
|||||||
"bound"
|
"bound"
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
"mesh-controller.assignments"
|
"mesh-provisioner.plans",
|
||||||
|
"mesh-provisioner.provisions"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -665,7 +665,14 @@
|
|||||||
"path": "${dir:mesh-state}/config.json",
|
"path": "${dir:mesh-state}/config.json",
|
||||||
"mode": "0600",
|
"mode": "0600",
|
||||||
"template": "files/config.json",
|
"template": "files/config.json",
|
||||||
"takes-config": ["domain", "proxy-address", "sitename", "website", "url", "container"],
|
"takes-config": [
|
||||||
|
"domain",
|
||||||
|
"proxy-address",
|
||||||
|
"sitename",
|
||||||
|
"website",
|
||||||
|
"url",
|
||||||
|
"container"
|
||||||
|
],
|
||||||
"merge": "json"
|
"merge": "json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -758,6 +765,9 @@
|
|||||||
"identity": {
|
"identity": {
|
||||||
"max": 64,
|
"max": 64,
|
||||||
"in": "a mailbox's local part"
|
"in": "a mailbox's local part"
|
||||||
|
},
|
||||||
|
"credential": {
|
||||||
|
"form": "pair"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
{
|
{
|
||||||
"capacity": "shanks=3,ace=2,g14=0,novox=0"
|
"capacity": 0,
|
||||||
|
"cores-per-step": 6,
|
||||||
|
"build-hours": ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"state": [
|
"state": [
|
||||||
"toolchains",
|
"toolchains",
|
||||||
"keys",
|
"keys",
|
||||||
"steps"
|
{"name": "steps", "ttl-seconds": 172800}, "pauses"
|
||||||
],
|
],
|
||||||
"claims": [
|
"claims": [
|
||||||
{
|
{
|
||||||
@@ -20,14 +20,27 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
"mesh-delivery-checker.kept"
|
"mesh-delivery-checker.kept",
|
||||||
|
"mesh-delivery-indexer.manifests"
|
||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"capacity": {
|
"capacity": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many asks of the Go build seat this module runs at once on this node (novox/hq ADR 0525 §5); 0 pulls nothing. It is set per node in the mesh's configuration; a node with no value builds nothing.",
|
||||||
|
"minimum": 0,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"build-hours": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "How many asks of the Go build seat this module runs at once on each node, as node=asks pairs separated by commas, such as shanks=3,ace=2 (novox/hq ADR 0525 §5); a node set to 0 pulls nothing, a node not named runs one at a time. The control-node and the laptop build nothing.",
|
"description": "When this node may take this module's build asks: one window HH:MM-HH:MM in the node's local time (an end before its start crosses midnight, 18:00-06:00). Outside it the node takes no new step and finishes the ones it runs; an empty value builds at any hour. It is set per node in the mesh's configuration.",
|
||||||
"pattern": "|[a-z0-9_-]+=[0-9]+(,[a-z0-9_-]+=[0-9]+)*",
|
"pattern": "|([01][0-9]|2[0-3]):[0-5][0-9]-([01][0-9]|2[0-3]):[0-5][0-9]",
|
||||||
"default": "shanks=3,ace=2,g14=0,novox=0"
|
"default": ""
|
||||||
|
},
|
||||||
|
"cores-per-step": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many processors one Go step of this module needs (a full check of a large repository takes what it is given: three at about 4 cores each ran past the 30-minute step bound on 2026-10-26). The capacity above is an upper bound: on each node the module runs at most floor(the cores of its build slice's CPU quota / this) steps at once, the quota read live from its cgroup (issue 1806), so a lowered build CPU share never starves its steps. Above 0.",
|
||||||
|
"minimum": 0.1,
|
||||||
|
"default": 6
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": [
|
"tools": [
|
||||||
@@ -38,6 +51,7 @@
|
|||||||
"build_go_release",
|
"build_go_release",
|
||||||
"build_go_step",
|
"build_go_step",
|
||||||
"build_go_steps",
|
"build_go_steps",
|
||||||
|
"build_go_step_end",
|
||||||
"build_go_toolchains",
|
"build_go_toolchains",
|
||||||
"build_go_status",
|
"build_go_status",
|
||||||
"build_go_health"
|
"build_go_health"
|
||||||
@@ -105,7 +119,7 @@
|
|||||||
"path": "${dir:state}/settings.json",
|
"path": "${dir:state}/settings.json",
|
||||||
"mode": "0600",
|
"mode": "0600",
|
||||||
"owner": "mesh-build-go",
|
"owner": "mesh-build-go",
|
||||||
"takes-config": ["capacity"],
|
"takes-config": ["capacity", "cores-per-step", "build-hours"],
|
||||||
"merge": "json",
|
"merge": "json",
|
||||||
"template": "files/settings.json"
|
"template": "files/settings.json"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
{
|
{
|
||||||
"capacity": "shanks=3,ace=2,g14=0,novox=0"
|
"capacity": 0,
|
||||||
|
"cores-per-step": 2,
|
||||||
|
"build-hours": ""
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-5
@@ -9,7 +9,7 @@
|
|||||||
],
|
],
|
||||||
"state": [
|
"state": [
|
||||||
"keys",
|
"keys",
|
||||||
"steps"
|
{"name": "steps", "ttl-seconds": 172800}, "pauses"
|
||||||
],
|
],
|
||||||
"claims": [
|
"claims": [
|
||||||
{
|
{
|
||||||
@@ -20,10 +20,22 @@
|
|||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"capacity": {
|
"capacity": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many asks of the image build seat this module runs at once on this node (novox/hq ADR 0525 §5); 0 pulls nothing. It is set per node in the mesh's configuration; a node with no value builds nothing.",
|
||||||
|
"minimum": 0,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"build-hours": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "How many asks of the image build seat this module runs at once on each node, as node=asks pairs separated by commas, such as shanks=3,ace=2 (novox/hq ADR 0525 §5); a node set to 0 pulls nothing, a node not named runs one at a time. The control-node and the laptop build nothing.",
|
"description": "When this node may take this module's build asks: one window HH:MM-HH:MM in the node's local time (an end before its start crosses midnight, 18:00-06:00). Outside it the node takes no new step and finishes the ones it runs; an empty value builds at any hour. It is set per node in the mesh's configuration.",
|
||||||
"pattern": "|[a-z0-9_-]+=[0-9]+(,[a-z0-9_-]+=[0-9]+)*",
|
"pattern": "|([01][0-9]|2[0-3]):[0-5][0-9]-([01][0-9]|2[0-3]):[0-5][0-9]",
|
||||||
"default": "shanks=3,ace=2,g14=0,novox=0"
|
"default": ""
|
||||||
|
},
|
||||||
|
"cores-per-step": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many processors one image step of this module needs (buildah, whose RUN lines are mostly fetches). The capacity above is an upper bound: on each node the module runs at most floor(the cores of its build slice's CPU quota / this) steps at once, the quota read live from its cgroup (issue 1806), so a lowered build CPU share never starves its steps. Above 0.",
|
||||||
|
"minimum": 0.1,
|
||||||
|
"default": 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": [
|
"tools": [
|
||||||
@@ -33,6 +45,7 @@
|
|||||||
"build_image_release",
|
"build_image_release",
|
||||||
"build_image_step",
|
"build_image_step",
|
||||||
"build_image_steps",
|
"build_image_steps",
|
||||||
|
"build_image_step_end",
|
||||||
"build_image_status",
|
"build_image_status",
|
||||||
"build_image_health"
|
"build_image_health"
|
||||||
],
|
],
|
||||||
@@ -77,7 +90,7 @@
|
|||||||
"path": "${dir:state}/settings.json",
|
"path": "${dir:state}/settings.json",
|
||||||
"mode": "0600",
|
"mode": "0600",
|
||||||
"owner": "mesh-build-image",
|
"owner": "mesh-build-image",
|
||||||
"takes-config": ["capacity"],
|
"takes-config": ["capacity", "cores-per-step", "build-hours"],
|
||||||
"merge": "json",
|
"merge": "json",
|
||||||
"template": "files/settings.json"
|
"template": "files/settings.json"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
{
|
{
|
||||||
"capacity": "shanks=3,ace=2,g14=0,novox=0"
|
"capacity": 0,
|
||||||
|
"cores-per-step": 2,
|
||||||
|
"build-hours": ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"state": [
|
"state": [
|
||||||
"toolchains",
|
"toolchains",
|
||||||
"keys",
|
"keys",
|
||||||
"steps"
|
{"name": "steps", "ttl-seconds": 172800}, "pauses"
|
||||||
],
|
],
|
||||||
"claims": [
|
"claims": [
|
||||||
{
|
{
|
||||||
@@ -21,10 +21,22 @@
|
|||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"capacity": {
|
"capacity": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many asks of the Node build seat this module runs at once on this node (novox/hq ADR 0525 §5); 0 pulls nothing. It is set per node in the mesh's configuration; a node with no value builds nothing.",
|
||||||
|
"minimum": 0,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"build-hours": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "How many asks of the Node build seat this module runs at once on each node, as node=asks pairs separated by commas, such as shanks=3,ace=2 (novox/hq ADR 0525 §5); a node set to 0 pulls nothing, a node not named runs one at a time. The control-node and the laptop build nothing.",
|
"description": "When this node may take this module's build asks: one window HH:MM-HH:MM in the node's local time (an end before its start crosses midnight, 18:00-06:00). Outside it the node takes no new step and finishes the ones it runs; an empty value builds at any hour. It is set per node in the mesh's configuration.",
|
||||||
"pattern": "|[a-z0-9_-]+=[0-9]+(,[a-z0-9_-]+=[0-9]+)*",
|
"pattern": "|([01][0-9]|2[0-3]):[0-5][0-9]-([01][0-9]|2[0-3]):[0-5][0-9]",
|
||||||
"default": "shanks=3,ace=2,g14=0,novox=0"
|
"default": ""
|
||||||
|
},
|
||||||
|
"cores-per-step": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many processors one Node step of this module needs (tsc, esbuild and a test runner; a median step takes 15 s). The capacity above is an upper bound: on each node the module runs at most floor(the cores of its build slice's CPU quota / this) steps at once, the quota read live from its cgroup (issue 1806), so a lowered build CPU share never starves its steps. Above 0.",
|
||||||
|
"minimum": 0.1,
|
||||||
|
"default": 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tools": [
|
"tools": [
|
||||||
@@ -34,6 +46,7 @@
|
|||||||
"build_node_release",
|
"build_node_release",
|
||||||
"build_node_step",
|
"build_node_step",
|
||||||
"build_node_steps",
|
"build_node_steps",
|
||||||
|
"build_node_step_end",
|
||||||
"build_node_toolchains",
|
"build_node_toolchains",
|
||||||
"build_node_status",
|
"build_node_status",
|
||||||
"build_node_health"
|
"build_node_health"
|
||||||
@@ -99,7 +112,7 @@
|
|||||||
"path": "${dir:state}/settings.json",
|
"path": "${dir:state}/settings.json",
|
||||||
"mode": "0600",
|
"mode": "0600",
|
||||||
"owner": "mesh-build-node",
|
"owner": "mesh-build-node",
|
||||||
"takes-config": ["capacity"],
|
"takes-config": ["capacity", "cores-per-step", "build-hours"],
|
||||||
"merge": "json",
|
"merge": "json",
|
||||||
"template": "files/settings.json"
|
"template": "files/settings.json"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,9 +25,7 @@
|
|||||||
"secrets": {
|
"secrets": {
|
||||||
"postgres-database": "${dir:state}/database.secret"
|
"postgres-database": "${dir:state}/database.secret"
|
||||||
},
|
},
|
||||||
"consumes": [
|
"consumes": [],
|
||||||
"mesh-controller.built-before"
|
|
||||||
],
|
|
||||||
"emits": [
|
"emits": [
|
||||||
"registered",
|
"registered",
|
||||||
"upgraded",
|
"upgraded",
|
||||||
@@ -92,5 +90,12 @@
|
|||||||
"from": "files"
|
"from": "files"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"invokes": [
|
||||||
|
"mesh-delivery-builder.builder_builds_since"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-delivery-builder.builds",
|
||||||
|
"mesh-delivery-indexer.manifests"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"module": "mesh-conditions",
|
||||||
|
"version": "1",
|
||||||
|
"runs-as": "mesh-conditions",
|
||||||
|
"claims": [
|
||||||
|
{
|
||||||
|
"name": "mesh-conditions",
|
||||||
|
"scope": "mesh",
|
||||||
|
"serves": [
|
||||||
|
"conditions",
|
||||||
|
"silence",
|
||||||
|
"compare",
|
||||||
|
"take-over",
|
||||||
|
"hand-back",
|
||||||
|
"resync"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"uses": [
|
||||||
|
"operator-channel"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-delivery-watchman.findings",
|
||||||
|
"mesh-self-check.findings",
|
||||||
|
"mesh-healers.findings",
|
||||||
|
"mesh-delivery-assigner.findings",
|
||||||
|
"messenger.findings",
|
||||||
|
"mesh-provisioner.findings",
|
||||||
|
"artifact-store-tools.findings",
|
||||||
|
"mesh-healers.attempts",
|
||||||
|
"mesh-controller.conditions",
|
||||||
|
"mesh-controller.lease",
|
||||||
|
"mesh-delivery-assigner.wants",
|
||||||
|
"node-engine.have",
|
||||||
|
"mesh-delivery-assigner.placement"
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
"conditions",
|
||||||
|
{
|
||||||
|
"name": "history",
|
||||||
|
"ttl-seconds": 7776000
|
||||||
|
},
|
||||||
|
"takeover",
|
||||||
|
"held",
|
||||||
|
{
|
||||||
|
"name": "bounds",
|
||||||
|
"key-ttl": true
|
||||||
|
},
|
||||||
|
"asked"
|
||||||
|
],
|
||||||
|
"own-secrets": {
|
||||||
|
"broker": "${dir:state}/broker"
|
||||||
|
},
|
||||||
|
"secrets-owner": "mesh-conditions",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"id": "account",
|
||||||
|
"type": "user",
|
||||||
|
"name": "mesh-conditions",
|
||||||
|
"shell": "/usr/bin/nologin",
|
||||||
|
"home": "/var/lib/mesh-conditions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "state",
|
||||||
|
"type": "directory",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "mesh-conditions",
|
||||||
|
"place": ".",
|
||||||
|
"unknown": "program"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"build": {
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"name": "tools",
|
||||||
|
"kind": "bundle",
|
||||||
|
"language": "go",
|
||||||
|
"system": "arch",
|
||||||
|
"from": "cmd/mesh-conditions",
|
||||||
|
"binary": "mesh-conditions",
|
||||||
|
"loads": [
|
||||||
|
"mesh-conditions"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,10 @@
|
|||||||
"name": "mesh-config",
|
"name": "mesh-config",
|
||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"serves": [
|
"serves": [
|
||||||
"config"
|
"config",
|
||||||
|
"compare",
|
||||||
|
"take-over",
|
||||||
|
"hand-back"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -23,14 +26,30 @@
|
|||||||
"gitea.forge.pull-request.closed"
|
"gitea.forge.pull-request.closed"
|
||||||
],
|
],
|
||||||
"invokes": [
|
"invokes": [
|
||||||
|
"seat:mesh-hand-acts.hand-act",
|
||||||
|
"seat:mesh-hand-acts.warranted",
|
||||||
"seat:mesh-controller.hand-act",
|
"seat:mesh-controller.hand-act",
|
||||||
"seat:mesh-controller.warranted",
|
"seat:mesh-controller.warranted",
|
||||||
"gitea.gitea_get_pull_request"
|
"gitea.gitea_get_pull_request"
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
"mesh-controller.assignments",
|
"mesh-delivery-assigner.placement",
|
||||||
|
"mesh-delivery-assigner.wants",
|
||||||
|
"mesh-delivery-builder.builds",
|
||||||
|
"mesh-delivery-indexer.modules",
|
||||||
|
"mesh-delivery-indexer.manifests",
|
||||||
|
"mesh-controller.predefined",
|
||||||
"mesh-controller.declared-config",
|
"mesh-controller.declared-config",
|
||||||
"mesh-controller.predefined"
|
"mesh-delivery-indexer.predefined",
|
||||||
|
"mesh-delivery-indexer.config-candidates",
|
||||||
|
"mesh-controller.lease"
|
||||||
|
],
|
||||||
|
"tools": [
|
||||||
|
"config_compare",
|
||||||
|
"config_take_over",
|
||||||
|
"config_hand_back",
|
||||||
|
"config_declared",
|
||||||
|
"config_resync"
|
||||||
],
|
],
|
||||||
"state": [
|
"state": [
|
||||||
"values",
|
"values",
|
||||||
@@ -38,7 +57,9 @@
|
|||||||
"predefined",
|
"predefined",
|
||||||
"proposals",
|
"proposals",
|
||||||
"pulls",
|
"pulls",
|
||||||
"kept"
|
"kept",
|
||||||
|
"declared",
|
||||||
|
"takeover"
|
||||||
],
|
],
|
||||||
"logs": [
|
"logs": [
|
||||||
"history"
|
"history"
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
"refusal-stall-floor-minutes": 10,
|
"refusal-stall-floor-minutes": 10,
|
||||||
"author-new-head-minutes": 120
|
"author-new-head-minutes": 120,
|
||||||
|
"check-gates-merge": true
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-5
@@ -14,7 +14,8 @@
|
|||||||
"table",
|
"table",
|
||||||
"stalled",
|
"stalled",
|
||||||
"recheck",
|
"recheck",
|
||||||
"close"
|
"close",
|
||||||
|
"settle"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -26,13 +27,17 @@
|
|||||||
"gitea.forge.pull-request.edited",
|
"gitea.forge.pull-request.edited",
|
||||||
"gitea.forge.pull-request.closed",
|
"gitea.forge.pull-request.closed",
|
||||||
"mesh-delivery-forge-bridge.forge.**",
|
"mesh-delivery-forge-bridge.forge.**",
|
||||||
"mesh-config.config-changed"
|
"mesh-config.config-changed",
|
||||||
|
"gitea.repo.writable"
|
||||||
],
|
],
|
||||||
"emits": [
|
"emits": [
|
||||||
"transition",
|
"transition",
|
||||||
"group",
|
"group",
|
||||||
"merged"
|
"merged"
|
||||||
],
|
],
|
||||||
|
"uses": [
|
||||||
|
"operator-channel"
|
||||||
|
],
|
||||||
"invokes": [
|
"invokes": [
|
||||||
"gitea.gitea_commit_statuses",
|
"gitea.gitea_commit_statuses",
|
||||||
"gitea.gitea_contains",
|
"gitea.gitea_contains",
|
||||||
@@ -57,14 +62,23 @@
|
|||||||
{
|
{
|
||||||
"name": "source",
|
"name": "source",
|
||||||
"history": 64
|
"history": 64
|
||||||
|
},
|
||||||
|
"conditions",
|
||||||
|
{
|
||||||
|
"name": "turns",
|
||||||
|
"history": 5
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
"mesh-delivery-teller.answers",
|
"mesh-delivery-teller.answers",
|
||||||
"mesh-delivery-checker.verdicts"
|
"mesh-delivery-checker.verdicts",
|
||||||
|
"mesh-delivery-view.reach"
|
||||||
],
|
],
|
||||||
"tools": [
|
"tools": [
|
||||||
"delivery_status"
|
"delivery_hand_now",
|
||||||
|
"delivery_merge_again",
|
||||||
|
"delivery_status",
|
||||||
|
"delivery_turns"
|
||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"refusal-stall-floor-minutes": {
|
"refusal-stall-floor-minutes": {
|
||||||
@@ -82,6 +96,12 @@
|
|||||||
"maximum": 10080,
|
"maximum": 10080,
|
||||||
"trusted": false,
|
"trusted": false,
|
||||||
"default": 120
|
"default": 120
|
||||||
|
},
|
||||||
|
"check-gates-merge": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether mesh/check gates the merge. True (the default): the operator's Approve is asked, and a merge handed, only on a passing verdict judged against the trunk's head, and a trunk's move puts a verdict out of date (ADR 0447, ADR 0505 §4). False (the operator, 2026-10-25 22:56: \"run the check locally only, but not as a gate, it loses us too much time\"; developers run the unit and integration levels locally before a pull request): a pull request reviewed at its head is ready, and its Approve is asked once the check at its heads (a group: of all its heads together) has a verdict, a pass or a failure said in the ask, or after 60 minutes with none, said so (the operator, 2026-10-27 23:54: \"if you don't want me to approve it, don't send the approval request\"); an approved merge waits for no verdict; no merge is refused for a check judged on an older trunk; a later verdict is shown on the pull request and the delivery, and asks a pending Approve again in its words; a group still merges all its members in one pass. Set it false together with the gitea module's check-gates-merge, which lets its merge tool merge an approved head without a passing mesh/check.",
|
||||||
|
"trusted": false,
|
||||||
|
"default": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"resources": [
|
"resources": [
|
||||||
@@ -99,7 +119,8 @@
|
|||||||
"mode": "0600",
|
"mode": "0600",
|
||||||
"takes-config": [
|
"takes-config": [
|
||||||
"refusal-stall-floor-minutes",
|
"refusal-stall-floor-minutes",
|
||||||
"author-new-head-minutes"
|
"author-new-head-minutes",
|
||||||
|
"check-gates-merge"
|
||||||
],
|
],
|
||||||
"merge": "json",
|
"merge": "json",
|
||||||
"template": "files/settings.json"
|
"template": "files/settings.json"
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"module": "mesh-hand-acts",
|
||||||
|
"version": "1",
|
||||||
|
"runs-as": "mesh-hand-acts",
|
||||||
|
"claims": [
|
||||||
|
{
|
||||||
|
"name": "mesh-hand-acts",
|
||||||
|
"scope": "mesh",
|
||||||
|
"serves": [
|
||||||
|
"hand-act",
|
||||||
|
"hand-acts",
|
||||||
|
"warranted"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-controller.hand-acts",
|
||||||
|
"messenger.asks"
|
||||||
|
],
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"name": "acts",
|
||||||
|
"max-age-days": 400
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
"warrants"
|
||||||
|
],
|
||||||
|
"own-secrets": {
|
||||||
|
"broker": "${dir:state}/broker"
|
||||||
|
},
|
||||||
|
"secrets-owner": "mesh-hand-acts",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"id": "account",
|
||||||
|
"type": "user",
|
||||||
|
"name": "mesh-hand-acts",
|
||||||
|
"shell": "/usr/bin/nologin",
|
||||||
|
"home": "/var/lib/mesh-hand-acts"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "state",
|
||||||
|
"type": "directory",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "mesh-hand-acts",
|
||||||
|
"place": ".",
|
||||||
|
"unknown": "program"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"build": {
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"name": "tools",
|
||||||
|
"kind": "bundle",
|
||||||
|
"language": "go",
|
||||||
|
"system": "arch",
|
||||||
|
"from": "cmd/mesh-hand-acts",
|
||||||
|
"binary": "mesh-hand-acts",
|
||||||
|
"loads": [
|
||||||
|
"mesh-hand-acts"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"module": "mesh-healers",
|
||||||
|
"version": "1",
|
||||||
|
"runs-as": "mesh-healers",
|
||||||
|
"claims": [
|
||||||
|
{
|
||||||
|
"name": "mesh-healers",
|
||||||
|
"scope": "mesh",
|
||||||
|
"serves": [
|
||||||
|
"healers",
|
||||||
|
"heal",
|
||||||
|
"drill"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"mesh-conditions.condition-raised",
|
||||||
|
"mesh-conditions.condition-changed",
|
||||||
|
"mesh-hand-acts.act-recorded"
|
||||||
|
],
|
||||||
|
"invokes": [
|
||||||
|
"mesh-grants.grants_assert",
|
||||||
|
"seat:mesh-hand-acts.hand-act",
|
||||||
|
"seat:mesh-controller.drill"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-controller.lease",
|
||||||
|
"mesh-conditions.conditions",
|
||||||
|
"mesh-controller.hand-acts"
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"name": "attempts",
|
||||||
|
"key-ttl": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "would",
|
||||||
|
"key-ttl": true
|
||||||
|
},
|
||||||
|
"findings",
|
||||||
|
{
|
||||||
|
"name": "wakes",
|
||||||
|
"key-ttl": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"own-secrets": {
|
||||||
|
"broker": "${dir:state}/broker"
|
||||||
|
},
|
||||||
|
"secrets-owner": "mesh-healers",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"id": "account",
|
||||||
|
"type": "user",
|
||||||
|
"name": "mesh-healers",
|
||||||
|
"shell": "/usr/bin/nologin",
|
||||||
|
"home": "/var/lib/mesh-healers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "state",
|
||||||
|
"type": "directory",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "mesh-healers",
|
||||||
|
"place": ".",
|
||||||
|
"unknown": "program"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"build": {
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"name": "tools",
|
||||||
|
"kind": "bundle",
|
||||||
|
"language": "go",
|
||||||
|
"system": "arch",
|
||||||
|
"from": "cmd/mesh-healers",
|
||||||
|
"binary": "mesh-healers",
|
||||||
|
"loads": [
|
||||||
|
"mesh-healers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,12 +13,17 @@
|
|||||||
"move",
|
"move",
|
||||||
"note",
|
"note",
|
||||||
"link",
|
"link",
|
||||||
|
"milestones",
|
||||||
|
"milestone-set",
|
||||||
|
"milestone-move",
|
||||||
"import",
|
"import",
|
||||||
"groom",
|
"groom",
|
||||||
"set",
|
"set",
|
||||||
"tracking",
|
"tracking",
|
||||||
"reserve",
|
"reserve",
|
||||||
"fix-times"
|
"fix-times",
|
||||||
|
"learn-fixes",
|
||||||
|
"changes"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -33,12 +38,17 @@
|
|||||||
"move",
|
"move",
|
||||||
"note",
|
"note",
|
||||||
"link",
|
"link",
|
||||||
|
"milestones",
|
||||||
|
"milestone-set",
|
||||||
|
"milestone-move",
|
||||||
"import",
|
"import",
|
||||||
"groom",
|
"groom",
|
||||||
"set",
|
"set",
|
||||||
"tracking",
|
"tracking",
|
||||||
"reserve",
|
"reserve",
|
||||||
"fix-times"
|
"fix-times",
|
||||||
|
"learn-fixes",
|
||||||
|
"changes"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -52,7 +62,9 @@
|
|||||||
"triaged",
|
"triaged",
|
||||||
"ready",
|
"ready",
|
||||||
"ready-to-verify",
|
"ready-to-verify",
|
||||||
"reserved"
|
"reserved",
|
||||||
|
"milestone-set",
|
||||||
|
"milestone-moved"
|
||||||
],
|
],
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"mesh-issues.opened",
|
"mesh-issues.opened",
|
||||||
@@ -66,6 +78,7 @@
|
|||||||
"seat:operator-channel.notify",
|
"seat:operator-channel.notify",
|
||||||
"gitea.gitea_pull_reviews",
|
"gitea.gitea_pull_reviews",
|
||||||
"gitea.gitea_contains",
|
"gitea.gitea_contains",
|
||||||
|
"gitea.gitea_get_pull_request",
|
||||||
"records.records_status",
|
"records.records_status",
|
||||||
"records.records_list",
|
"records.records_list",
|
||||||
"records.records_read",
|
"records.records_read",
|
||||||
@@ -81,7 +94,11 @@
|
|||||||
},
|
},
|
||||||
"counters",
|
"counters",
|
||||||
"grooming",
|
"grooming",
|
||||||
"reservations"
|
"reservations",
|
||||||
|
{
|
||||||
|
"name": "milestones",
|
||||||
|
"history": 5
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"first-number": {
|
"first-number": {
|
||||||
|
|||||||
@@ -32,7 +32,8 @@
|
|||||||
"propose",
|
"propose",
|
||||||
"import",
|
"import",
|
||||||
"return",
|
"return",
|
||||||
"withdraw"
|
"withdraw",
|
||||||
|
"progress"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -52,13 +53,15 @@
|
|||||||
"propose",
|
"propose",
|
||||||
"import",
|
"import",
|
||||||
"return",
|
"return",
|
||||||
"withdraw"
|
"withdraw",
|
||||||
|
"progress"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tools": [
|
"tools": [
|
||||||
"knowledge_health",
|
"knowledge_health",
|
||||||
"knowledge_highest"
|
"knowledge_highest",
|
||||||
|
"knowledge_marks"
|
||||||
],
|
],
|
||||||
"emits": [
|
"emits": [
|
||||||
"reserved",
|
"reserved",
|
||||||
@@ -81,7 +84,14 @@
|
|||||||
"records.records_status",
|
"records.records_status",
|
||||||
"records.records_list",
|
"records.records_list",
|
||||||
"records.records_read",
|
"records.records_read",
|
||||||
"seat:operator-channel.notify"
|
"seat:operator-channel.notify",
|
||||||
|
"seat:issue-tracker.list",
|
||||||
|
"seat:issue-tracker.get",
|
||||||
|
"seat:issue-tracker.milestones",
|
||||||
|
"seat:issue-tracker.changes",
|
||||||
|
"seat:mesh-delivery.deliveries",
|
||||||
|
"seat:mesh-delivery.show",
|
||||||
|
"seat:mesh-delivery.groups"
|
||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"judge-model": {
|
"judge-model": {
|
||||||
|
|||||||
+26
-1
@@ -11,11 +11,36 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"uses": [
|
||||||
|
"operator-channel"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-delivery-assigner.placement",
|
||||||
|
"mesh-delivery-assigner.wants",
|
||||||
|
"mesh-delivery-indexer.modules",
|
||||||
|
"mesh-delivery-indexer.manifests",
|
||||||
|
"mesh-delivery-builder.builds",
|
||||||
|
"node-engine.have",
|
||||||
|
"mesh-config.resolved",
|
||||||
|
"gitea.bound",
|
||||||
|
"keycloak.bound",
|
||||||
|
"postgres.bound",
|
||||||
|
"route-adapter.bound",
|
||||||
|
"mesh-vault.bound"
|
||||||
|
],
|
||||||
|
"tools": [
|
||||||
|
"provisioner_provisions",
|
||||||
|
"provisioner_plans",
|
||||||
|
"provisioner_compose",
|
||||||
|
"provisioner_decide"
|
||||||
|
],
|
||||||
"state": [
|
"state": [
|
||||||
"registry",
|
"registry",
|
||||||
"needs",
|
"needs",
|
||||||
"applied",
|
"applied",
|
||||||
"collect"
|
"collect",
|
||||||
|
"provisions",
|
||||||
|
"plans"
|
||||||
],
|
],
|
||||||
"own-secrets": {
|
"own-secrets": {
|
||||||
"broker": "${dir:state}/broker"
|
"broker": "${dir:state}/broker"
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"module": "mesh-self-check",
|
||||||
|
"version": "1",
|
||||||
|
"runs-as": "mesh-self-check",
|
||||||
|
"claims": [
|
||||||
|
{
|
||||||
|
"name": "mesh-self-check",
|
||||||
|
"scope": "mesh",
|
||||||
|
"serves": [
|
||||||
|
"doctor",
|
||||||
|
"probes"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"invokes": [
|
||||||
|
"nats.nats_streams",
|
||||||
|
"nats.nats_closed_connections",
|
||||||
|
"seat:mesh-watchdogs.signals",
|
||||||
|
"seat:node-intrusion-prevention.banned"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-delivery-assigner.placement",
|
||||||
|
"mesh-delivery-assigner.seat-holders",
|
||||||
|
"mesh-delivery-watchman.presence",
|
||||||
|
"mesh-host.health",
|
||||||
|
"disk-load.readings",
|
||||||
|
"restic.good",
|
||||||
|
"mesh-delivery-indexer.modules",
|
||||||
|
"mesh-delivery-indexer.manifests"
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
"findings",
|
||||||
|
"verdict",
|
||||||
|
{
|
||||||
|
"name": "verdicts",
|
||||||
|
"ttl-seconds": 604800
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"own-secrets": {
|
||||||
|
"broker": "${dir:state}/broker"
|
||||||
|
},
|
||||||
|
"secrets-owner": "mesh-self-check",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"id": "account",
|
||||||
|
"type": "user",
|
||||||
|
"name": "mesh-self-check",
|
||||||
|
"shell": "/usr/bin/nologin",
|
||||||
|
"home": "/var/lib/mesh-self-check"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "state",
|
||||||
|
"type": "directory",
|
||||||
|
"mode": "0700",
|
||||||
|
"owner": "mesh-self-check",
|
||||||
|
"place": ".",
|
||||||
|
"unknown": "program"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"build": {
|
||||||
|
"artifacts": [
|
||||||
|
{
|
||||||
|
"name": "tools",
|
||||||
|
"kind": "bundle",
|
||||||
|
"language": "go",
|
||||||
|
"system": "arch",
|
||||||
|
"from": "cmd/mesh-self-check",
|
||||||
|
"binary": "mesh-self-check",
|
||||||
|
"loads": [
|
||||||
|
"mesh-self-check"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"probes": {
|
||||||
|
"type": "list",
|
||||||
|
"description": "The ids of the probes that run, each judging one thing of the mesh (mesh-self-check.probes lists them with what each asserts). A probe not listed runs nothing and raises nothing, and what it raised before is cleared. D8 and DA are in the code and off by default.",
|
||||||
|
"trusted": true,
|
||||||
|
"default": [
|
||||||
|
"D13",
|
||||||
|
"D-fill"
|
||||||
|
],
|
||||||
|
"runtime": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,9 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "secret",
|
"name": "secret",
|
||||||
|
"credential": {
|
||||||
|
"form": "pair"
|
||||||
|
},
|
||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": {
|
"identity": {
|
||||||
"in": "a vault entry"
|
"in": "a vault entry"
|
||||||
@@ -14,10 +17,27 @@
|
|||||||
"emits": [
|
"emits": [
|
||||||
"provisioned",
|
"provisioned",
|
||||||
"rotated",
|
"rotated",
|
||||||
"secret-changed"
|
"secret-changed",
|
||||||
|
"account-hashed",
|
||||||
|
"own-replaced",
|
||||||
|
"account-issued",
|
||||||
|
"signed"
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
"mesh-controller.assignments"
|
"node-engine.have",
|
||||||
|
"mesh-grants.accounts",
|
||||||
|
"mesh-controller.lease",
|
||||||
|
"mesh-delivery-assigner.placement",
|
||||||
|
"mesh-provisioner.plans",
|
||||||
|
"mesh-provisioner.provisions"
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
{
|
||||||
|
"name": "bus-accounts",
|
||||||
|
"history": 2
|
||||||
|
},
|
||||||
|
"signers",
|
||||||
|
"bound"
|
||||||
],
|
],
|
||||||
"receives": {
|
"receives": {
|
||||||
"secret": "${dir:grants}/mesh.json"
|
"secret": "${dir:grants}/mesh.json"
|
||||||
@@ -135,7 +155,8 @@
|
|||||||
"MESH_VAULT_LEDGER": "${dir:ledger}",
|
"MESH_VAULT_LEDGER": "${dir:ledger}",
|
||||||
"MESH_VAULT_ROOT": "${dir:root}",
|
"MESH_VAULT_ROOT": "${dir:root}",
|
||||||
"MESH_VAULT_STORE": "${dir:store}",
|
"MESH_VAULT_STORE": "${dir:store}",
|
||||||
"MESH_VAULT_STATE": "${dir:state}"
|
"MESH_VAULT_STATE": "${dir:state}",
|
||||||
|
"MESH_VAULT_SECRET_ASK_CALLERS": "node-tools"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -145,6 +166,10 @@
|
|||||||
"secret_holders",
|
"secret_holders",
|
||||||
"secret_verify",
|
"secret_verify",
|
||||||
"secret_handed",
|
"secret_handed",
|
||||||
|
"secret_own",
|
||||||
|
"account_hash",
|
||||||
|
"account_adopt",
|
||||||
|
"account_retire",
|
||||||
"secret_asks",
|
"secret_asks",
|
||||||
"secret_vault_export",
|
"secret_vault_export",
|
||||||
"provisioner_retirement",
|
"provisioner_retirement",
|
||||||
@@ -152,7 +177,12 @@
|
|||||||
"provisioner_retire_reject",
|
"provisioner_retire_reject",
|
||||||
"provisioner_delete",
|
"provisioner_delete",
|
||||||
"vault_status",
|
"vault_status",
|
||||||
"vault_health"
|
"vault_health",
|
||||||
|
"own_drift",
|
||||||
|
"own_take_switch",
|
||||||
|
"vault_signers",
|
||||||
|
"vault_signed",
|
||||||
|
"signers_reassert"
|
||||||
],
|
],
|
||||||
"claims": [
|
"claims": [
|
||||||
{
|
{
|
||||||
@@ -166,7 +196,10 @@
|
|||||||
"rotate",
|
"rotate",
|
||||||
"move-in",
|
"move-in",
|
||||||
"node-key",
|
"node-key",
|
||||||
"move-asks"
|
"move-asks",
|
||||||
|
"own",
|
||||||
|
"issue-account",
|
||||||
|
"sign"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3,11 +3,15 @@
|
|||||||
"version": "1",
|
"version": "1",
|
||||||
"slug": "watch",
|
"slug": "watch",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"mesh-controller.doctor-heartbeat"
|
"mesh-controller.doctor-heartbeat",
|
||||||
|
"mesh-self-check.checked"
|
||||||
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-conditions.takeover",
|
||||||
|
"mesh-delivery-assigner.seat-holders"
|
||||||
],
|
],
|
||||||
"invokes": [
|
"invokes": [
|
||||||
"mesh-watcher.watcher_ping",
|
"mesh-watcher.watcher_ping"
|
||||||
"seat:mesh-controller.seats"
|
|
||||||
],
|
],
|
||||||
"own-secrets": {
|
"own-secrets": {
|
||||||
"telegram-token": "${dir:state}/telegram-token"
|
"telegram-token": "${dir:state}/telegram-token"
|
||||||
@@ -39,7 +43,9 @@
|
|||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "${dir:state}/settings.json",
|
"path": "${dir:state}/settings.json",
|
||||||
"mode": "0600",
|
"mode": "0600",
|
||||||
"takes-config": ["telegram-chat-id"],
|
"takes-config": [
|
||||||
|
"telegram-chat-id"
|
||||||
|
],
|
||||||
"merge": "json",
|
"merge": "json",
|
||||||
"template": "files/settings.json"
|
"template": "files/settings.json"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,9 @@
|
|||||||
"mesh-controller.condition-raised",
|
"mesh-controller.condition-raised",
|
||||||
"mesh-controller.condition-changed",
|
"mesh-controller.condition-changed",
|
||||||
"mesh-controller.condition-cleared",
|
"mesh-controller.condition-cleared",
|
||||||
|
"mesh-conditions.condition-raised",
|
||||||
|
"mesh-conditions.condition-changed",
|
||||||
|
"mesh-conditions.condition-cleared",
|
||||||
"mesh-delivery-view.moving",
|
"mesh-delivery-view.moving",
|
||||||
"mesh-delivery-view.settled",
|
"mesh-delivery-view.settled",
|
||||||
"mesh-delivery-view.stuck",
|
"mesh-delivery-view.stuck",
|
||||||
@@ -90,9 +93,13 @@
|
|||||||
],
|
],
|
||||||
"invokes": [
|
"invokes": [
|
||||||
"seat:mesh-controller.conditions",
|
"seat:mesh-controller.conditions",
|
||||||
"seat:mesh-controller.root-free",
|
"seat:mesh-conditions.conditions",
|
||||||
|
"seat:node-engine.root-free",
|
||||||
"seat:issue-tracker.tracking"
|
"seat:issue-tracker.tracking"
|
||||||
],
|
],
|
||||||
|
"reads": [
|
||||||
|
"mesh-conditions.takeover"
|
||||||
|
],
|
||||||
"state": [
|
"state": [
|
||||||
"open",
|
"open",
|
||||||
"sent",
|
"sent",
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
"identity": {
|
"identity": {
|
||||||
"max": 20,
|
"max": 20,
|
||||||
"in": "an S3 access key"
|
"in": "an S3 access key"
|
||||||
|
},
|
||||||
|
"credential": {
|
||||||
|
"form": "pair"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -36,8 +39,8 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"invokes": [
|
"reads": [
|
||||||
"seat:mesh-controller.seats"
|
"mesh-delivery-assigner.seat-holders"
|
||||||
],
|
],
|
||||||
"contributes": {
|
"contributes": {
|
||||||
"route": {
|
"route": {
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
"identity": {
|
"identity": {
|
||||||
"max": 63,
|
"max": 63,
|
||||||
"in": "a MongoDB database name"
|
"in": "a MongoDB database name"
|
||||||
|
},
|
||||||
|
"credential": {
|
||||||
|
"form": "pair"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": {
|
"identity": {
|
||||||
"in": "a Mosquitto client and topic prefix"
|
"in": "a Mosquitto client and topic prefix"
|
||||||
|
},
|
||||||
|
"credential": {
|
||||||
|
"form": "pair"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -5,11 +5,9 @@
|
|||||||
"nfs-share"
|
"nfs-share"
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
|
"disk-load.readings",
|
||||||
"nfs-server.exports"
|
"nfs-server.exports"
|
||||||
],
|
],
|
||||||
"invokes": [
|
|
||||||
"seat:mesh-controller.data"
|
|
||||||
],
|
|
||||||
"capabilities": [
|
"capabilities": [
|
||||||
"package-manager",
|
"package-manager",
|
||||||
"service-manager"
|
"service-manager"
|
||||||
@@ -38,20 +36,20 @@
|
|||||||
"per-machine": true
|
"per-machine": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"config": {
|
"config": {
|
||||||
"shares": {
|
"shares": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The shares of another machine this machine mounts: space-separated name=mountpoint, each optionally :ro, or none (novox/hq ADR 0263 rule 5).",
|
"description": "The shares of another machine this machine mounts: space-separated name=mountpoint, each optionally :ro, or none (novox/hq ADR 0263 rule 5).",
|
||||||
"trusted": true,
|
"trusted": true,
|
||||||
"default": "none"
|
"default": "none"
|
||||||
},
|
|
||||||
"sources": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "The occasional sources this machine mounts: space-separated name=smb://[<user>@]<host>/<share>@<mountpoint> or name=disk:<uuid>@<mountpoint>, each optionally :ro, or none (novox/hq ADR 0263 rule 6); an SMB source's username is in its entry, its password the secret smb-password-<name> (novox/hq ADR 0283).",
|
|
||||||
"trusted": true,
|
|
||||||
"default": "none"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
"sources": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The occasional sources this machine mounts: space-separated name=smb://[<user>@]<host>/<share>@<mountpoint> or name=disk:<uuid>@<mountpoint>, each optionally :ro, or none (novox/hq ADR 0263 rule 6); an SMB source's username is in its entry, its password the secret smb-password-<name> (novox/hq ADR 0283).",
|
||||||
|
"trusted": true,
|
||||||
|
"default": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
"own-secrets": {
|
"own-secrets": {
|
||||||
"smb-password-*": {
|
"smb-password-*": {
|
||||||
"path": "${dir:state}/smb-password-*.secret",
|
"path": "${dir:state}/smb-password-*.secret",
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
"identity": {
|
"identity": {
|
||||||
"max": 128,
|
"max": 128,
|
||||||
"in": "a SQL Server login and database name"
|
"in": "a SQL Server login and database name"
|
||||||
|
},
|
||||||
|
"credential": {
|
||||||
|
"form": "pair"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -8,7 +8,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "mesh-bus",
|
"name": "mesh-bus",
|
||||||
"scope": "mesh"
|
"scope": "mesh",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"claims": [
|
"claims": [
|
||||||
@@ -19,12 +22,16 @@
|
|||||||
],
|
],
|
||||||
"bus-users": "/var/lib/nats-module/conf/accounts.conf",
|
"bus-users": "/var/lib/nats-module/conf/accounts.conf",
|
||||||
"own-secrets": {
|
"own-secrets": {
|
||||||
"broker": "${dir:mesh-state}/broker"
|
"broker": "${dir:mesh-state}/broker",
|
||||||
|
"broker-nats-tools": "${dir:tools-secret}/broker-nats-tools"
|
||||||
},
|
},
|
||||||
"capabilities": [
|
"capabilities": [
|
||||||
"container-runtime"
|
"container-runtime"
|
||||||
],
|
],
|
||||||
"emits": [],
|
"emits": [
|
||||||
|
"consumer-removed",
|
||||||
|
"bucket-keys-removed"
|
||||||
|
],
|
||||||
"consumes": [],
|
"consumes": [],
|
||||||
"listens": [
|
"listens": [
|
||||||
{
|
{
|
||||||
@@ -45,7 +52,9 @@
|
|||||||
"nats_buckets",
|
"nats_buckets",
|
||||||
"nats_users",
|
"nats_users",
|
||||||
"nats_user_can",
|
"nats_user_can",
|
||||||
"nats_snapshot_verify"
|
"nats_snapshot_verify",
|
||||||
|
"nats_consumer_remove",
|
||||||
|
"nats_bucket_remove"
|
||||||
],
|
],
|
||||||
"guards": [
|
"guards": [
|
||||||
8222
|
8222
|
||||||
@@ -86,6 +95,13 @@
|
|||||||
"mode": "0700",
|
"mode": "0700",
|
||||||
"unknown": "program"
|
"unknown": "program"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "tools-secret",
|
||||||
|
"type": "directory",
|
||||||
|
"path": "/var/lib/mesh/nats-tools",
|
||||||
|
"mode": "0711",
|
||||||
|
"unknown": "program"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "snapshots",
|
"id": "snapshots",
|
||||||
"type": "directory",
|
"type": "directory",
|
||||||
@@ -190,11 +206,18 @@
|
|||||||
"loads": [
|
"loads": [
|
||||||
"nats-tools"
|
"nats-tools"
|
||||||
],
|
],
|
||||||
|
"bus": {
|
||||||
|
"removes": [
|
||||||
|
"DEAD_LETTER_NOTICES.controller",
|
||||||
|
"mesh-host_acts"
|
||||||
|
]
|
||||||
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"MESH_NATS_MONITOR": "http://127.0.0.1:8222",
|
"MESH_NATS_MONITOR": "http://127.0.0.1:8222",
|
||||||
"MESH_NATS_CONTAINER": "mesh-broker-nats",
|
"MESH_NATS_CONTAINER": "mesh-broker-nats",
|
||||||
"MESH_NATS_USERS_FILE": "/etc/nats/accounts.conf",
|
"MESH_NATS_USERS_FILE": "/etc/nats/accounts.conf",
|
||||||
"MESH_NATS_SNAPSHOTS_DIR": "${dir:snapshots}"
|
"MESH_NATS_SNAPSHOTS_DIR": "${dir:snapshots}",
|
||||||
|
"NATS_TOOLS_CREDENTIAL": "${dir:tools-secret}/broker-nats-tools"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The Nextcloud account the module's tools act as; empty is admin.",
|
"description": "The Nextcloud account the module's tools act as; empty is mesh-admin, the account the module makes and keeps for itself. Any other account is used as given and never repaired.",
|
||||||
"trusted": true,
|
"trusted": true,
|
||||||
"default": ""
|
"default": ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,10 @@
|
|||||||
{
|
{
|
||||||
"name": "nfs-share",
|
"name": "nfs-share",
|
||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": false
|
"identity": false,
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"data": {
|
"data": {
|
||||||
@@ -45,26 +48,24 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
|
"disk-load.readings",
|
||||||
|
"mesh-delivery-assigner.seat-holders",
|
||||||
"mounts.shares"
|
"mounts.shares"
|
||||||
],
|
],
|
||||||
"invokes": [
|
"config": {
|
||||||
"seat:mesh-controller.seats",
|
"shares": {
|
||||||
"seat:mesh-controller.data"
|
"type": "string",
|
||||||
],
|
"description": "The folders this machine exports, as space-separated name=path; the operator's, with no default (novox/hq ADR 0263).",
|
||||||
"config": {
|
"trusted": true,
|
||||||
"shares": {
|
"required": true
|
||||||
"type": "string",
|
|
||||||
"description": "The folders this machine exports, as space-separated name=path; the operator's, with no default (novox/hq ADR 0263).",
|
|
||||||
"trusted": true,
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"grants": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Which nodes may mount which share, and how: share=node:rw|ro[,node:rw|ro], entries separated by spaces, or none to export to no node whatever a node wants (novox/hq ADR 0263).",
|
|
||||||
"trusted": true,
|
|
||||||
"default": "none"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
"grants": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Which nodes may mount which share, and how: share=node:rw|ro[,node:rw|ro], entries separated by spaces, or none to export to no node whatever a node wants (novox/hq ADR 0263).",
|
||||||
|
"trusted": true,
|
||||||
|
"default": "none"
|
||||||
|
}
|
||||||
|
},
|
||||||
"facts": {
|
"facts": {
|
||||||
"machines": {
|
"machines": {
|
||||||
"path": "/etc/nfs-server/machines",
|
"path": "/etc/nfs-server/machines",
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "node-toolchain",
|
"name": "node-toolchain",
|
||||||
"reach": "machine"
|
"reach": "machine",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"resources": [
|
"resources": [
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "model-access",
|
"name": "model-access",
|
||||||
"scope": "node"
|
"scope": "node",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"listens": [
|
"listens": [
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "postgres-database",
|
"name": "postgres-database",
|
||||||
|
"credential": {"form": "pair"},
|
||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": {
|
"identity": {
|
||||||
"max": 63,
|
"max": 63,
|
||||||
@@ -195,6 +196,7 @@
|
|||||||
"bound"
|
"bound"
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
"mesh-controller.assignments"
|
"mesh-provisioner.plans",
|
||||||
|
"mesh-provisioner.provisions"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -314,6 +314,48 @@
|
|||||||
"mode": "0644",
|
"mode": "0644",
|
||||||
"template": "templates/systemd/system/suspend-then-hibernate.target.d/mesh-power.conf"
|
"template": "templates/systemd/system/suspend-then-hibernate.target.d/mesh-power.conf"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "reboot-drop-ins",
|
||||||
|
"type": "directory",
|
||||||
|
"path": "/etc/systemd/system/reboot.target.d",
|
||||||
|
"mode": "0755",
|
||||||
|
"unknown": "program"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "reboot-bound",
|
||||||
|
"type": "file",
|
||||||
|
"path": "/etc/systemd/system/reboot.target.d/mesh-power.conf",
|
||||||
|
"mode": "0644",
|
||||||
|
"template": "templates/systemd/system/reboot.target.d/mesh-power.conf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "poweroff-drop-ins",
|
||||||
|
"type": "directory",
|
||||||
|
"path": "/etc/systemd/system/poweroff.target.d",
|
||||||
|
"mode": "0755",
|
||||||
|
"unknown": "program"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "poweroff-bound",
|
||||||
|
"type": "file",
|
||||||
|
"path": "/etc/systemd/system/poweroff.target.d/mesh-power.conf",
|
||||||
|
"mode": "0644",
|
||||||
|
"template": "templates/systemd/system/poweroff.target.d/mesh-power.conf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "halt-drop-ins",
|
||||||
|
"type": "directory",
|
||||||
|
"path": "/etc/systemd/system/halt.target.d",
|
||||||
|
"mode": "0755",
|
||||||
|
"unknown": "program"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "halt-bound",
|
||||||
|
"type": "file",
|
||||||
|
"path": "/etc/systemd/system/halt.target.d/mesh-power.conf",
|
||||||
|
"mode": "0644",
|
||||||
|
"template": "templates/systemd/system/halt.target.d/mesh-power.conf"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "udev-rule",
|
"id": "udev-rule",
|
||||||
"type": "file",
|
"type": "file",
|
||||||
|
|||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
# Written by the mesh (module power, novox/hq ADR 0211; issue 1126). Replaced on every push.
|
||||||
|
#
|
||||||
|
# A shutdown is bounded at ten minutes, not systemd's thirty. A unit started again during the shutdown
|
||||||
|
# (on ace, 2026-10-28, the bus and the authorization manager) is never stopped a second time, and the
|
||||||
|
# shutdown then waits on this job's timeout with nothing on the console. The target keeps its own
|
||||||
|
# forcing action: the last phase still ends every process, unmounts and syncs.
|
||||||
|
[Unit]
|
||||||
|
JobTimeoutSec=10min
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
# Written by the mesh (module power, novox/hq ADR 0211; issue 1126). Replaced on every push.
|
||||||
|
#
|
||||||
|
# A shutdown is bounded at ten minutes, not systemd's thirty. A unit started again during the shutdown
|
||||||
|
# (on ace, 2026-10-28, the bus and the authorization manager) is never stopped a second time, and the
|
||||||
|
# shutdown then waits on this job's timeout with nothing on the console. The target keeps its own
|
||||||
|
# forcing action: the last phase still ends every process, unmounts and syncs.
|
||||||
|
[Unit]
|
||||||
|
JobTimeoutSec=10min
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
# Written by the mesh (module power, novox/hq ADR 0211; issue 1126). Replaced on every push.
|
||||||
|
#
|
||||||
|
# A shutdown is bounded at ten minutes, not systemd's thirty. A unit started again during the shutdown
|
||||||
|
# (on ace, 2026-10-28, the bus and the authorization manager) is never stopped a second time, and the
|
||||||
|
# shutdown then waits on this job's timeout with nothing on the console. The target keeps its own
|
||||||
|
# forcing action: the last phase still ends every process, unmounts and syncs.
|
||||||
|
[Unit]
|
||||||
|
JobTimeoutSec=10min
|
||||||
@@ -7,6 +7,9 @@
|
|||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": {
|
"identity": {
|
||||||
"in": "a Redis ACL user and key prefix"
|
"in": "a Redis ACL user and key prefix"
|
||||||
|
},
|
||||||
|
"credential": {
|
||||||
|
"form": "pair"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -41,40 +41,40 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"keep-daily": {
|
"keep-daily": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"description": "How many nightly restore points are kept, a count from 1 to 9999: two weeks undo a mistake noticed within a fortnight. Read by the night, which thins nothing while it does not read (novox/hq issue 416); lowering it deletes the restore points beyond the new count at the next night, and that cannot be undone.",
|
"description": "How many nightly restore points are kept, a count from 1 to 9999: two weeks undo a mistake noticed within a fortnight. Read by the night, which thins nothing while it does not read (novox/hq issue 416); lowering it deletes the restore points beyond the new count at the next night, and that cannot be undone.",
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
"maximum": 9999,
|
"maximum": 9999,
|
||||||
"trusted": true,
|
"trusted": true,
|
||||||
"default": 14
|
"default": 14
|
||||||
},
|
|
||||||
"keep-weekly": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "How many weekly restore points are kept behind the dailies, a count from 1 to 9999, refused by the night like keep-daily; lowering it deletes the restore points beyond the new count at the next night, and that cannot be undone.",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 9999,
|
|
||||||
"trusted": true,
|
|
||||||
"default": 8
|
|
||||||
},
|
|
||||||
"keep-monthly": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "How many monthly restore points are kept behind the weeklies, a count from 1 to 9999, refused by the night like keep-daily; lowering it deletes the restore points beyond the new count at the next night, and that cannot be undone.",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 9999,
|
|
||||||
"trusted": true,
|
|
||||||
"default": 6
|
|
||||||
},
|
|
||||||
"keep-hand-taken-days": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "How many days a restore point taken by hand (node-backup.now, or the mesh's before a module moves) is kept at least, a count from 1 to 9999; it is kept until a later good night of its module exists, and this many days in any case, so the next thinning never takes the one taken against a risky change (novox/hq issue 453). Lowering it lets go of the older ones taken by hand at the next thinning, and that cannot be undone.",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 9999,
|
|
||||||
"trusted": true,
|
|
||||||
"default": 7
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
"keep-weekly": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many weekly restore points are kept behind the dailies, a count from 1 to 9999, refused by the night like keep-daily; lowering it deletes the restore points beyond the new count at the next night, and that cannot be undone.",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 9999,
|
||||||
|
"trusted": true,
|
||||||
|
"default": 8
|
||||||
|
},
|
||||||
|
"keep-monthly": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many monthly restore points are kept behind the weeklies, a count from 1 to 9999, refused by the night like keep-daily; lowering it deletes the restore points beyond the new count at the next night, and that cannot be undone.",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 9999,
|
||||||
|
"trusted": true,
|
||||||
|
"default": 6
|
||||||
|
},
|
||||||
|
"keep-hand-taken-days": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "How many days a restore point taken by hand (node-backup.now, or the mesh's before a module moves) is kept at least, a count from 1 to 9999; it is kept until a later good night of its module exists, and this many days in any case, so the next thinning never takes the one taken against a risky change (novox/hq issue 453). Lowering it lets go of the older ones taken by hand at the next thinning, and that cannot be undone.",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 9999,
|
||||||
|
"trusted": true,
|
||||||
|
"default": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
"resources": [
|
"resources": [
|
||||||
{
|
{
|
||||||
"id": "state",
|
"id": "state",
|
||||||
@@ -139,22 +139,17 @@
|
|||||||
"MESH_BACKUP_DATA": "${dir:state}/data.conf"
|
"MESH_BACKUP_DATA": "${dir:state}/data.conf"
|
||||||
},
|
},
|
||||||
"health": {
|
"health": {
|
||||||
"kind": "tool",
|
"kind": "unit"
|
||||||
"tool": "backup_health",
|
|
||||||
"interval": "60s",
|
|
||||||
"timeout": "20s",
|
|
||||||
"looks": 2,
|
|
||||||
"grace": "60s"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "measure",
|
"id": "awake",
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"name": "restic-measure",
|
"name": "restic-awake",
|
||||||
"artifact": "tools",
|
"artifact": "tools",
|
||||||
"run": [
|
"run": [
|
||||||
"./restic-backups",
|
"./restic-backups",
|
||||||
"measure"
|
"awake"
|
||||||
],
|
],
|
||||||
"user": "${machine:account}",
|
"user": "${machine:account}",
|
||||||
"env": {
|
"env": {
|
||||||
@@ -165,7 +160,12 @@
|
|||||||
"MESH_BACKUP_DATA": "${dir:state}/data.conf"
|
"MESH_BACKUP_DATA": "${dir:state}/data.conf"
|
||||||
},
|
},
|
||||||
"health": {
|
"health": {
|
||||||
"kind": "unit"
|
"kind": "tool",
|
||||||
|
"tool": "backup_health",
|
||||||
|
"interval": "60s",
|
||||||
|
"timeout": "20s",
|
||||||
|
"looks": 2,
|
||||||
|
"grace": "60s"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -195,5 +195,11 @@
|
|||||||
"from": "files"
|
"from": "files"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"reads": [
|
||||||
|
"disk-load.readings"
|
||||||
|
],
|
||||||
|
"state": [
|
||||||
|
"good"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "route",
|
"name": "route",
|
||||||
|
"credential": {"form": "none"},
|
||||||
"scope": "mesh",
|
"scope": "mesh",
|
||||||
"identity": false
|
"identity": false
|
||||||
}
|
}
|
||||||
@@ -129,6 +130,7 @@
|
|||||||
"bound"
|
"bound"
|
||||||
],
|
],
|
||||||
"reads": [
|
"reads": [
|
||||||
"mesh-controller.assignments"
|
"mesh-provisioner.plans",
|
||||||
|
"mesh-provisioner.provisions"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "greeting",
|
"name": "greeting",
|
||||||
"scope": "mesh"
|
"scope": "mesh",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"serves": {
|
"serves": {
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "internal-acme-ca",
|
"name": "internal-acme-ca",
|
||||||
"scope": "mesh"
|
"scope": "mesh",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"serves": {
|
"serves": {
|
||||||
|
|||||||
@@ -8,7 +8,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "split-dns",
|
"name": "split-dns",
|
||||||
"reach": "machine"
|
"reach": "machine",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"requires": [
|
"requires": [
|
||||||
|
|||||||
@@ -32,7 +32,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "analytics",
|
"name": "analytics",
|
||||||
"scope": "mesh"
|
"scope": "mesh",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"serves": {
|
"serves": {
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
"provides": [
|
"provides": [
|
||||||
{
|
{
|
||||||
"name": "x11-display",
|
"name": "x11-display",
|
||||||
"reach": "machine"
|
"reach": "machine",
|
||||||
|
"credential": {
|
||||||
|
"form": "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"claims": [
|
"claims": [
|
||||||
|
|||||||
Reference in New Issue
Block a user