Merge pull request 'The licence manager declares its logs in the logs section, so they are issued and its carry-over can finish (issue 1409)' (#660) from fix/1409-logs-section into main
This commit was merged in pull request #660.
This commit is contained in:
@@ -32,7 +32,8 @@ from a file on this module's node or sealed by a node's `claude_code_add_api_key
|
|||||||
|
|
||||||
## What it keeps on the bus
|
## What it keeps on the bus
|
||||||
|
|
||||||
Each piece asked for in `requires` by its template (ADR 0595), read by `licences_kept`:
|
Each state asked for in `requires` by its template (ADR 0595), and the two logs declared in the `logs` section, the
|
||||||
|
form the runtime issues today (design 39 bus-and-switch C3); each read by `licences_kept`:
|
||||||
|
|
||||||
| name | template | what |
|
| name | template | what |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// design 39 bus-and-switch §1: the module moves to the new form whole — no `reads`, no old `state`, no `prepare`
|
// design 39 bus-and-switch §1: the module moves to the new form whole — no `reads`, no old `state`, no `prepare`
|
||||||
// step — and asks for each piece of its kept data by template.
|
// step — and asks for each state it keeps by template; its two logs are in the `logs` section with their bounds, the
|
||||||
|
// form the runtime on main issues (C3).
|
||||||
func TestTheManifestKeepsNoOldForm(t *testing.T) {
|
func TestTheManifestKeepsNoOldForm(t *testing.T) {
|
||||||
raw, err := os.ReadFile(filepath.Join(moduleDir, "module.json"))
|
raw, err := os.ReadFile(filepath.Join(moduleDir, "module.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -44,15 +45,32 @@ func TestTheManifestKeepsNoOldForm(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for name, template := range map[string]string{"licences": "state", "bindings": "state", "leases": "state",
|
for name, template := range map[string]string{"licences": "state", "bindings": "state", "leases": "state",
|
||||||
"offered": "state", "usage": "log", "audit": "log", "carried": "state", "conditions": "state"} {
|
"offered": "state", "usage": "", "audit": "", "carried": "state", "conditions": "state"} {
|
||||||
if kept[name] != template {
|
if kept[name] != template {
|
||||||
t.Errorf("bus-state entry %s is %q, want template %s", name, kept[name], template)
|
t.Errorf("bus-state entry %s is %q in requires, want %q", name, kept[name], template)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var logs []json.RawMessage
|
||||||
|
_ = json.Unmarshal(m["logs"], &logs)
|
||||||
|
declared := logsSection(logs)
|
||||||
|
for name, bounds := range map[string]map[string]float64{"usage": {"max-age-days": 35, "max-mib": 256},
|
||||||
|
"audit": {"max-mib": 64}} {
|
||||||
|
l, ok := declared[name]
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("the log %s is not in the logs section", name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for k, v := range bounds {
|
||||||
|
if l[k] != v {
|
||||||
|
t.Errorf("the log %s has %s %v, want %v", name, k, l[k], v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// issued is what the manager's own runtime is issued from its manifest (design 39 bus-and-switch C1): its account, the
|
// issued is what the manager's own runtime is issued from its manifest (design 39 bus-and-switch C1): its account, the
|
||||||
// states and logs it keeps (`requires` by template), what it may ask (`invokes`) and say (`emits`).
|
// states it keeps (`requires` by template), the logs it keeps (the `logs` section, the form the runtime on main issues,
|
||||||
|
// C3; a log asked for by template in `requires` is issued nothing), what it may ask (`invokes`) and say (`emits`).
|
||||||
type issued struct {
|
type issued struct {
|
||||||
RunsAs, SecretsOwner string
|
RunsAs, SecretsOwner string
|
||||||
OwnSecrets map[string]string
|
OwnSecrets map[string]string
|
||||||
@@ -72,6 +90,7 @@ func manifestIssued(t testing.TB) issued {
|
|||||||
SecretsOwner string `json:"secrets-owner"`
|
SecretsOwner string `json:"secrets-owner"`
|
||||||
OwnSecrets map[string]string `json:"own-secrets"`
|
OwnSecrets map[string]string `json:"own-secrets"`
|
||||||
Requires []json.RawMessage `json:"requires"`
|
Requires []json.RawMessage `json:"requires"`
|
||||||
|
Logs []json.RawMessage `json:"logs"`
|
||||||
Resources []map[string]any `json:"resources"`
|
Resources []map[string]any `json:"resources"`
|
||||||
Invokes []string `json:"invokes"`
|
Invokes []string `json:"invokes"`
|
||||||
Emits []string `json:"emits"`
|
Emits []string `json:"emits"`
|
||||||
@@ -86,13 +105,13 @@ func manifestIssued(t testing.TB) issued {
|
|||||||
if json.Unmarshal(r, &e) != nil {
|
if json.Unmarshal(r, &e) != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch e.Storage {
|
if e.Storage == "key-value" {
|
||||||
case "key-value":
|
|
||||||
out.States[e.Name] = true
|
out.States[e.Name] = true
|
||||||
case "stream":
|
|
||||||
out.Logs[e.Name] = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for name := range logsSection(m.Logs) {
|
||||||
|
out.Logs[name] = true
|
||||||
|
}
|
||||||
for _, k := range m.Invokes {
|
for _, k := range m.Invokes {
|
||||||
out.Invokes[k] = true
|
out.Invokes[k] = true
|
||||||
}
|
}
|
||||||
@@ -102,6 +121,25 @@ func manifestIssued(t testing.TB) issued {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// logsSection is the manifest's `logs` section by name: each a name alone or {name, max-age-days, max-mib}.
|
||||||
|
func logsSection(logs []json.RawMessage) map[string]map[string]any {
|
||||||
|
out := map[string]map[string]any{}
|
||||||
|
for _, l := range logs {
|
||||||
|
var name string
|
||||||
|
if json.Unmarshal(l, &name) == nil {
|
||||||
|
out[name] = map[string]any{}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var e map[string]any
|
||||||
|
if json.Unmarshal(l, &e) == nil {
|
||||||
|
if n, _ := e["name"].(string); n != "" {
|
||||||
|
out[n] = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// mayAsk is whether the manager's own account may ask key: a module tool asked on one node (`<module>.<tool>@<node>`)
|
// mayAsk is whether the manager's own account may ask key: a module tool asked on one node (`<module>.<tool>@<node>`)
|
||||||
// is invoked as `<module>.<tool>`.
|
// is invoked as `<module>.<tool>`.
|
||||||
func (i issued) mayAsk(key string) bool {
|
func (i issued) mayAsk(key string) bool {
|
||||||
|
|||||||
@@ -203,8 +203,14 @@ func TestKeptReadsEveryEntryOfTheManifest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
var m struct {
|
var m struct {
|
||||||
Requires []json.RawMessage `json:"requires"`
|
Requires []json.RawMessage `json:"requires"`
|
||||||
|
Logs []json.RawMessage `json:"logs"`
|
||||||
}
|
}
|
||||||
_ = json.Unmarshal(raw, &m)
|
_ = json.Unmarshal(raw, &m)
|
||||||
|
// The logs are declared in the logs section (C3), each read as a log.
|
||||||
|
for name := range logsSection(m.Logs) {
|
||||||
|
r, _ := json.Marshal(map[string]string{"name": name, "template": "log"})
|
||||||
|
m.Requires = append(m.Requires, r)
|
||||||
|
}
|
||||||
mm := newMesh(t)
|
mm := newMesh(t)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
_, _ = saying(mm)
|
_, _ = saying(mm)
|
||||||
|
|||||||
@@ -40,23 +40,6 @@
|
|||||||
"key-ttl": true
|
"key-ttl": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "usage",
|
|
||||||
"storage": "stream",
|
|
||||||
"template": "log",
|
|
||||||
"options": {
|
|
||||||
"max-age-days": 35,
|
|
||||||
"max-mib": 256
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "audit",
|
|
||||||
"storage": "stream",
|
|
||||||
"template": "log",
|
|
||||||
"options": {
|
|
||||||
"max-mib": 64
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "carried",
|
"name": "carried",
|
||||||
"storage": "key-value",
|
"storage": "key-value",
|
||||||
@@ -74,6 +57,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"logs": [
|
||||||
|
{
|
||||||
|
"name": "usage",
|
||||||
|
"max-age-days": 35,
|
||||||
|
"max-mib": 256
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "audit",
|
||||||
|
"max-mib": 64
|
||||||
|
}
|
||||||
|
],
|
||||||
"contributes": {
|
"contributes": {
|
||||||
"postgres-database": {
|
"postgres-database": {
|
||||||
"name": "claude_licences",
|
"name": "claude_licences",
|
||||||
|
|||||||
Reference in New Issue
Block a user