Keep libraries under groups of their own, and give modules users in them (hq ADR 0328, issue 567)
ADR 0328 supersedes ADR 0325: shared data is a library with one home, kept usable by its group rather than by ACL entries. The engine now makes each library's group and each module's user in its libraries' groups; keeps a library's root and requested sub-paths in its group with group write and setgid on its home, making missing sub-paths as the root is; waits for the operator's word before touching a root that holds data, and on the take act walks it by descriptor (no link, same filesystem, bounded and resumed, files with other names left); holds the containers of a library whose disk or mount is not there; and puts the tool runner's account in the group. The ACL keeping, mask repair and watch are gone; an access is again as before ADR 0325.
This commit is contained in:
+11
-17
@@ -328,16 +328,15 @@ type DirectoryJudgements interface {
|
||||
HearDirectoryJudgements(JudgeDirectoriesFunc)
|
||||
}
|
||||
|
||||
// The take act on an accessed folder, asked over the bus (novox/hq ADR 0325 §8, issue 567).
|
||||
// The take act on a library, asked over the bus (novox/hq ADR 0328 §7, issue 567).
|
||||
//
|
||||
// A folder that already holds data is kept only on the operator's word: the access waits (§7), the controller asks
|
||||
// the operator once for that folder on that machine (ADR 0259), and on the approved warrant asks this node's engine
|
||||
// on AskAccessActSubject, signed as a hand-over is and held to the same checks (believed), under a signing context
|
||||
// of its own, naming the act, the access, its folder as the engine states it, and the warrant. The engine judges
|
||||
// every value against what it was last declared and what is on disk, answers at once that the act started or why
|
||||
// it is refused, adds the users' entries to everything under the folder (following no link, entering no other
|
||||
// filesystem), and states the act on the access's verdict (Act). Adding or dropping a user of a folder already
|
||||
// taken asks nobody: the engine does it on the apply that declares it.
|
||||
// A library whose root already holds data is kept only on the operator's word: it waits (§8), the controller asks
|
||||
// the operator once for that library (ADR 0259), and on the approved warrant asks the library's home engine on
|
||||
// AskAccessActSubject, signed as a hand-over is and held to the same checks (believed), under a signing context of
|
||||
// its own, naming the act, the access `library:<name>`, its root as the engine states it, and the warrant. The engine
|
||||
// judges every value against what it was last declared and what is on disk, answers at once that the act started or
|
||||
// why it is refused, sets the library's group, group write and setgid on everything under the root (following no
|
||||
// link, entering no other filesystem), and states the act on the library's verdict (Act).
|
||||
|
||||
// AskAccessActSubject is where the controller asks this node's engine to run an act on one access's folder.
|
||||
func AskAccessActSubject(node string) string { return "mesh.node." + node + ".ask.access-act" }
|
||||
@@ -345,14 +344,9 @@ func AskAccessActSubject(node string) string { return "mesh.node." + node + ".as
|
||||
// AccessActContext is prefixed to an act ask's bytes before signing: never another ask's, nor a declaration's.
|
||||
const AccessActContext = "novox-mesh access-act v2\n"
|
||||
|
||||
// The walks under an accessed folder. Only ActTake is asked; ActAdd and ActDrop are what an apply starts.
|
||||
const (
|
||||
// ActTake adds the users' entries to the folder and everything under it, on a warrant (ADR 0325 §8).
|
||||
ActTake = "take"
|
||||
// ActAdd adds the entries of a user that joined a taken folder; ActDrop removes exactly a dropped user's.
|
||||
ActAdd = "add"
|
||||
ActDrop = "drop"
|
||||
)
|
||||
// ActTake is the one act asked: the library's group, group write and setgid set on everything under its root, on
|
||||
// a warrant (ADR 0328 §7).
|
||||
const ActTake = "take"
|
||||
|
||||
// AccessActAsk is an act's own fields, beside a hand-over's (node, path, by, expires, nonce): which act, the
|
||||
// access by its declared resource id exactly as the declaration names it (`/` allowed), and the warrant the
|
||||
|
||||
@@ -66,7 +66,7 @@ type natsLink struct {
|
||||
searching *nats.Subscription
|
||||
// judging hears the controller asking for a read-only judgement of this node's directories (issue 358).
|
||||
judging *nats.Subscription
|
||||
// acting hears the controller asking for the take act on an access's folder (novox/hq ADR 0325 §8).
|
||||
// acting hears the controller asking for the take act on a library (novox/hq ADR 0328 §7).
|
||||
acting *nats.Subscription
|
||||
node string
|
||||
// signer is the mesh's key, which a hand-over ask is verified with as a declaration is (issue 356).
|
||||
@@ -262,7 +262,7 @@ func (l *natsLink) HearDirectoryJudgements(handle JudgeDirectoriesFunc) {
|
||||
}
|
||||
|
||||
// HearAccessActs listens for the controller asking this node to run the take act on an access's folder (novox/hq ADR
|
||||
// 0325 §8), on this machine's own subject, verified as a hand-over is (AnswerAccessAct). A bus whose user list is older
|
||||
// 0328 §7), on this machine's own subject, verified as a hand-over is (AnswerAccessAct). A bus whose user list is older
|
||||
// than the grant refuses the subscription, said by the client; the controller then hears no answer.
|
||||
func (l *natsLink) HearAccessActs(handle AccessActFunc) {
|
||||
if handle == nil {
|
||||
|
||||
+29
-40
@@ -266,6 +266,14 @@ const GrantContract = 4
|
||||
// tells the controller this host may be sent those fields; an older host refuses the whole declaration for them.
|
||||
const IdentityContract = 5
|
||||
|
||||
// LibraryContract is the statement of a host that reads a declaration's `groups` and `libraries` and an identity's
|
||||
// `groups` (novox/hq ADR 0328, which supersedes ADR 0325): it makes each library's group and each module's user in
|
||||
// its libraries' groups, keeps each library it is home to under its group, holds the containers of a library whose
|
||||
// disk is not there, states a library it may not keep yet as waiting, and hears the take act for `library:<name>`.
|
||||
// It keeps no ACL entries: an access's `users` and `taken` are accepted and not acted on. Like the fields before
|
||||
// it, its presence is what tells the controller this host may be sent those fields.
|
||||
const LibraryContract = 6
|
||||
|
||||
// Health is one statement of every long-running resource's state on this machine (to-be 48 §4). Said in
|
||||
// every report, as an event on each change, and again every minute while anything is not healthy — so a
|
||||
// lost statement is not a lost fault.
|
||||
@@ -304,15 +312,14 @@ const KindAccount = "account"
|
||||
// starting ReasonUsedAsFound, until the operator hands it to the mesh (`nox node hand-over <node> <path>` on the control-node, novox/hq issue 356).
|
||||
const KindDirectory = "directory"
|
||||
|
||||
// KindAccess is an access whose folder the engine keeps for its users (novox/hq ADR 0325): healthy while every user
|
||||
// has its effective right on the folder and the sweep's sample under it (§10), waiting while the mesh may not keep
|
||||
// it yet or its disk is not there (§7), unhealthy otherwise — root's data on its placed filesystem among it (§12).
|
||||
// KindAccess is an access (novox/hq ADR 0051): no engine since ADR 0328 states one; kept for the controller's reading
|
||||
// of an older engine's statements.
|
||||
const KindAccess = "access"
|
||||
|
||||
// KindKeptEntries is the mesh's entries on a shared folder that nobody wants and that could not be taken out yet
|
||||
// (novox/hq ADR 0325 §8): a folder no access names whose disk is away, or entries left on a filesystem no longer at
|
||||
// a folder. Unhealthy, said under the access that last named it, until the drop walk has run.
|
||||
const KindKeptEntries = "kept-entries"
|
||||
// KindLibrary is a library this machine is reached by (novox/hq ADR 0328), said under resource `library:<name>`
|
||||
// with no module: healthy while it is kept (or, not home, while its mount is there), waiting with an access wait of
|
||||
// reason keep or disk, unknown while its filesystem could not be named, unhealthy otherwise.
|
||||
const KindLibrary = "library"
|
||||
|
||||
// ReasonUsedAsFound starts the reason of a directory used as found.
|
||||
const ReasonUsedAsFound = "used as found:"
|
||||
@@ -426,24 +433,21 @@ type ResourceHealth struct {
|
||||
// Waits is what a resource stated waiting waits for (novox/hq ADR 0283): each one own secret or one
|
||||
// setting of the module by name, the part, and what the operator gives, in words. Absent otherwise.
|
||||
Waits []health.Wait `json:"waits,omitempty"`
|
||||
// AccessWaits is what an access stated waiting waits for (novox/hq ADR 0325 §7). Beside Waits rather than in
|
||||
// AccessWaits is what a library stated waiting waits for (novox/hq ADR 0328 §8, §9). Beside Waits rather than in
|
||||
// it because mesh-sdk's health.Wait names a secret or a setting and nothing else; it moves there once that type
|
||||
// has a kind. Absent otherwise.
|
||||
AccessWaits []AccessWait `json:"access-waits,omitempty"`
|
||||
// Act is the last walk under an access's folder (ADR 0325 §8): a take on a warrant, or an add or a drop of a
|
||||
// user's entries. Absent on every other verdict, and on a folder never walked.
|
||||
// Act is the last walk under a library's root (ADR 0328 §7): the take on a warrant. Absent on every other
|
||||
// verdict, and on a library never walked.
|
||||
Act *AccessActRecord `json:"act,omitempty"`
|
||||
// Entries is the listing of a kept folder's users, for an access's verdict (ADR 0325 §4): each identity, its
|
||||
// use, and a note beside the tool runner's entry. Absent on a folder not kept.
|
||||
Entries []KeptEntry `json:"entries,omitempty"`
|
||||
}
|
||||
|
||||
// WaitKindAccess is the kind of a wait on an access (novox/hq ADR 0325 §7).
|
||||
// WaitKindAccess is the kind of a wait on a library (novox/hq ADR 0328 §8, §9; first ADR 0325 §7).
|
||||
const WaitKindAccess = "access"
|
||||
|
||||
// AccessWait is one access waiting for the operator: the access by its module's own id for it, the part (its
|
||||
// module), and what the operator gives, in words with no path (ADR 0234 §6): "let the mesh keep the shared folder
|
||||
// movies", or "mount the disk that holds books".
|
||||
// AccessWait is one library waiting for the operator (ADR 0328 §8, §9): the access `library:<name>`, the part (the
|
||||
// library), and what the operator gives, in words with no path (ADR 0234 §6): "let the mesh keep the library media",
|
||||
// or "mount the disk that holds the library media".
|
||||
type AccessWait struct {
|
||||
// Kind is WaitKindAccess.
|
||||
Kind string `json:"kind"`
|
||||
@@ -456,31 +460,14 @@ type AccessWait struct {
|
||||
// Reason is what the wait is for, for the controller to read without parsing words: WaitKeep (the operator's
|
||||
// word to keep it) or WaitDisk (its disk mounted).
|
||||
Reason string `json:"reason"`
|
||||
// ACL is said on a keep wait whose folder's filesystem refuses access entries now: ACLNeedsEnabling when the
|
||||
// take act will let it (a ZFS dataset's acltype, which the ask then says it sets), ACLUnsupported when no act
|
||||
// can (the operator mounts it with ACLs). Absent when it allows them.
|
||||
ACL string `json:"acl,omitempty"`
|
||||
}
|
||||
|
||||
// The reasons of an access wait, and what its filesystem says of ACLs.
|
||||
// The reasons of an access wait.
|
||||
const (
|
||||
WaitKeep = "keep"
|
||||
WaitDisk = "disk"
|
||||
ACLNeedsEnabling = "needs-enabling"
|
||||
ACLUnsupported = "unsupported"
|
||||
WaitKeep = "keep"
|
||||
WaitDisk = "disk"
|
||||
)
|
||||
|
||||
// KeptEntry is one user of a kept folder as its listing says it.
|
||||
type KeptEntry struct {
|
||||
Identity string `json:"identity"`
|
||||
UID int `json:"uid"`
|
||||
Use string `json:"use"`
|
||||
From string `json:"from"`
|
||||
// Note is said beside the tool runner's entry (ADR 0325 §4): it stands for every module whose tools use the
|
||||
// folder, at the widest use any of them declares.
|
||||
Note string `json:"note,omitempty"`
|
||||
}
|
||||
|
||||
// The states of a walk under an accessed folder.
|
||||
const (
|
||||
ActRunning = "running"
|
||||
@@ -491,10 +478,10 @@ const (
|
||||
ActFailed = "failed"
|
||||
)
|
||||
|
||||
// AccessActRecord is one walk under an access's folder, as the engine records it (novox/hq ADR 0325 §8). Counts
|
||||
// only: never a path.
|
||||
// AccessActRecord is one walk under a library's root, as the engine records it (novox/hq ADR 0328 §7). Counts only:
|
||||
// never a path.
|
||||
type AccessActRecord struct {
|
||||
// Act is ActTake, ActAdd or ActDrop.
|
||||
// Act is ActTake.
|
||||
Act string `json:"act"`
|
||||
Access string `json:"access"`
|
||||
Warrant string `json:"warrant,omitempty"`
|
||||
@@ -511,6 +498,8 @@ type AccessActRecord struct {
|
||||
Links int `json:"links,omitempty"`
|
||||
Other int `json:"other,omitempty"`
|
||||
Mounts int `json:"mounts,omitempty"`
|
||||
// Shared is the files with another name elsewhere (more than one link), left as they are.
|
||||
Shared int `json:"shared,omitempty"`
|
||||
// Why is what stopped or failed it, in words with no path.
|
||||
Why string `json:"why,omitempty"`
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ type Queue struct {
|
||||
// link (novox/hq issue 358). Nil answers every such ask with a refusal.
|
||||
JudgeDirectories JudgeDirectoriesFunc
|
||||
// AccessAct judges and runs the take act on an access's folder, asked by the controller on an approved
|
||||
// warrant (novox/hq ADR 0325 §8). Nil answers every such ask with a refusal.
|
||||
// warrant (novox/hq ADR 0328 §7). Nil answers every such ask with a refusal.
|
||||
AccessAct AccessActFunc
|
||||
Say Announce
|
||||
Timeout time.Duration
|
||||
|
||||
@@ -252,7 +252,7 @@ func serve(ctx context.Context, link Link, m Membership, queue *Queue, say Annou
|
||||
if j, ok := link.(DirectoryJudgements); ok {
|
||||
j.HearDirectoryJudgements(queue.JudgeDirectories)
|
||||
}
|
||||
// And asking for the take act on an access's folder, on a warrant (novox/hq ADR 0325 §8).
|
||||
// And asking for the take act on a library, on a warrant (novox/hq ADR 0328 §7).
|
||||
if s, ok := link.(AccessActs); ok {
|
||||
s.HearAccessActs(queue.AccessAct)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user