Skip to content

Commit 29dcda5

Browse files
committed
cmd/oci-image-tool: fix unpacking...
Signed-off-by: Antonio Murdaca <[email protected]>
1 parent 6541392 commit 29dcda5

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

image/manifest.go

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
"os"
2626
"path/filepath"
2727
"strings"
28-
"time"
2928

3029
"github.com/opencontainers/image-spec/schema"
3130
"github.com/pkg/errors"
@@ -107,7 +106,7 @@ func (m *manifest) unpack(w walker, dest string) error {
107106
}
108107

109108
dd, err := filepath.Rel("blobs", filepath.Clean(path))
110-
if err != nil || d.Digest != dd {
109+
if err != nil || d.getDigest() != dd {
111110
return nil // ignore
112111
}
113112

@@ -134,6 +133,7 @@ func unpackLayer(dest string, r io.Reader) error {
134133
}
135134
defer gz.Close()
136135

136+
var dirs []*tar.Header
137137
tr := tar.NewReader(gz)
138138

139139
loop:
@@ -148,7 +148,22 @@ loop:
148148
return errors.Wrapf(err, "error advancing tar stream")
149149
}
150150

151-
path := filepath.Join(dest, filepath.Clean(hdr.Name))
151+
hdr.Name = filepath.Clean(hdr.Name)
152+
// After calling filepath.Clean(hdr.Name) above, hdr.Name will now be in
153+
// the filepath format for the OS on which the daemon is running. Hence
154+
// the check for a slash-suffix MUST be done in an OS-agnostic way.
155+
if !strings.HasSuffix(hdr.Name, string(os.PathSeparator)) {
156+
// Not the root directory, ensure that the parent directory exists
157+
parent := filepath.Dir(hdr.Name)
158+
parentPath := filepath.Join(dest, parent)
159+
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
160+
err = os.MkdirAll(parentPath, 0777)
161+
if err != nil {
162+
return err
163+
}
164+
}
165+
}
166+
path := filepath.Join(dest, hdr.Name)
152167
info := hdr.FileInfo()
153168

154169
if strings.HasPrefix(info.Name(), ".wh.") {
@@ -163,8 +178,10 @@ loop:
163178

164179
switch hdr.Typeflag {
165180
case tar.TypeDir:
166-
if err := os.MkdirAll(path, info.Mode()); err != nil {
167-
return errors.Wrap(err, "error creating directory")
181+
if fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) {
182+
if err := os.MkdirAll(path, info.Mode()); err != nil {
183+
return errors.Wrap(err, "error creating directory")
184+
}
168185
}
169186

170187
case tar.TypeReg, tar.TypeRegA:
@@ -200,13 +217,19 @@ loop:
200217
if err := os.Symlink(hdr.Linkname, path); err != nil {
201218
return err
202219
}
203-
204220
}
221+
// Directory mtimes must be handled at the end to avoid further
222+
// file creation in them to modify the directory mtime
223+
if hdr.Typeflag == tar.TypeDir {
224+
dirs = append(dirs, hdr)
225+
}
226+
}
227+
for _, hdr := range dirs {
228+
path := filepath.Join(dest, hdr.Name)
205229

206-
if err := os.Chtimes(path, time.Now().UTC(), info.ModTime()); err != nil {
230+
if err := os.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil {
207231
return errors.Wrap(err, "error changing time")
208232
}
209233
}
210-
211234
return nil
212235
}

0 commit comments

Comments
 (0)