mirror of
https://github.com/vbatts/go-mtree.git
synced 2025-07-14 02:39:11 +00:00
*: 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>
This commit is contained in:
parent
e359fa7d2d
commit
fc5450ed71
10 changed files with 351 additions and 11 deletions
87
update.go
Normal file
87
update.go
Normal file
|
@ -0,0 +1,87 @@
|
|||
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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue