diff options
-rw-r--r-- | libpod/diff.go | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/libpod/diff.go b/libpod/diff.go index f348e6b81..925bda927 100644 --- a/libpod/diff.go +++ b/libpod/diff.go @@ -1,6 +1,9 @@ package libpod import ( + "archive/tar" + "io" + "github.com/containers/libpod/libpod/layers" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" @@ -44,6 +47,59 @@ func (r *Runtime) GetDiff(from, to string) ([]archive.Change, error) { return rchanges, err } +// skipFileInTarAchive is an archive.TarModifierFunc function +// which tells archive.ReplaceFileTarWrapper to skip files +// from the tarstream +func skipFileInTarAchive(path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error) { + return nil, nil, nil +} + +// GetDiffTarStream returns the differences between the two images, layers, or containers. +// It is the same functionality as GetDiff() except that it returns a tarstream +func (r *Runtime) GetDiffTarStream(from, to string) (io.ReadCloser, error) { + toLayer, err := r.getLayerID(to) + if err != nil { + return nil, err + } + fromLayer := "" + if from != "" { + fromLayer, err = r.getLayerID(from) + if err != nil { + return nil, err + } + } + rc, err := r.store.Diff(fromLayer, toLayer, nil) + if err != nil { + return nil, err + } + + // Skip files in the tar archive which are listed + // in containerMounts map. Just as in the GetDiff() + // function from above + filterMap := make(map[string]archive.TarModifierFunc) + for key := range containerMounts { + filterMap[key[1:]] = skipFileInTarAchive + // In the tarstream directories always include a trailing '/'. + // For simplicity this duplicates every entry from + // containerMounts with a trailing '/', as containerMounts + // does not use trailing '/' for directories. + filterMap[key[1:]+"/"] = skipFileInTarAchive + } + + filteredTarStream := archive.ReplaceFileTarWrapper(rc, filterMap) + return filteredTarStream, nil +} + +// ApplyDiffTarStream applies the changes stored in 'diff' to the layer 'to' +func (r *Runtime) ApplyDiffTarStream(to string, diff io.Reader) error { + toLayer, err := r.getLayerID(to) + if err != nil { + return err + } + _, err = r.store.ApplyDiff(toLayer, diff) + return err +} + // GetLayerID gets a full layer id given a full or partial id // If the id matches a container or image, the id of the top layer is returned // If the id matches a layer, the top layer id is returned |