85 lines
2.9 KiB
Go
85 lines
2.9 KiB
Go
package resolution
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"path"
|
|
|
|
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
const filesAsAccount = "as the node's operator account, through sudo -n where its rights do not reach; a place a " +
|
|
"secret is kept, or a known credential file, is refused by name"
|
|
|
|
const overrideWord = "a reason, to change a path a module owns anyway (optional)"
|
|
|
|
// ownedPaths is every path a module owns on this node, as the holder is told (novox/hq ADR 0394 §5): the
|
|
// paths every seat declares (ADR 0287) with the module holding the seat here, and the paths and files each
|
|
// module's manifest places (declaredPaths). A seat's path wins where both name one.
|
|
func resolutionOwnedPaths(r mcat.Resolution) map[string]string {
|
|
owned := map[string]string{}
|
|
for _, m := range r.Modules {
|
|
for _, p := range sortedKeys(declaredPaths(m)) {
|
|
owned[p] = m.Module + " (its own tools)"
|
|
}
|
|
}
|
|
for _, s := range mcat.Seats() {
|
|
for _, sp := range s.Paths {
|
|
for _, m := range r.Modules {
|
|
if m.ClaimsSeat(s.Name) && declaresPath(m, path.Clean(sp.Path)) && !resolutionStepsBackHere(r, m, sp) {
|
|
owned[sp.Path] = m.Module + " (" + s.Name + ")"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return owned
|
|
}
|
|
|
|
// stepsBackHere says m's seat path steps back on this machine (novox/hq ADR 0287): it names a seat whose holder here
|
|
// declares the path too, so that holder owns it, as stepsBack leaves m's own rendering of it out. Without it the owner
|
|
// told was the last seat in the order of the seat table, which the controller reads sorted by name and a node in the
|
|
// order compiled (issue 1126, C3: /etc/resolv.conf, node-uplink against node-resolver).
|
|
func resolutionStepsBackHere(r mcat.Resolution, m mcat.Manifest, sp mcat.SeatPath) bool {
|
|
if sp.StepsBackFor == "" {
|
|
return false
|
|
}
|
|
for _, o := range r.Modules {
|
|
if o.Module != m.Module && holdsSeat(o, sp.StepsBackFor) && declaresPath(o, path.Clean(sp.Path)) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// filesWords is what the holder of node-files is given beside its own words: the node's secret places and the
|
|
// paths modules own here.
|
|
func resolutionFilesWords(r mcat.Resolution, m mcat.Manifest, words map[string]string, with mcat.Rendering) (map[string]string, error) {
|
|
if !m.ClaimsSeat(mcat.FilesSeat) {
|
|
return words, nil
|
|
}
|
|
places, err := resolutionSecretPlaces(r, with)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
places2, err := json.Marshal(places)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
owned, err := json.Marshal(resolutionOwnedPaths(r))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if words == nil {
|
|
words = map[string]string{}
|
|
}
|
|
for _, w := range []string{mcat.ReadsSecretPlaces, mcat.FilesOwnedPaths} {
|
|
if _, has := words[w]; has {
|
|
return nil, fmt.Errorf("%s gives its own %s; the node's secret places and owned paths are the mesh's to "+
|
|
"say (novox/hq ADR 0394 §5)", m.Module, w)
|
|
}
|
|
}
|
|
words[mcat.ReadsSecretPlaces] = string(places2)
|
|
words[mcat.FilesOwnedPaths] = string(owned)
|
|
return words, nil
|
|
}
|