1
0
Fork 0
mirror of https://github.com/vbatts/go-mtree.git synced 2024-11-22 08:25:38 +00:00
go-mtree/update.go
Vincent Batts ed464af779
*: xattr can Update()
This is a gnarly patchset that has been mashed together.
It uncovered that some aspects of Check were never really working
correctly for `xattr` keywords, but also the `Update()` had been left
undone for a while.

This includes some API changes around the `Keyword` and `KeyVal` types.

Also I would like to update the signature for the `UpdateKeywordFunc` to
just accept a `KeyVal` as an argugment, rather than a keyword AND the
value. with this context there would be no need to guess on the value of
what's passed to the xattr update function of whether it needs or
already is base64 encoded.

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2017-06-24 15:05:24 -04:00

90 lines
2.1 KiB
Go

package mtree
import (
"os"
"sort"
"github.com/Sirupsen/logrus"
)
// DefaultUpdateKeywords is the default set of keywords that can take updates to the files on disk
var DefaultUpdateKeywords = []Keyword{
"uid",
"gid",
"mode",
"time",
"xattr",
}
// Update attempts to set the attributes of root directory path, given the values of `keywords` in dh DirectoryHierarchy.
func Update(root string, dh *DirectoryHierarchy, keywords []Keyword, fs FsEval) ([]InodeDelta, error) {
creator := dhCreator{DH: dh}
curDir, err := os.Getwd()
if err == nil {
defer os.Chdir(curDir)
}
if err := os.Chdir(root); err != nil {
return nil, err
}
sort.Sort(byPos(creator.DH.Entries))
results := []InodeDelta{}
for i, e := range creator.DH.Entries {
switch e.Type {
case SpecialType:
if e.Name == "/set" {
creator.curSet = &creator.DH.Entries[i]
} else if e.Name == "/unset" {
creator.curSet = nil
}
logrus.Debugf("%#v", e)
continue
case RelativeType, FullType:
e.Set = creator.curSet
pathname, err := e.Path()
if err != nil {
return nil, err
}
// filter the keywords to update on the file, from the keywords available for this entry:
var kvToUpdate []KeyVal
kvToUpdate = keyvalSelector(e.AllKeys(), keywords)
logrus.Debugf("kvToUpdate(%q): %#v", pathname, kvToUpdate)
for _, kv := range kvToUpdate {
if !InKeywordSlice(kv.Keyword().Prefix(), keywordPrefixes(keywords)) {
continue
}
logrus.Debugf("finding function for %q (%q)", kv.Keyword(), kv.Keyword().Prefix())
ukFunc, ok := UpdateKeywordFuncs[kv.Keyword().Prefix()]
if !ok {
logrus.Debugf("no UpdateKeywordFunc for %s; skipping", kv.Keyword())
continue
}
if _, err := ukFunc(kv.Keyword(), pathname, kv.Value()); err != nil {
results = append(results, InodeDelta{
diff: ErrorDifference,
path: pathname,
old: e,
keys: []KeyDelta{
{
diff: ErrorDifference,
name: kv.Keyword(),
err: err,
},
}})
}
}
}
}
return results, nil
}
// Result of an "update" returns the produced results
type Result struct {
Path string
Keyword Keyword
Got string
}