mirror of
https://github.com/vbatts/go-mtree.git
synced 2024-11-22 08:25:38 +00:00
gomtree: add special cases for tar generation checking
Due to several unsolveable problems in tar generation, such as the size=... keyword, we have to special case quite a few things in the checking code. We might want to move this to mtree properly (but I'm hesitant about ignoring errors that only happen for tar DHes). Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
parent
d214ab47e8
commit
3bfdecf467
1 changed files with 87 additions and 0 deletions
|
@ -62,6 +62,90 @@ var formats = map[string]func([]mtree.InodeDelta) string{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isDirEntry returns wheter an mtree.Entry describes a directory.
|
||||||
|
func isDirEntry(e mtree.Entry) bool {
|
||||||
|
for _, kw := range e.Keywords {
|
||||||
|
kv := mtree.KeyVal(kw)
|
||||||
|
if kv.Keyword() == "type" {
|
||||||
|
return kv.Value() == "dir"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Shouldn't be reached.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// filterMissingKeywords is a fairly annoying hack to get around the fact that
|
||||||
|
// tar archive manifest generation has certain unsolveable problems regarding
|
||||||
|
// certain keywords. For example, the size=... keyword cannot be implemented
|
||||||
|
// for directories in a tar archive (which causes Missing errors for that
|
||||||
|
// keyword).
|
||||||
|
//
|
||||||
|
// This function just removes all instances of Missing errors for keywords.
|
||||||
|
// This makes certain assumptions about the type of issues tar archives have.
|
||||||
|
// Only call this on tar archive manifest comparisons.
|
||||||
|
func filterMissingKeywords(diffs []mtree.InodeDelta) []mtree.InodeDelta {
|
||||||
|
newDiffs := []mtree.InodeDelta{}
|
||||||
|
loop:
|
||||||
|
for _, diff := range diffs {
|
||||||
|
if diff.Type() == mtree.Modified {
|
||||||
|
// We only apply this filtering to directories.
|
||||||
|
// NOTE: This will probably break if someone drops the size keyword.
|
||||||
|
if isDirEntry(*diff.Old()) || isDirEntry(*diff.New()) {
|
||||||
|
// If this applies to '.' then we just filter everything
|
||||||
|
// (meaning we remove this entry). This is because note all tar
|
||||||
|
// archives include a '.' entry. Which makes checking this not
|
||||||
|
// practical.
|
||||||
|
if diff.Path() == "." {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only filter out the size keyword.
|
||||||
|
// NOTE: This currently takes advantage of the fact the
|
||||||
|
// diff.Diff() returns the actual slice to diff.keys.
|
||||||
|
keys := diff.Diff()
|
||||||
|
for idx, k := range keys {
|
||||||
|
// Delete the key if it's "size". Unfortunately in Go you
|
||||||
|
// can't delete from a slice without reassigning it. So we
|
||||||
|
// just overwrite it with the last value.
|
||||||
|
if k.Name() == "size" {
|
||||||
|
if len(keys) < 2 {
|
||||||
|
continue loop
|
||||||
|
}
|
||||||
|
keys[idx] = keys[len(keys)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we got here, append to the new set.
|
||||||
|
newDiffs = append(newDiffs, diff)
|
||||||
|
}
|
||||||
|
return newDiffs
|
||||||
|
}
|
||||||
|
|
||||||
|
// isTarSpec returns whether the spec provided came from the tar generator.
|
||||||
|
// This takes advantage of an unsolveable problem in tar generation.
|
||||||
|
func isTarSpec(spec *mtree.DirectoryHierarchy) bool {
|
||||||
|
// Find a directory and check whether it's missing size=...
|
||||||
|
// NOTE: This will definitely break if someone drops the size=... keyword.
|
||||||
|
for _, e := range spec.Entries {
|
||||||
|
if !isDirEntry(e) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, kw := range e.Keywords {
|
||||||
|
kv := mtree.KeyVal(kw)
|
||||||
|
if kv.Keyword() == "size" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should never be reached.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
@ -327,6 +411,9 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if res != nil {
|
if res != nil {
|
||||||
|
if isTarSpec(specDh) || *flTar != "" {
|
||||||
|
res = filterMissingKeywords(res)
|
||||||
|
}
|
||||||
if len(res) > 0 {
|
if len(res) > 0 {
|
||||||
defer os.Exit(1)
|
defer os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue