1
0
Fork 0
mirror of https://github.com/vbatts/go-mtree.git synced 2024-11-25 09:35:39 +00:00
go-mtree/update.go
Vincent Batts fc5450ed71
*: add an update/restore functionality
This allows for restoring some attributes of files from the state in an
mtree Manifest

Reported-by: Matthew Garrett <Matthewgarrett@google.com>
Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
2017-03-17 12:42:57 -04:00

87 lines
2 KiB
Go

package mtree
import (
"os"
"sort"
)
// DefaultUpdateKeywords is the default set of keywords that can take updates to the files on disk
var DefaultUpdateKeywords = []Keyword{
"uid",
"gid",
"mode",
"time",
// TODO 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
}
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 toCheck []KeyVal
toCheck = keyvalSelector(e.AllKeys(), keywords)
Debugf("toCheck(%q): %v", pathname, toCheck)
for _, kv := range toCheck {
if !InKeywordSlice(kv.Keyword(), keywords) {
continue
}
ukFunc, ok := UpdateKeywordFuncs[kv.Keyword()]
if !ok {
Debugf("no UpdateKeywordFunc for %s; skipping", kv.Keyword())
continue
}
if _, err := ukFunc(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
}