aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Reber <areber@redhat.com>2019-06-26 12:01:55 +0000
committerAdrian Reber <areber@redhat.com>2019-07-11 14:43:34 +0200
commitd5f1caaf505a87f093b3c715e9c53ee304917ac4 (patch)
tree8de9d0b72c994fcaaf6ad667a77b106cd2712b27
parent144567b42dba2c8c426538a4b5fe7d718b43284a (diff)
downloadpodman-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.go56
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