diff options
Diffstat (limited to 'vendor/github.com/projectatomic/buildah/add.go')
-rw-r--r-- | vendor/github.com/projectatomic/buildah/add.go | 79 |
1 files changed, 25 insertions, 54 deletions
diff --git a/vendor/github.com/projectatomic/buildah/add.go b/vendor/github.com/projectatomic/buildah/add.go index 4fab5a8d7..ee2cf253a 100644 --- a/vendor/github.com/projectatomic/buildah/add.go +++ b/vendor/github.com/projectatomic/buildah/add.go @@ -12,6 +12,7 @@ import ( "time" "github.com/containers/storage/pkg/archive" + "github.com/containers/storage/pkg/idtools" "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/projectatomic/libpod/pkg/chrootuser" @@ -26,7 +27,7 @@ type AddAndCopyOptions struct { // addURL copies the contents of the source URL to the destination. This is // its own function so that deferred closes happen after we're done pulling // down each item of potentially many. -func addURL(destination, srcurl string) error { +func addURL(destination, srcurl string, owner idtools.IDPair) error { logrus.Debugf("saving %q to %q", srcurl, destination) resp, err := http.Get(srcurl) if err != nil { @@ -37,6 +38,9 @@ func addURL(destination, srcurl string) error { if err != nil { return errors.Wrapf(err, "error creating %q", destination) } + if err = f.Chown(owner.UID, owner.GID); err != nil { + return errors.Wrapf(err, "error setting owner of %q", destination) + } if last := resp.Header.Get("Last-Modified"); last != "" { if mtime, err2 := time.Parse(time.RFC1123, last); err2 != nil { logrus.Debugf("error parsing Last-Modified time %q: %v", last, err2) @@ -80,11 +84,17 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption if err != nil { return err } + containerOwner := idtools.IDPair{UID: int(user.UID), GID: int(user.GID)} + hostUID, hostGID, err := getHostIDs(b.IDMappingOptions.UIDMap, b.IDMappingOptions.GIDMap, user.UID, user.GID) + if err != nil { + return err + } + hostOwner := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)} dest := mountPoint if destination != "" && filepath.IsAbs(destination) { dest = filepath.Join(dest, destination) } else { - if err = ensureDir(filepath.Join(dest, b.WorkDir()), user, 0755); err != nil { + if err = idtools.MkdirAllAndChownNew(filepath.Join(dest, b.WorkDir()), 0755, hostOwner); err != nil { return err } dest = filepath.Join(dest, b.WorkDir(), destination) @@ -93,7 +103,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption // with a '/', create it so that we can be sure that it's a directory, // and any files we're copying will be placed in the directory. if len(destination) > 0 && destination[len(destination)-1] == os.PathSeparator { - if err = ensureDir(dest, user, 0755); err != nil { + if err = idtools.MkdirAllAndChownNew(dest, 0755, hostOwner); err != nil { return err } } @@ -112,6 +122,9 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption if len(source) > 1 && (destfi == nil || !destfi.IsDir()) { return errors.Errorf("destination %q is not a directory", dest) } + copyFileWithTar := b.copyFileWithTar(&containerOwner) + copyWithTar := b.copyWithTar(&containerOwner) + untarPath := b.untarPath(nil) for _, src := range source { if strings.HasPrefix(src, "http://") || strings.HasPrefix(src, "https://") { // We assume that source is a file, and we're copying @@ -127,10 +140,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption if destfi != nil && destfi.IsDir() { d = filepath.Join(dest, path.Base(url.Path)) } - if err := addURL(d, src); err != nil { - return err - } - if err := setOwner("", d, user); err != nil { + if err := addURL(d, src, hostOwner); err != nil { return err } continue @@ -153,16 +163,13 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption // the source directory into the target directory. Try // to create it first, so that if there's a problem, // we'll discover why that won't work. - if err = ensureDir(dest, user, 0755); err != nil { + if err = idtools.MkdirAllAndChownNew(dest, 0755, hostOwner); err != nil { return err } logrus.Debugf("copying %q to %q", gsrc+string(os.PathSeparator)+"*", dest+string(os.PathSeparator)+"*") if err := copyWithTar(gsrc, dest); err != nil { return errors.Wrapf(err, "error copying %q to %q", gsrc, dest) } - if err := setOwner(gsrc, dest, user); err != nil { - return err - } continue } if !extract || !archive.IsArchivePath(gsrc) { @@ -178,9 +185,6 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption if err := copyFileWithTar(gsrc, d); err != nil { return errors.Wrapf(err, "error copying %q to %q", gsrc, d) } - if err := setOwner(gsrc, d, user); err != nil { - return err - } continue } // We're extracting an archive into the destination directory. @@ -205,49 +209,16 @@ func (b *Builder) user(mountPoint string, userspec string) (specs.User, error) { GID: gid, Username: userspec, } - return u, err -} - -// setOwner sets the uid and gid owners of a given path. -func setOwner(src, dest string, user specs.User) error { - fid, err := os.Stat(dest) - if err != nil { - return errors.Wrapf(err, "error reading %q", dest) - } - if !fid.IsDir() || src == "" { - if err := os.Lchown(dest, int(user.UID), int(user.GID)); err != nil { - return errors.Wrapf(err, "error setting ownership of %q", dest) - } - return nil - } - err = filepath.Walk(src, func(p string, info os.FileInfo, we error) error { - relPath, err2 := filepath.Rel(src, p) + if !strings.Contains(userspec, ":") { + groups, err2 := chrootuser.GetAdditionalGroupsForUser(mountPoint, uint64(u.UID)) if err2 != nil { - return errors.Wrapf(err2, "error getting relative path of %q to set ownership on destination", p) - } - if relPath != "." { - absPath := filepath.Join(dest, relPath) - if err2 := os.Lchown(absPath, int(user.UID), int(user.GID)); err != nil { - return errors.Wrapf(err2, "error setting ownership of %q", absPath) + if errors.Cause(err2) != chrootuser.ErrNoSuchUser && err == nil { + err = err2 } + } else { + u.AdditionalGids = groups } - return nil - }) - if err != nil { - return errors.Wrapf(err, "error walking dir %q to set ownership", src) - } - return nil -} -// ensureDir creates a directory if it doesn't exist, setting ownership and permissions as passed by user and perm. -func ensureDir(path string, user specs.User, perm os.FileMode) error { - if _, err := os.Stat(path); os.IsNotExist(err) { - if err := os.MkdirAll(path, perm); err != nil { - return errors.Wrapf(err, "error ensuring directory %q exists", path) - } - if err := os.Chown(path, int(user.UID), int(user.GID)); err != nil { - return errors.Wrapf(err, "error setting ownership of %q", path) - } } - return nil + return u, err } |