One object store, not two
object-store.json and minio.json described the same thing: same image, same provision at the same scope, same provisioner. Not two implementations a person could choose between — one module written twice. Assigning both to a node would have collided on `s3-bucket`. It exists because it was written first, to pair with photos.json for the README's worked edge, and minio.json was the fuller version of the same module written later. Nobody removed the first. The pair test keeps its point and now reads the surviving one. Checked across the rest: this was the only duplicate.
This commit is contained in:
@@ -2,8 +2,11 @@ package inventory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
|
||||
"github.com/novox/mesh-control/internal/secrets"
|
||||
)
|
||||
|
||||
@@ -150,6 +153,46 @@ func (i *Inventory) SecretsFrom(ctx context.Context, provider string) ([]Secret,
|
||||
// and kept, because regenerating it on every declaration would change the password a running
|
||||
// database has already been started with — and remade when the node's sealing key changes, for
|
||||
// the same reason as everything else sealed here.
|
||||
// ModuleSecretIfIssued is what a module already holds on a node, and nothing if it holds nothing.
|
||||
//
|
||||
// **The read half of SecretForModule**, which mints one when there is none — an insert, and a row
|
||||
// lock, on a path that also serves questions. Composing a declaration to answer *is this machine
|
||||
// running what I would send it* went through the minting version for every module on every node,
|
||||
// so asking wrote to the database and blocked against the machine it was asking about.
|
||||
//
|
||||
// A module with no secret yet has never been sent one, which is the same answer the caller wanted
|
||||
// anyway: this machine is not running what the mesh would send it.
|
||||
func (i *Inventory) ModuleSecretIfIssued(
|
||||
ctx context.Context, node, module, name string,
|
||||
) (string, bool, error) {
|
||||
key, err := i.SealingKeyOf(ctx, node)
|
||||
if err != nil || key == "" {
|
||||
return "", false, err
|
||||
}
|
||||
record, err := i.NodeByName(ctx, node)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
var sealed, against, origin string
|
||||
err = i.store.Pool().QueryRow(ctx,
|
||||
`select sealed, node_key, origin from module_secret
|
||||
where node = $1 and module = $2 and name = $3`,
|
||||
record.ID, module, name).Scan(&sealed, &against, &origin)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return "", false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
// Sealed to a key the node no longer has is not something it holds. Reported as absent rather
|
||||
// than as an error: this is the read, and refusing here would make a question fail for a
|
||||
// condition its writing counterpart is the right place to explain.
|
||||
if against != key {
|
||||
return "", false, nil
|
||||
}
|
||||
return sealed, true, nil
|
||||
}
|
||||
|
||||
func (i *Inventory) SecretForModule(ctx context.Context, node, module, name string) (string, error) {
|
||||
key, err := i.SealingKeyOf(ctx, node)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user