Skip to content

Commit

Permalink
cmd/oci-image-tool: fix unpacking...
Browse files Browse the repository at this point in the history
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
  • Loading branch information
runcom committed Jul 22, 2016
1 parent 6541392 commit 5c9fb98
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 15 deletions.
6 changes: 4 additions & 2 deletions image/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type config struct {

func findConfig(w walker, d *descriptor) (*config, error) {
var c config
cpath := filepath.Join("blobs", d.getDigest())
cpath := filepath.Join("blobs", d.normalizeDigest())

f := func(path string, info os.FileInfo, r io.Reader) error {
if info.IsDir() {
Expand Down Expand Up @@ -97,13 +97,15 @@ func (c *config) runtimeSpec(rootfs string) (*specs.Spec, error) {

var s specs.Spec
s.Version = "0.5.0"
// we should at least apply the default spec, otherwise this is totally useless
s.Process.Terminal = true
s.Root.Path = rootfs
s.Process.Cwd = "/"
if c.Config.WorkingDir != "" {
s.Process.Cwd = c.Config.WorkingDir
}
s.Process.Env = append(s.Process.Env, c.Config.Env...)
s.Process.Args = append(s.Process.Env, c.Config.Entrypoint...)
s.Process.Args = append(s.Process.Args, c.Config.Entrypoint...)
s.Process.Args = append(s.Process.Args, c.Config.Cmd...)

if len(s.Process.Args) == 0 {
Expand Down
8 changes: 4 additions & 4 deletions image/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type descriptor struct {
Size int64 `json:"size"`
}

func (d *descriptor) getDigest() string {
func (d *descriptor) normalizeDigest() string {
return strings.Replace(d.Digest, ":", "-", -1)
}

Expand Down Expand Up @@ -76,7 +76,7 @@ func (d *descriptor) validate(w walker) error {
}

digest, err := filepath.Rel("blobs", filepath.Clean(path))
if err != nil || d.getDigest() != digest {
if err != nil || d.normalizeDigest() != digest {
return nil // ignore
}

Expand All @@ -89,11 +89,11 @@ func (d *descriptor) validate(w walker) error {

switch err := w.walk(f); err {
case nil:
return fmt.Errorf("%s: not found", d.getDigest())
return fmt.Errorf("%s: not found", d.normalizeDigest())
case errEOW:
// found, continue below
default:
return errors.Wrapf(err, "%s: validation failed", d.getDigest())
return errors.Wrapf(err, "%s: validation failed", d.normalizeDigest())
}

return nil
Expand Down
51 changes: 42 additions & 9 deletions image/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type manifest struct {

func findManifest(w walker, d *descriptor) (*manifest, error) {
var m manifest
mpath := filepath.Join("blobs", d.getDigest())
mpath := filepath.Join("blobs", d.normalizeDigest())

f := func(path string, info os.FileInfo, r io.Reader) error {
if info.IsDir() {
Expand Down Expand Up @@ -107,7 +107,7 @@ func (m *manifest) unpack(w walker, dest string) error {
}

dd, err := filepath.Rel("blobs", filepath.Clean(path))
if err != nil || d.Digest != dd {
if err != nil || d.normalizeDigest() != dd {
return nil // ignore
}

Expand All @@ -134,6 +134,7 @@ func unpackLayer(dest string, r io.Reader) error {
}
defer gz.Close()

var dirs []*tar.Header
tr := tar.NewReader(gz)

loop:
Expand All @@ -148,8 +149,27 @@ loop:
return errors.Wrapf(err, "error advancing tar stream")
}

path := filepath.Join(dest, filepath.Clean(hdr.Name))
hdr.Name = filepath.Clean(hdr.Name)
if !strings.HasSuffix(hdr.Name, string(os.PathSeparator)) {
// Not the root directory, ensure that the parent directory exists
parent := filepath.Dir(hdr.Name)
parentPath := filepath.Join(dest, parent)
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
err = os.MkdirAll(parentPath, 0777)
if err != nil {
return err
}
}
}
path := filepath.Join(dest, hdr.Name)
rel, err := filepath.Rel(dest, path)
if err != nil {
return err
}
info := hdr.FileInfo()
if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
return fmt.Errorf("%q is outside of %q", hdr.Name, dest)
}

if strings.HasPrefix(info.Name(), ".wh.") {
path = strings.Replace(path, ".wh.", "", 1)
Expand All @@ -163,12 +183,14 @@ loop:

switch hdr.Typeflag {
case tar.TypeDir:
if err := os.MkdirAll(path, info.Mode()); err != nil {
return errors.Wrap(err, "error creating directory")
if fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) {
if err2 := os.MkdirAll(path, info.Mode()); err2 != nil {
return errors.Wrap(err2, "error creating directory")
}
}

case tar.TypeReg, tar.TypeRegA:
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, info.Mode())
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, info.Mode())
if err != nil {
return errors.Wrap(err, "unable to open file")
}
Expand Down Expand Up @@ -200,13 +222,24 @@ loop:
if err := os.Symlink(hdr.Linkname, path); err != nil {
return err
}

case tar.TypeXGlobalHeader:
return nil
}
// Directory mtimes must be handled at the end to avoid further
// file creation in them to modify the directory mtime
if hdr.Typeflag == tar.TypeDir {
dirs = append(dirs, hdr)
}
}
for _, hdr := range dirs {
path := filepath.Join(dest, hdr.Name)

if err := os.Chtimes(path, time.Now().UTC(), info.ModTime()); err != nil {
finfo := hdr.FileInfo()
// I believe the old version was using time.Now().UTC() to overcome an
// invalid error from chtimes.....but here we lose hdr.AccessTime like this...
if err := os.Chtimes(path, time.Now().UTC(), finfo.ModTime()); err != nil {
return errors.Wrap(err, "error changing time")
}
}

return nil
}

0 comments on commit 5c9fb98

Please sign in to comment.