diff options
author | Adrian Reber <areber@redhat.com> | 2019-06-26 12:01:55 +0000 |
---|---|---|
committer | Adrian Reber <areber@redhat.com> | 2019-07-11 14:43:34 +0200 |
commit | d5f1caaf505a87f093b3c715e9c53ee304917ac4 (patch) | |
tree | 8de9d0b72c994fcaaf6ad667a77b106cd2712b27 | |
parent | 144567b42dba2c8c426538a4b5fe7d718b43284a (diff) | |
download | podman-d5f1caaf505a87f093b3c715e9c53ee304917ac4.tar.gz podman-d5f1caaf505a87f093b3c715e9c53ee304917ac4.tar.bz2 podman-d5f1caaf505a87f093b3c715e9c53ee304917ac4.zip |
Add function to get a filtered tarstream diff
The newly added function GetDiffTarStream() mirrors the GetDiff()
function. It tries to get the correct layer ID from getLayerID()
and it filters out containerMounts from the tarstream. Thus the
behavior is the same as GetDiff(), but it returns a tarstream.
This also adds the function ApplyDiffTarStream() to apply the tarstream
generated by GetDiffTarStream().
These functions are targeted to support container migration with
root file-system changes.
Signed-off-by: Adrian Reber <areber@redhat.com>
-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 |