summaryrefslogtreecommitdiffstats
path: root/recipes-containers/oci-image-tools/files/0002-image-manifest-Split-unpackLayerEntry-into-its-own-f.patch
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@windriver.com>2017-06-06 23:44:34 -0400
committerBruce Ashfield <bruce.ashfield@windriver.com>2017-06-06 23:44:34 -0400
commit3e1d16db4aa3a76aa4086de49f3b62337c7f4efa (patch)
treed7d8427a7b74f58a6068e549dd205959d9140447 /recipes-containers/oci-image-tools/files/0002-image-manifest-Split-unpackLayerEntry-into-its-own-f.patch
parentdd49614c70364a11dc50798f32f1b2ffa3d0409e (diff)
downloadmeta-virtualization-3e1d16db4aa3a76aa4086de49f3b62337c7f4efa.tar.gz
oci-image-tools: update to latest and fix symlink issues
Updating to the latest oci-image-tools for better support in unpack/creating runtime bundles. With this update, we get a single tool with subcommands, versus separate commands previously. We also add two proposed (but not merged) patches that can deal with existing symlinks when unpacking layers. Without this, we fail to unpack many complex containers due to duplicate files in layers. Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
Diffstat (limited to 'recipes-containers/oci-image-tools/files/0002-image-manifest-Split-unpackLayerEntry-into-its-own-f.patch')
-rw-r--r--recipes-containers/oci-image-tools/files/0002-image-manifest-Split-unpackLayerEntry-into-its-own-f.patch242
1 files changed, 242 insertions, 0 deletions
diff --git a/recipes-containers/oci-image-tools/files/0002-image-manifest-Split-unpackLayerEntry-into-its-own-f.patch b/recipes-containers/oci-image-tools/files/0002-image-manifest-Split-unpackLayerEntry-into-its-own-f.patch
new file mode 100644
index 00000000..9cf513ec
--- /dev/null
+++ b/recipes-containers/oci-image-tools/files/0002-image-manifest-Split-unpackLayerEntry-into-its-own-f.patch
@@ -0,0 +1,242 @@
1From 1e55f2a83b1f644803b640b72171b4ae0d95217b Mon Sep 17 00:00:00 2001
2From: "W. Trevor King" <wking@tremily.us>
3Date: Thu, 20 Oct 2016 23:30:22 -0700
4Subject: [PATCH 2/2] image/manifest: Split unpackLayerEntry into its own
5 function
6
7To help address:
8
9 $ make lint
10 checking lint
11 image/manifest.go:140::warning: cyclomatic complexity 39 of function unpackLayer() is high (> 35) (gocyclo)
12 ...
13
14Signed-off-by: W. Trevor King <wking@tremily.us>
15---
16 image/manifest.go | 185 +++++++++++++++++++++++++++++-------------------------
17 1 file changed, 100 insertions(+), 85 deletions(-)
18
19diff --git a/image/manifest.go b/image/manifest.go
20index 144bd4f62219..dfd5a83f70e4 100644
21--- a/image/manifest.go
22+++ b/image/manifest.go
23@@ -218,116 +218,131 @@ loop:
24 return errors.Wrapf(err, "error advancing tar stream")
25 }
26
27- hdr.Name = filepath.Clean(hdr.Name)
28- if !strings.HasSuffix(hdr.Name, string(os.PathSeparator)) {
29- // Not the root directory, ensure that the parent directory exists
30- parent := filepath.Dir(hdr.Name)
31- parentPath := filepath.Join(dest, parent)
32- if _, err2 := os.Lstat(parentPath); err2 != nil && os.IsNotExist(err2) {
33- if err3 := os.MkdirAll(parentPath, 0755); err3 != nil {
34- return err3
35- }
36- }
37- }
38- path := filepath.Join(dest, hdr.Name)
39- if entries[path] {
40- return fmt.Errorf("duplicate entry for %s", path)
41- }
42- entries[path] = true
43- rel, err := filepath.Rel(dest, path)
44+ var whiteout bool
45+ whiteout, err = unpackLayerEntry(dest, hdr, tr, &entries)
46 if err != nil {
47 return err
48 }
49- info := hdr.FileInfo()
50- if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
51- return fmt.Errorf("%q is outside of %q", hdr.Name, dest)
52+ if whiteout {
53+ continue loop
54 }
55
56- if strings.HasPrefix(info.Name(), ".wh.") {
57- path = strings.Replace(path, ".wh.", "", 1)
58+ // Directory mtimes must be handled at the end to avoid further
59+ // file creation in them to modify the directory mtime
60+ if hdr.Typeflag == tar.TypeDir {
61+ dirs = append(dirs, hdr)
62+ }
63+ }
64+ for _, hdr := range dirs {
65+ path := filepath.Join(dest, hdr.Name)
66
67- if err := os.RemoveAll(path); err != nil {
68- return errors.Wrap(err, "unable to delete whiteout path")
69+ finfo := hdr.FileInfo()
70+ // I believe the old version was using time.Now().UTC() to overcome an
71+ // invalid error from chtimes.....but here we lose hdr.AccessTime like this...
72+ if err := os.Chtimes(path, time.Now().UTC(), finfo.ModTime()); err != nil {
73+ return errors.Wrap(err, "error changing time")
74+ }
75+ }
76+ return nil
77+}
78+
79+// unpackLayerEntry unpacks a single entry from a layer.
80+func unpackLayerEntry(dest string, header *tar.Header, reader io.Reader, entries *map[string]bool) (whiteout bool, err error) {
81+ header.Name = filepath.Clean(header.Name)
82+ if !strings.HasSuffix(header.Name, string(os.PathSeparator)) {
83+ // Not the root directory, ensure that the parent directory exists
84+ parent := filepath.Dir(header.Name)
85+ parentPath := filepath.Join(dest, parent)
86+ if _, err2 := os.Lstat(parentPath); err2 != nil && os.IsNotExist(err2) {
87+ if err3 := os.MkdirAll(parentPath, 0755); err3 != nil {
88+ return false, err3
89 }
90+ }
91+ }
92+ path := filepath.Join(dest, header.Name)
93+ if (*entries)[path] {
94+ return false, fmt.Errorf("duplicate entry for %s", path)
95+ }
96+ (*entries)[path] = true
97+ rel, err := filepath.Rel(dest, path)
98+ if err != nil {
99+ return false, err
100+ }
101+ info := header.FileInfo()
102+ if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
103+ return false, fmt.Errorf("%q is outside of %q", header.Name, dest)
104+ }
105
106- continue loop
107+ if strings.HasPrefix(info.Name(), ".wh.") {
108+ path = strings.Replace(path, ".wh.", "", 1)
109+
110+ if err = os.RemoveAll(path); err != nil {
111+ return true, errors.Wrap(err, "unable to delete whiteout path")
112 }
113
114- if hdr.Typeflag != tar.TypeDir {
115- err = os.RemoveAll(path)
116- if err != nil && !os.IsNotExist(err) {
117- return err
118- }
119+ return true, nil
120+ }
121+
122+ if header.Typeflag != tar.TypeDir {
123+ err = os.RemoveAll(path)
124+ if err != nil && !os.IsNotExist(err) {
125+ return false, err
126 }
127+ }
128
129- switch hdr.Typeflag {
130- case tar.TypeDir:
131- fi, err := os.Lstat(path)
132+ switch header.Typeflag {
133+ case tar.TypeDir:
134+ fi, err := os.Lstat(path)
135+ if err != nil && !os.IsNotExist(err) {
136+ return false, err
137+ }
138+ if os.IsNotExist(err) || !fi.IsDir() {
139+ err = os.RemoveAll(path)
140 if err != nil && !os.IsNotExist(err) {
141- return err
142- }
143- if os.IsNotExist(err) || !fi.IsDir() {
144- err = os.RemoveAll(path)
145- if err != nil && !os.IsNotExist(err) {
146- return err
147- }
148- err = os.MkdirAll(path, info.Mode())
149- if err != nil {
150- return err
151- }
152+ return false, err
153 }
154-
155- case tar.TypeReg, tar.TypeRegA:
156- f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, info.Mode())
157+ err = os.MkdirAll(path, info.Mode())
158 if err != nil {
159- return errors.Wrap(err, "unable to open file")
160+ return false, err
161 }
162+ }
163
164- if _, err := io.Copy(f, tr); err != nil {
165- f.Close()
166- return errors.Wrap(err, "unable to copy")
167- }
168- f.Close()
169+ case tar.TypeReg, tar.TypeRegA:
170+ f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, info.Mode())
171+ if err != nil {
172+ return false, errors.Wrap(err, "unable to open file")
173+ }
174
175- case tar.TypeLink:
176- target := filepath.Join(dest, hdr.Linkname)
177+ if _, err := io.Copy(f, reader); err != nil {
178+ f.Close()
179+ return false, errors.Wrap(err, "unable to copy")
180+ }
181+ f.Close()
182
183- if !strings.HasPrefix(target, dest) {
184- return fmt.Errorf("invalid hardlink %q -> %q", target, hdr.Linkname)
185- }
186+ case tar.TypeLink:
187+ target := filepath.Join(dest, header.Linkname)
188
189- if err := os.Link(target, path); err != nil {
190- return err
191- }
192+ if !strings.HasPrefix(target, dest) {
193+ return false, fmt.Errorf("invalid hardlink %q -> %q", target, header.Linkname)
194+ }
195
196- case tar.TypeSymlink:
197- target := filepath.Join(filepath.Dir(path), hdr.Linkname)
198+ if err := os.Link(target, path); err != nil {
199+ return false, err
200+ }
201
202- if !strings.HasPrefix(target, dest) {
203- return fmt.Errorf("invalid symlink %q -> %q", path, hdr.Linkname)
204- }
205+ case tar.TypeSymlink:
206+ target := filepath.Join(filepath.Dir(path), header.Linkname)
207
208- if err := os.Symlink(hdr.Linkname, path); err != nil {
209- return err
210- }
211- case tar.TypeXGlobalHeader:
212- return nil
213+ if !strings.HasPrefix(target, dest) {
214+ return false, fmt.Errorf("invalid symlink %q -> %q", path, header.Linkname)
215 }
216- // Directory mtimes must be handled at the end to avoid further
217- // file creation in them to modify the directory mtime
218- if hdr.Typeflag == tar.TypeDir {
219- dirs = append(dirs, hdr)
220- }
221- }
222- for _, hdr := range dirs {
223- path := filepath.Join(dest, hdr.Name)
224
225- finfo := hdr.FileInfo()
226- // I believe the old version was using time.Now().UTC() to overcome an
227- // invalid error from chtimes.....but here we lose hdr.AccessTime like this...
228- if err := os.Chtimes(path, time.Now().UTC(), finfo.ModTime()); err != nil {
229- return errors.Wrap(err, "error changing time")
230+ if err := os.Symlink(header.Linkname, path); err != nil {
231+ return false, err
232 }
233+ case tar.TypeXGlobalHeader:
234+ return false, nil
235 }
236- return nil
237+
238+ return false, nil
239 }
240--
2412.4.0.53.g8440f74
242