From 14ec550ec34e8e5914adf4ae9d1723e8a404bd38 Mon Sep 17 00:00:00 2001 From: TomSweeneyRedHat Date: Tue, 4 Jun 2019 12:58:16 -0400 Subject: Vendor Buildah v1.8.3 Vendor in Buildah v1.8.3 Signed-off-by: TomSweeneyRedHat --- vendor/github.com/containers/buildah/add.go | 163 ++++++++------------- vendor/github.com/containers/buildah/buildah.go | 2 +- vendor/github.com/containers/buildah/chroot/run.go | 13 +- vendor/github.com/containers/buildah/config.go | 11 -- .../containers/buildah/imagebuildah/build.go | 35 +++-- .../containers/buildah/imagebuildah/util.go | 4 +- .../containers/buildah/pkg/chrootuser/user.go | 16 +- .../buildah/pkg/chrootuser/user_basic.go | 4 + .../buildah/pkg/chrootuser/user_linux.go | 28 ++++ .../containers/buildah/pkg/secrets/secrets.go | 76 ++++++---- .../containers/buildah/pkg/unshare/unshare.go | 29 +++- vendor/github.com/containers/buildah/run_linux.go | 28 +++- 12 files changed, 235 insertions(+), 174 deletions(-) (limited to 'vendor') diff --git a/vendor/github.com/containers/buildah/add.go b/vendor/github.com/containers/buildah/add.go index 589e090a8..11bfb6a12 100644 --- a/vendor/github.com/containers/buildah/add.go +++ b/vendor/github.com/containers/buildah/add.go @@ -14,6 +14,7 @@ import ( "github.com/containers/buildah/pkg/chrootuser" "github.com/containers/buildah/util" "github.com/containers/storage/pkg/archive" + "github.com/containers/storage/pkg/fileutils" "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/system" "github.com/opencontainers/runtime-spec/specs-go" @@ -89,7 +90,10 @@ func addURL(destination, srcurl string, owner idtools.IDPair, hasher io.Writer) // filesystem, optionally extracting contents of local files that look like // non-empty archives. func (b *Builder) Add(destination string, extract bool, options AddAndCopyOptions, source ...string) error { - excludes := dockerIgnoreHelper(options.Excludes, options.ContextDir) + excludes, err := dockerIgnoreMatcher(options.Excludes, options.ContextDir) + if err != nil { + return err + } mountPoint, err := b.Mount(b.MountLabel) if err != nil { return err @@ -100,7 +104,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption } }() // Find out which user (and group) the destination should belong to. - user, err := b.user(mountPoint, options.Chown) + user, _, err := b.user(mountPoint, options.Chown) if err != nil { return err } @@ -153,12 +157,12 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption } // user returns the user (and group) information which the destination should belong to. -func (b *Builder) user(mountPoint string, userspec string) (specs.User, error) { +func (b *Builder) user(mountPoint string, userspec string) (specs.User, string, error) { if userspec == "" { userspec = b.User() } - uid, gid, err := chrootuser.GetUser(mountPoint, userspec) + uid, gid, homeDir, err := chrootuser.GetUser(mountPoint, userspec) u := specs.User{ UID: uid, GID: gid, @@ -175,45 +179,48 @@ func (b *Builder) user(mountPoint string, userspec string) (specs.User, error) { } } - return u, err + return u, homeDir, err } -// dockerIgnore struct keep info from .dockerignore -type dockerIgnore struct { - ExcludePath string - IsExcluded bool -} - -// dockerIgnoreHelper returns the lines from .dockerignore file without the comments -// and reverses the order -func dockerIgnoreHelper(lines []string, contextDir string) []dockerIgnore { - var excludes []dockerIgnore - // the last match of a file in the .dockerignmatches determines whether it is included or excluded - // reverse the order - for i := len(lines) - 1; i >= 0; i-- { - exclude := lines[i] - // ignore the comment in .dockerignore - if strings.HasPrefix(exclude, "#") || len(exclude) == 0 { +// dockerIgnoreMatcher returns a matcher based on the contents of the .dockerignore file under contextDir +func dockerIgnoreMatcher(lines []string, contextDir string) (*fileutils.PatternMatcher, error) { + // if there's no context dir, there's no .dockerignore file to consult + if contextDir == "" { + return nil, nil + } + patterns := []string{".dockerignore"} + for _, ignoreSpec := range lines { + ignoreSpec = strings.TrimSpace(ignoreSpec) + // ignore comments passed back from .dockerignore + if ignoreSpec == "" || ignoreSpec[0] == '#' { continue } - excludeFlag := true - if strings.HasPrefix(exclude, "!") { - exclude = strings.TrimPrefix(exclude, "!") - excludeFlag = false + // if the spec starts with '!' it means the pattern + // should be included. make a note so that we can move + // it to the front of the updated pattern + includeFlag := "" + if strings.HasPrefix(ignoreSpec, "!") { + includeFlag = "!" + ignoreSpec = ignoreSpec[1:] } - excludes = append(excludes, dockerIgnore{ExcludePath: filepath.Join(contextDir, exclude), IsExcluded: excludeFlag}) + if ignoreSpec == "" { + continue + } + patterns = append(patterns, includeFlag+filepath.Join(contextDir, ignoreSpec)) } - if len(excludes) != 0 { - excludes = append(excludes, dockerIgnore{ExcludePath: filepath.Join(contextDir, ".dockerignore"), IsExcluded: true}) + // if there are no patterns, save time by not constructing the object + if len(patterns) == 0 { + return nil, nil } - return excludes -} - -func addHelper(excludes []dockerIgnore, extract bool, dest string, destfi os.FileInfo, hostOwner idtools.IDPair, options AddAndCopyOptions, copyFileWithTar, copyWithTar, untarPath func(src, dest string) error, source ...string) error { - dirsInDockerignore, err := getDirsInDockerignore(options.ContextDir, excludes) + // return a matcher object + matcher, err := fileutils.NewPatternMatcher(patterns) if err != nil { - return errors.Wrapf(err, "error checking directories in .dockerignore") + return nil, errors.Wrapf(err, "error creating file matcher using patterns %v", patterns) } + return matcher, nil +} + +func addHelper(excludes *fileutils.PatternMatcher, extract bool, dest string, destfi os.FileInfo, hostOwner idtools.IDPair, options AddAndCopyOptions, copyFileWithTar, copyWithTar, untarPath func(src, dest string) error, source ...string) error { for _, src := range source { if strings.HasPrefix(src, "http://") || strings.HasPrefix(src, "https://") { // We assume that source is a file, and we're copying @@ -242,7 +249,7 @@ func addHelper(excludes []dockerIgnore, extract bool, dest string, destfi os.Fil if len(glob) == 0 { return errors.Wrapf(syscall.ENOENT, "no files found matching %q", src) } - outer: + for _, gsrc := range glob { esrc, err := filepath.EvalSymlinks(gsrc) if err != nil { @@ -261,7 +268,7 @@ func addHelper(excludes []dockerIgnore, extract bool, dest string, destfi os.Fil return errors.Wrapf(err, "error creating directory %q", dest) } logrus.Debugf("copying %q to %q", esrc+string(os.PathSeparator)+"*", dest+string(os.PathSeparator)+"*") - if len(excludes) == 0 { + if excludes == nil { if err = copyWithTar(esrc, dest); err != nil { return errors.Wrapf(err, "error copying %q to %q", esrc, dest) } @@ -271,23 +278,12 @@ func addHelper(excludes []dockerIgnore, extract bool, dest string, destfi os.Fil if err != nil { return err } - for _, exclude := range excludes { - match, err := filepath.Match(filepath.Clean(exclude.ExcludePath), filepath.Clean(path)) - if err != nil { - return err - } - prefix, exist := dirsInDockerignore[exclude.ExcludePath] - hasPrefix := false - if exist { - hasPrefix = filepath.HasPrefix(path, prefix) - } - if !(match || hasPrefix) { - continue - } - if (hasPrefix && exclude.IsExcluded) || (match && exclude.IsExcluded) { - return nil - } - break + skip, err := excludes.Matches(path) + if err != nil { + return errors.Wrapf(err, "error checking if %s is an excluded path", path) + } + if skip { + return nil } // combine the filename with the dest directory fpath, err := filepath.Rel(esrc, path) @@ -297,8 +293,8 @@ func addHelper(excludes []dockerIgnore, extract bool, dest string, destfi os.Fil mtime := info.ModTime() atime := mtime times := []syscall.Timespec{ - {Sec: atime.Unix(), Nsec: atime.UnixNano() % 1000000000}, - {Sec: mtime.Unix(), Nsec: mtime.UnixNano() % 1000000000}, + syscall.NsecToTimespec(atime.Unix()), + syscall.NsecToTimespec(mtime.Unix()), } if info.IsDir() { return addHelperDirectory(esrc, path, filepath.Join(dest, fpath), info, hostOwner, times) @@ -320,20 +316,6 @@ func addHelper(excludes []dockerIgnore, extract bool, dest string, destfi os.Fil continue } - for _, exclude := range excludes { - match, err := filepath.Match(filepath.Clean(exclude.ExcludePath), esrc) - if err != nil { - return err - } - if !match { - continue - } - if exclude.IsExcluded { - continue outer - } - break - } - if !extract || !archive.IsArchivePath(esrc) { // This source is a file, and either it's not an // archive, or we don't care whether or not it's an @@ -349,6 +331,7 @@ func addHelper(excludes []dockerIgnore, extract bool, dest string, destfi os.Fil } continue } + // We're extracting an archive into the destination directory. logrus.Debugf("extracting contents of %q into %q", esrc, dest) if err = untarPath(esrc, dest); err != nil { @@ -381,7 +364,15 @@ func addHelperSymlink(src, dest string, info os.FileInfo, hostOwner idtools.IDPa return errors.Wrapf(err, "error reading contents of symbolic link at %q", src) } if err = os.Symlink(linkContents, dest); err != nil { - return errors.Wrapf(err, "error creating symbolic link to %q at %q", linkContents, dest) + if !os.IsExist(err) { + return errors.Wrapf(err, "error creating symbolic link to %q at %q", linkContents, dest) + } + if err = os.RemoveAll(dest); err != nil { + return errors.Wrapf(err, "error clearing symbolic link target %q", dest) + } + if err = os.Symlink(linkContents, dest); err != nil { + return errors.Wrapf(err, "error creating symbolic link to %q at %q (second try)", linkContents, dest) + } } if err = idtools.SafeLchown(dest, hostOwner.UID, hostOwner.GID); err != nil { return errors.Wrapf(err, "error setting owner of symbolic link %q to %d:%d", dest, hostOwner.UID, hostOwner.GID) @@ -392,35 +383,3 @@ func addHelperSymlink(src, dest string, info os.FileInfo, hostOwner idtools.IDPa logrus.Debugf("Symlink(%s, %s)", linkContents, dest) return nil } - -func getDirsInDockerignore(srcAbsPath string, excludes []dockerIgnore) (map[string]string, error) { - visitedDir := make(map[string]string) - if len(excludes) == 0 { - return visitedDir, nil - } - err := filepath.Walk(srcAbsPath, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - for _, exclude := range excludes { - match, err := filepath.Match(filepath.Clean(exclude.ExcludePath), filepath.Clean(path)) - if err != nil { - return err - } - if !match { - continue - } - if _, exist := visitedDir[exclude.ExcludePath]; exist { - continue - } - visitedDir[exclude.ExcludePath] = path - } - } - return nil - }) - if err != nil { - return visitedDir, err - } - return visitedDir, nil -} diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go index 33b7afccd..56c8f088f 100644 --- a/vendor/github.com/containers/buildah/buildah.go +++ b/vendor/github.com/containers/buildah/buildah.go @@ -26,7 +26,7 @@ const ( Package = "buildah" // Version for the Package. Bump version in contrib/rpm/buildah.spec // too. - Version = "1.9.0-dev" + Version = "1.8.3" // The value we use to identify what type of information, currently a // serialized Builder structure, we are using as per-container state. // This should only be changed when we make incompatible changes to diff --git a/vendor/github.com/containers/buildah/chroot/run.go b/vendor/github.com/containers/buildah/chroot/run.go index c65926c8e..d6e5a61ea 100644 --- a/vendor/github.com/containers/buildah/chroot/run.go +++ b/vendor/github.com/containers/buildah/chroot/run.go @@ -84,9 +84,18 @@ type runUsingChrootExecSubprocOptions struct { // RunUsingChroot runs a chrooted process, using some of the settings from the // passed-in spec, and using the specified bundlePath to hold temporary files, // directories, and mountpoints. -func RunUsingChroot(spec *specs.Spec, bundlePath string, stdin io.Reader, stdout, stderr io.Writer) (err error) { +func RunUsingChroot(spec *specs.Spec, bundlePath, homeDir string, stdin io.Reader, stdout, stderr io.Writer) (err error) { var confwg sync.WaitGroup - + var homeFound bool + for _, env := range spec.Process.Env { + if strings.HasPrefix(env, "HOME=") { + homeFound = true + break + } + } + if !homeFound { + spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("HOME=%s", homeDir)) + } runtime.LockOSThread() defer runtime.UnlockOSThread() diff --git a/vendor/github.com/containers/buildah/config.go b/vendor/github.com/containers/buildah/config.go index 05b0abb23..234f93259 100644 --- a/vendor/github.com/containers/buildah/config.go +++ b/vendor/github.com/containers/buildah/config.go @@ -3,7 +3,6 @@ package buildah import ( "context" "encoding/json" - "os" "runtime" "strings" "time" @@ -269,21 +268,11 @@ func (b *Builder) Env() []string { // built using an image built from this container. func (b *Builder) SetEnv(k string, v string) { reset := func(s *[]string) { - getenv := func(name string) string { - for i := range *s { - val := strings.SplitN((*s)[i], "=", 2) - if len(val) == 2 && val[0] == name { - return val[1] - } - } - return name - } n := []string{} for i := range *s { if !strings.HasPrefix((*s)[i], k+"=") { n = append(n, (*s)[i]) } - v = os.Expand(v, getenv) } n = append(n, k+"="+v) *s = n diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go index b8b9db0f3..3665251cd 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/build.go +++ b/vendor/github.com/containers/buildah/imagebuildah/build.go @@ -487,6 +487,7 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err // Check the file and see if part of it is a symlink. // Convert it to the target if so. To be ultrasafe // do the same for the mountpoint. + hadFinalPathSeparator := len(copy.Dest) > 0 && copy.Dest[len(copy.Dest)-1] == os.PathSeparator secureMountPoint, err := securejoin.SecureJoin("", s.mountPoint) finalPath, err := securejoin.SecureJoin(secureMountPoint, copy.Dest) if err != nil { @@ -496,6 +497,11 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err return errors.Wrapf(err, "error resolving copy destination %s", copy.Dest) } copy.Dest = strings.TrimPrefix(finalPath, secureMountPoint) + if len(copy.Dest) == 0 || copy.Dest[len(copy.Dest)-1] != os.PathSeparator { + if hadFinalPathSeparator { + copy.Dest += string(os.PathSeparator) + } + } if copy.Download { logrus.Debugf("ADD %#v, %#v", excludes, copy) @@ -507,29 +513,32 @@ func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) err } sources := []string{} for _, src := range copy.Src { + contextDir := s.executor.contextDir + copyExcludes := excludes if strings.HasPrefix(src, "http://") || strings.HasPrefix(src, "https://") { sources = append(sources, src) } else if len(copy.From) > 0 { if other, ok := s.executor.stages[copy.From]; ok && other.index < s.index { sources = append(sources, filepath.Join(other.mountPoint, src)) + contextDir = other.mountPoint } else if builder, ok := s.executor.containerMap[copy.From]; ok { sources = append(sources, filepath.Join(builder.MountPoint, src)) + contextDir = builder.MountPoint } else { return errors.Errorf("the stage %q has not been built", copy.From) } } else { sources = append(sources, filepath.Join(s.executor.contextDir, src)) + copyExcludes = append(s.executor.excludes, excludes...) + } + options := buildah.AddAndCopyOptions{ + Chown: copy.Chown, + ContextDir: contextDir, + Excludes: copyExcludes, + } + if err := s.builder.Add(copy.Dest, copy.Download, options, sources...); err != nil { + return err } - } - - options := buildah.AddAndCopyOptions{ - Chown: copy.Chown, - ContextDir: s.executor.contextDir, - Excludes: s.executor.excludes, - } - - if err := s.builder.Add(copy.Dest, copy.Download, options, sources...); err != nil { - return err } } return nil @@ -590,7 +599,11 @@ func (s *StageExecutor) Run(run imagebuilder.Run, config docker.Config) error { args := run.Args if run.Shell { - args = append([]string{"/bin/sh", "-c"}, args...) + if len(config.Shell) > 0 && s.builder.Format == buildah.Dockerv2ImageManifest { + args = append(config.Shell, args...) + } else { + args = append([]string{"/bin/sh", "-c"}, args...) + } } if err := s.volumeCacheSave(); err != nil { return err diff --git a/vendor/github.com/containers/buildah/imagebuildah/util.go b/vendor/github.com/containers/buildah/imagebuildah/util.go index f982fcebf..3962d1a9d 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/util.go +++ b/vendor/github.com/containers/buildah/imagebuildah/util.go @@ -17,7 +17,7 @@ import ( ) func cloneToDirectory(url, dir string) error { - if !strings.HasPrefix(url, "git://") { + if !strings.HasPrefix(url, "git://") && !strings.HasSuffix(url, ".git") { url = "git://" + url } logrus.Debugf("cloning %q to %q", url, dir) @@ -72,7 +72,7 @@ func TempDirForURL(dir, prefix, url string) (name string, subdir string, err err if err != nil { return "", "", errors.Wrapf(err, "error creating temporary directory for %q", url) } - if strings.HasPrefix(url, "git://") { + if strings.HasPrefix(url, "git://") || strings.HasSuffix(url, ".git") { err = cloneToDirectory(url, name) if err != nil { if err2 := os.Remove(name); err2 != nil { diff --git a/vendor/github.com/containers/buildah/pkg/chrootuser/user.go b/vendor/github.com/containers/buildah/pkg/chrootuser/user.go index c83dcc230..26a67c35a 100644 --- a/vendor/github.com/containers/buildah/pkg/chrootuser/user.go +++ b/vendor/github.com/containers/buildah/pkg/chrootuser/user.go @@ -18,7 +18,7 @@ var ( // it will use the /etc/passwd and /etc/group files inside of the rootdir // to return this information. // userspec format [user | user:group | uid | uid:gid | user:gid | uid:group ] -func GetUser(rootdir, userspec string) (uint32, uint32, error) { +func GetUser(rootdir, userspec string) (uint32, uint32, string, error) { var gid64 uint64 var gerr error = user.UnknownGroupError("error looking up group") @@ -26,7 +26,7 @@ func GetUser(rootdir, userspec string) (uint32, uint32, error) { userspec = spec[0] groupspec := "" if userspec == "" { - return 0, 0, nil + return 0, 0, "/", nil } if len(spec) > 1 { groupspec = spec[1] @@ -65,15 +65,21 @@ func GetUser(rootdir, userspec string) (uint32, uint32, error) { } } + homedir, err := lookupHomedirInContainer(rootdir, uid64) + if err != nil { + homedir = "/" + } + if uerr == nil && gerr == nil { - return uint32(uid64), uint32(gid64), nil + return uint32(uid64), uint32(gid64), homedir, nil } - err := errors.Wrapf(uerr, "error determining run uid") + err = errors.Wrapf(uerr, "error determining run uid") if uerr == nil { err = errors.Wrapf(gerr, "error determining run gid") } - return 0, 0, err + + return 0, 0, homedir, err } // GetGroup returns the gid by looking it up in the /etc/group file diff --git a/vendor/github.com/containers/buildah/pkg/chrootuser/user_basic.go b/vendor/github.com/containers/buildah/pkg/chrootuser/user_basic.go index 79b0b24b5..6c997c4c9 100644 --- a/vendor/github.com/containers/buildah/pkg/chrootuser/user_basic.go +++ b/vendor/github.com/containers/buildah/pkg/chrootuser/user_basic.go @@ -25,3 +25,7 @@ func lookupAdditionalGroupsForUIDInContainer(rootdir string, userid uint64) (gid func lookupUIDInContainer(rootdir string, uid uint64) (string, uint64, error) { return "", 0, errors.New("UID lookup not supported") } + +func lookupHomedirInContainer(rootdir string, uid uint64) (string, error) { + return "", errors.New("Home directory lookup not supported") +} diff --git a/vendor/github.com/containers/buildah/pkg/chrootuser/user_linux.go b/vendor/github.com/containers/buildah/pkg/chrootuser/user_linux.go index 583eca569..ea20fca80 100644 --- a/vendor/github.com/containers/buildah/pkg/chrootuser/user_linux.go +++ b/vendor/github.com/containers/buildah/pkg/chrootuser/user_linux.go @@ -84,6 +84,7 @@ type lookupPasswdEntry struct { name string uid uint64 gid uint64 + home string } type lookupGroupEntry struct { name string @@ -135,6 +136,7 @@ func parseNextPasswd(rc *bufio.Reader) *lookupPasswdEntry { name: fields[0], uid: uid, gid: gid, + home: fields[5], } } @@ -291,3 +293,29 @@ func lookupUIDInContainer(rootdir string, uid uint64) (string, uint64, error) { return "", 0, user.UnknownUserError(fmt.Sprintf("error looking up uid %q", uid)) } + +func lookupHomedirInContainer(rootdir string, uid uint64) (string, error) { + cmd, f, err := openChrootedFile(rootdir, "/etc/passwd") + if err != nil { + return "", err + } + defer func() { + _ = cmd.Wait() + }() + rc := bufio.NewReader(f) + defer f.Close() + + lookupUser.Lock() + defer lookupUser.Unlock() + + pwd := parseNextPasswd(rc) + for pwd != nil { + if pwd.uid != uid { + pwd = parseNextPasswd(rc) + continue + } + return pwd.home, nil + } + + return "", user.UnknownUserError(fmt.Sprintf("error looking up uid %q for homedir", uid)) +} diff --git a/vendor/github.com/containers/buildah/pkg/secrets/secrets.go b/vendor/github.com/containers/buildah/pkg/secrets/secrets.go index 97b681125..70bd6a4b7 100644 --- a/vendor/github.com/containers/buildah/pkg/secrets/secrets.go +++ b/vendor/github.com/containers/buildah/pkg/secrets/secrets.go @@ -117,7 +117,12 @@ func getMounts(filePath string) []string { } var mounts []string for scanner.Scan() { - mounts = append(mounts, scanner.Text()) + if strings.HasPrefix(strings.TrimSpace(scanner.Text()), "/") { + mounts = append(mounts, scanner.Text()) + } else { + logrus.Debugf("skipping unrecognized mount in %v: %q", + filePath, scanner.Text()) + } } return mounts } @@ -190,58 +195,79 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir, mountPr var mounts []rspec.Mount defaultMountsPaths := getMounts(filePath) for _, path := range defaultMountsPaths { - hostDir, ctrDir, err := getMountsMap(path) + hostDirOrFile, ctrDirOrFile, err := getMountsMap(path) if err != nil { return nil, err } - // skip if the hostDir path doesn't exist - if _, err = os.Stat(hostDir); err != nil { + // skip if the hostDirOrFile path doesn't exist + fileInfo, err := os.Stat(hostDirOrFile) + if err != nil { if os.IsNotExist(err) { - logrus.Warnf("Path %q from %q doesn't exist, skipping", hostDir, filePath) + logrus.Warnf("Path %q from %q doesn't exist, skipping", hostDirOrFile, filePath) continue } - return nil, errors.Wrapf(err, "failed to stat %q", hostDir) + return nil, errors.Wrapf(err, "failed to stat %q", hostDirOrFile) } - ctrDirOnHost := filepath.Join(containerWorkingDir, ctrDir) + ctrDirOrFileOnHost := filepath.Join(containerWorkingDir, ctrDirOrFile) - // In the event of a restart, don't want to copy secrets over again as they already would exist in ctrDirOnHost - _, err = os.Stat(ctrDirOnHost) + // In the event of a restart, don't want to copy secrets over again as they already would exist in ctrDirOrFileOnHost + _, err = os.Stat(ctrDirOrFileOnHost) if os.IsNotExist(err) { - if err = os.MkdirAll(ctrDirOnHost, 0755); err != nil { - return nil, errors.Wrapf(err, "making container directory %q failed", ctrDirOnHost) - } - hostDir, err = resolveSymbolicLink(hostDir) + + hostDirOrFile, err = resolveSymbolicLink(hostDirOrFile) if err != nil { return nil, err } - data, err := getHostSecretData(hostDir) - if err != nil { - return nil, errors.Wrapf(err, "getting host secret data failed") - } - for _, s := range data { - if err := s.saveTo(ctrDirOnHost); err != nil { - return nil, errors.Wrapf(err, "error saving data to container filesystem on host %q", ctrDirOnHost) + switch mode := fileInfo.Mode(); { + case mode.IsDir(): + if err = os.MkdirAll(ctrDirOrFileOnHost, 0755); err != nil { + return nil, errors.Wrapf(err, "making container directory %q failed", ctrDirOrFileOnHost) + } + data, err := getHostSecretData(hostDirOrFile) + if err != nil { + return nil, errors.Wrapf(err, "getting host secret data failed") + } + for _, s := range data { + if err := s.saveTo(ctrDirOrFileOnHost); err != nil { + return nil, errors.Wrapf(err, "error saving data to container filesystem on host %q", ctrDirOrFileOnHost) + } + } + case mode.IsRegular(): + data, err := readFile("", hostDirOrFile) + if err != nil { + return nil, errors.Wrapf(err, "error reading file %q", hostDirOrFile) + + } + for _, s := range data { + if err := os.MkdirAll(filepath.Dir(ctrDirOrFileOnHost), 0700); err != nil { + return nil, err + } + if err := ioutil.WriteFile(ctrDirOrFileOnHost, s.data, 0700); err != nil { + return nil, errors.Wrapf(err, "error saving data to container filesystem on host %q", ctrDirOrFileOnHost) + } } + default: + return nil, errors.Errorf("unsupported file type for: %q", hostDirOrFile) } - err = label.Relabel(ctrDirOnHost, mountLabel, false) + err = label.Relabel(ctrDirOrFileOnHost, mountLabel, false) if err != nil { return nil, errors.Wrap(err, "error applying correct labels") } if uid != 0 || gid != 0 { - if err := rchown(ctrDirOnHost, uid, gid); err != nil { + if err := rchown(ctrDirOrFileOnHost, uid, gid); err != nil { return nil, err } } } else if err != nil { - return nil, errors.Wrapf(err, "error getting status of %q", ctrDirOnHost) + return nil, errors.Wrapf(err, "error getting status of %q", ctrDirOrFileOnHost) } m := rspec.Mount{ - Source: filepath.Join(mountPrefix, ctrDir), - Destination: ctrDir, + Source: filepath.Join(mountPrefix, ctrDirOrFile), + Destination: ctrDirOrFile, Type: "bind", Options: []string{"bind", "rprivate"}, } diff --git a/vendor/github.com/containers/buildah/pkg/unshare/unshare.go b/vendor/github.com/containers/buildah/pkg/unshare/unshare.go index 33232740e..5a68d6b8d 100644 --- a/vendor/github.com/containers/buildah/pkg/unshare/unshare.go +++ b/vendor/github.com/containers/buildah/pkg/unshare/unshare.go @@ -64,6 +64,7 @@ func (c *Cmd) Start() error { if os.Geteuid() != 0 { c.Env = append(c.Env, "_CONTAINERS_USERNS_CONFIGURED=done") c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_UID=%d", os.Geteuid())) + c.Env = append(c.Env, fmt.Sprintf("_CONTAINERS_ROOTLESS_GID=%d", os.Getegid())) } // Create the pipe for reading the child's PID. @@ -183,6 +184,7 @@ func (c *Cmd) Start() error { for _, m := range c.GidMappings { fmt.Fprintf(g, "%d %d %d\n", m.ContainerID, m.HostID, m.Size) } + gidmapSet := false // Set the GID map. if c.UseNewgidmap { cmd := exec.Command("newgidmap", append([]string{pidString}, strings.Fields(strings.Replace(g.String(), "\n", " ", -1))...)...) @@ -190,11 +192,16 @@ func (c *Cmd) Start() error { cmd.Stdout = g cmd.Stderr = g err := cmd.Run() - if err != nil { + if err == nil { + gidmapSet = true + } else { fmt.Fprintf(continueWrite, "error running newgidmap: %v: %s", err, g.String()) - return errors.Wrapf(err, "error running newgidmap: %s", g.String()) + fmt.Fprintf(continueWrite, "falling back to single mapping\n") + g.Reset() + g.Write([]byte(fmt.Sprintf("0 %d 1\n", os.Getegid()))) } - } else { + } + if !gidmapSet { gidmap, err := os.OpenFile(fmt.Sprintf("/proc/%s/gid_map", pidString), os.O_TRUNC|os.O_WRONLY, 0) if err != nil { fmt.Fprintf(continueWrite, "error opening /proc/%s/gid_map: %v", pidString, err) @@ -214,6 +221,7 @@ func (c *Cmd) Start() error { for _, m := range c.UidMappings { fmt.Fprintf(u, "%d %d %d\n", m.ContainerID, m.HostID, m.Size) } + uidmapSet := false // Set the GID map. if c.UseNewuidmap { cmd := exec.Command("newuidmap", append([]string{pidString}, strings.Fields(strings.Replace(u.String(), "\n", " ", -1))...)...) @@ -221,11 +229,16 @@ func (c *Cmd) Start() error { cmd.Stdout = u cmd.Stderr = u err := cmd.Run() - if err != nil { + if err == nil { + uidmapSet = true + } else { fmt.Fprintf(continueWrite, "error running newuidmap: %v: %s", err, u.String()) - return errors.Wrapf(err, "error running newuidmap: %s", u.String()) + fmt.Fprintf(continueWrite, "falling back to single mapping\n") + u.Reset() + u.Write([]byte(fmt.Sprintf("0 %d 1\n", os.Geteuid()))) } - } else { + } + if !uidmapSet { uidmap, err := os.OpenFile(fmt.Sprintf("/proc/%s/uid_map", pidString), os.O_TRUNC|os.O_WRONLY, 0) if err != nil { fmt.Fprintf(continueWrite, "error opening /proc/%s/uid_map: %v", pidString, err) @@ -354,7 +367,9 @@ func MaybeReexecUsingUserNamespace(evenForRoot bool) { // range in /etc/subuid and /etc/subgid file is a starting host // ID and a range size. uidmap, gidmap, err = GetSubIDMappings(me.Username, me.Username) - bailOnError(err, "error reading allowed ID mappings") + if err != nil { + logrus.Warnf("error reading allowed ID mappings: %v", err) + } if len(uidmap) == 0 { logrus.Warnf("Found no UID ranges set aside for user %q in /etc/subuid.", me.Username) } diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go index 81ce2b944..16c0550aa 100644 --- a/vendor/github.com/containers/buildah/run_linux.go +++ b/vendor/github.com/containers/buildah/run_linux.go @@ -131,7 +131,8 @@ func (b *Builder) Run(command []string, options RunOptions) error { return err } - if err := b.configureUIDGID(g, mountPoint, options); err != nil { + homeDir, err := b.configureUIDGID(g, mountPoint, options) + if err != nil { return err } @@ -210,7 +211,7 @@ func (b *Builder) Run(command []string, options RunOptions) error { } err = b.runUsingRuntimeSubproc(isolation, options, configureNetwork, configureNetworks, moreCreateArgs, spec, mountPoint, path, Package+"-"+filepath.Base(path)) case IsolationChroot: - err = chroot.RunUsingChroot(spec, path, options.Stdin, options.Stdout, options.Stderr) + err = chroot.RunUsingChroot(spec, path, homeDir, options.Stdin, options.Stdout, options.Stderr) case IsolationOCIRootless: moreCreateArgs := []string{"--no-new-keyring"} if options.NoPivot { @@ -1454,7 +1455,18 @@ func setupNamespaces(g *generate.Generator, namespaceOptions NamespaceOptions, i } if configureNetwork { for name, val := range util.DefaultNetworkSysctl { - g.AddLinuxSysctl(name, val) + // Check that the sysctl we are adding is actually supported + // by the kernel + p := filepath.Join("/proc/sys", strings.Replace(name, ".", "/", -1)) + _, err := os.Stat(p) + if err != nil && !os.IsNotExist(err) { + return false, nil, false, errors.Wrapf(err, "cannot stat %s", p) + } + if err == nil { + g.AddLinuxSysctl(name, val) + } else { + logrus.Warnf("ignoring sysctl %s since %s doesn't exist", name, p) + } } } return configureNetwork, configureNetworks, configureUTS, nil @@ -1775,14 +1787,14 @@ func getDNSIP(dnsServers []string) (dns []net.IP, err error) { return dns, nil } -func (b *Builder) configureUIDGID(g *generate.Generator, mountPoint string, options RunOptions) error { +func (b *Builder) configureUIDGID(g *generate.Generator, mountPoint string, options RunOptions) (string, error) { // Set the user UID/GID/supplemental group list/capabilities lists. - user, err := b.user(mountPoint, options.User) + user, homeDir, err := b.user(mountPoint, options.User) if err != nil { - return err + return "", err } if err := setupCapabilities(g, b.AddCapabilities, b.DropCapabilities, options.AddCapabilities, options.DropCapabilities); err != nil { - return err + return "", err } g.SetProcessUID(user.UID) g.SetProcessGID(user.GID) @@ -1797,7 +1809,7 @@ func (b *Builder) configureUIDGID(g *generate.Generator, mountPoint string, opti g.Config.Process.Capabilities.Bounding = bounding } - return nil + return homeDir, nil } func (b *Builder) configureEnvironment(g *generate.Generator, options RunOptions) { -- cgit v1.2.3-54-g00ecf