Hold a joining build for a person without superseding its delivery, join only on an engine that keeps own groups, and keep a held module's settings (hq ADR 0328 §8, ADR 0334; re-review of 96e15f86)
A delivery does not send a joining build held for its library or its engine: the module waits for a person, the plan stays open saying so and judges its other modules, and sends it once nothing holds it. A held move is no move for the gate. A module joins only on an engine at contract 7, and a held module is composed with the settings it last ran with. The runner's verdicts are said for their modules and judged by whether a move changes them. mesh-host pinned at #97 (7a41e120), its bundle now examples/foundation-first-node.lock.
This commit is contained in:
@@ -82,7 +82,7 @@ func theCarriedAccounts(t *testing.T) string {
|
||||
// the commit the mesh runs, or as captured in testdata/beside (internal/beside, novox/hq issue 432).
|
||||
func theTemplate(t *testing.T) []map[string]any {
|
||||
t.Helper()
|
||||
path := filepath.Join(beside.Dir(t, "mesh-host"), "examples", "foundation-first-node-nats.lock")
|
||||
path := filepath.Join(beside.Dir(t, "mesh-host"), "examples", "foundation-first-node.lock")
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
||||
@@ -335,6 +335,7 @@ func TestTheEngineTakesWhatIsComposedForLibraries(t *testing.T) {
|
||||
for _, node := range []string{"ace", "novox"} {
|
||||
r := Resolution{Node: node, Account: "jochen", Modules: []Manifest{aRadarr(t), theRuntime(t)}}
|
||||
with := librariesRendering()
|
||||
with.RunnerJoinsOwnGroups = true // contract 7 (mesh-host #97): the runner on identities, setgid on own directories
|
||||
with.Libraries["books"] = Library{Name: "books", Home: "ace", Root: "/storage/books", Reach: []string{"novox"}}
|
||||
composed := composeLibraries(t, r, with)
|
||||
body, err := json.Marshal(map[string]any{"declaration": validate.Version, "resources": composed.Resources,
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
|
||||
@@ -290,3 +291,41 @@ func (i *Inventory) TakeFailed(ctx context.Context, library, warrant string) err
|
||||
`delete from kept_library where library = $1 and warrant = $2 and not done`, library, warrant)
|
||||
return err
|
||||
}
|
||||
|
||||
// SettingsAsOf is a module's settings layers on a machine as they stood at a moment: each layer — the whole mesh's,
|
||||
// then the machine's — as it was set then, read from the layer standing now or from its history. What a module held at
|
||||
// the build it ran is composed with: the settings it last ran with (novox/hq ADR 0328 §8).
|
||||
func (i *Inventory) SettingsAsOf(ctx context.Context, nodeName, module string, at time.Time) ([]catalogue.Layer, error) {
|
||||
node, err := i.NodeByName(ctx, nodeName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var layers []catalogue.Layer
|
||||
for _, scope := range []struct {
|
||||
id *string
|
||||
from string
|
||||
}{{nil, catalogue.MeshWideLayer}, {&node.ID, nodeName}} {
|
||||
var raw []byte
|
||||
err := i.store.Pool().QueryRow(ctx,
|
||||
`select values from settings
|
||||
where module = $1 and node is not distinct from $2::uuid and set_at <= $3
|
||||
union all
|
||||
select values from (select values from settings_history
|
||||
where module = $1 and node is not distinct from $2::uuid
|
||||
and (set_at is null or set_at <= $3) and replaced_at > $3
|
||||
order by replaced_at asc limit 1) h
|
||||
limit 1`, module, scope.id, at).Scan(&raw)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values := map[string]any{}
|
||||
if err := json.Unmarshal(raw, &values); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
layers = append(layers, catalogue.Layer{From: scope.from, Values: values})
|
||||
}
|
||||
return layers, nil
|
||||
}
|
||||
|
||||
@@ -457,6 +457,10 @@ const LibraryContract = 6
|
||||
// Identity and put that account in the group mesh-<module>, and accept a directory mode whose first digit is 2.
|
||||
const OwnGroupContract = 7
|
||||
|
||||
// KindRunner is the tool runner's membership as the engine states it (novox/hq ADR 0334 §2; mesh-host internal/link):
|
||||
// `runner:<module>` of a joining module, in its own group; `runner:library:<name>` of no module, in a library's group.
|
||||
const KindRunner = "runner"
|
||||
|
||||
// KindLibrary is a library's own verdict on its home, as the engine may state it (novox/hq ADR 0328): healthy once
|
||||
// kept. Read beside an access verdict naming the library until the engine's shape is settled.
|
||||
const KindLibrary = "library"
|
||||
|
||||
Reference in New Issue
Block a user