Merge pull request from rhatdan/build

Support podman --remote when Containerfile is not in context directory
This commit is contained in:
OpenShift Merge Robot
2023-05-30 13:53:02 -04:00
committed by GitHub
4 changed files with 29 additions and 25 deletions
pkg
api/handlers/compat
bindings/images
util
test/e2e

@ -221,9 +221,11 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
var m = []string{} var m = []string{}
if err := json.Unmarshal([]byte(query.Dockerfile), &m); err != nil { if err := json.Unmarshal([]byte(query.Dockerfile), &m); err != nil {
// it's not json, assume just a string // it's not json, assume just a string
m = []string{filepath.Join(contextDirectory, query.Dockerfile)} m = []string{query.Dockerfile}
}
for _, containerfile := range m {
containerFiles = append(containerFiles, filepath.Join(contextDirectory, filepath.Clean(filepath.FromSlash(containerfile))))
} }
containerFiles = m
dockerFileSet = true dockerFileSet = true
} }
} }

@ -650,14 +650,14 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
defer gw.Close() defer gw.Close()
defer tw.Close() defer tw.Close()
seen := make(map[devino]string) seen := make(map[devino]string)
for _, src := range sources { for i, src := range sources {
s, err := filepath.Abs(src) source, err := filepath.Abs(src)
if err != nil { if err != nil {
logrus.Errorf("Cannot stat one of source context: %v", err) logrus.Errorf("Cannot stat one of source context: %v", err)
merr = multierror.Append(merr, err) merr = multierror.Append(merr, err)
return return
} }
err = filepath.WalkDir(s, func(path string, d fs.DirEntry, err error) error { err = filepath.WalkDir(source, func(path string, dentry fs.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }
@ -665,9 +665,9 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
separator := string(filepath.Separator) separator := string(filepath.Separator)
// check if what we are given is an empty dir, if so then continue w/ it. Else return. // check if what we are given is an empty dir, if so then continue w/ it. Else return.
// if we are given a file or a symlink, we do not want to exclude it. // if we are given a file or a symlink, we do not want to exclude it.
if s == path { if source == path {
separator = "" separator = ""
if d.IsDir() { if dentry.IsDir() {
var p *os.File var p *os.File
p, err = os.Open(path) p, err = os.Open(path)
if err != nil { if err != nil {
@ -682,8 +682,15 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
} }
} }
} }
name := filepath.ToSlash(strings.TrimPrefix(path, s+separator)) var name string
if i == 0 {
name = filepath.ToSlash(strings.TrimPrefix(path, source+separator))
} else {
if !dentry.Type().IsRegular() {
return fmt.Errorf("path %s must be a regular file", path)
}
name = filepath.ToSlash(path)
}
excluded, err := pm.Matches(name) //nolint:staticcheck excluded, err := pm.Matches(name) //nolint:staticcheck
if err != nil { if err != nil {
return fmt.Errorf("checking if %q is excluded: %w", name, err) return fmt.Errorf("checking if %q is excluded: %w", name, err)
@ -695,8 +702,8 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
return nil return nil
} }
switch { switch {
case d.Type().IsRegular(): // add file item case dentry.Type().IsRegular(): // add file item
info, err := d.Info() info, err := dentry.Info()
if err != nil { if err != nil {
return err return err
} }
@ -735,8 +742,8 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
seen[di] = name seen[di] = name
} }
return err return err
case d.IsDir(): // add folders case dentry.IsDir(): // add folders
info, err := d.Info() info, err := dentry.Info()
if err != nil { if err != nil {
return err return err
} }
@ -749,12 +756,12 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
if lerr := tw.WriteHeader(hdr); lerr != nil { if lerr := tw.WriteHeader(hdr); lerr != nil {
return lerr return lerr
} }
case d.Type()&os.ModeSymlink != 0: // add symlinks as it, not content case dentry.Type()&os.ModeSymlink != 0: // add symlinks as it, not content
link, err := os.Readlink(path) link, err := os.Readlink(path)
if err != nil { if err != nil {
return err return err
} }
info, err := d.Info() info, err := dentry.Info()
if err != nil { if err != nil {
return err return err
} }

@ -94,6 +94,7 @@ func ParseDockerignore(containerfiles []string, root string) ([]string, string,
// so remote must support parsing that. // so remote must support parsing that.
if dockerIgnoreErr != nil { if dockerIgnoreErr != nil {
for _, containerfile := range containerfiles { for _, containerfile := range containerfiles {
containerfile = strings.TrimPrefix(containerfile, root)
if _, err := os.Stat(filepath.Join(root, containerfile+".containerignore")); err == nil { if _, err := os.Stat(filepath.Join(root, containerfile+".containerignore")); err == nil {
path, symlinkErr = securejoin.SecureJoin(root, containerfile+".containerignore") path, symlinkErr = securejoin.SecureJoin(root, containerfile+".containerignore")
if symlinkErr == nil { if symlinkErr == nil {

@ -358,14 +358,9 @@ RUN exit 5`, ALPINE)
if IsRemote() { if IsRemote() {
podmanTest.StopRemoteService() podmanTest.StopRemoteService()
podmanTest.StartRemoteService() podmanTest.StartRemoteService()
} else {
Skip("Only valid at remote test, case works fine for regular podman and buildah")
} }
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())
// Write target and fake files // Write target and fake files
targetSubPath := filepath.Join(cwd, "emptydir") targetSubPath := filepath.Join(podmanTest.TempDir, "emptydir")
if _, err = os.Stat(targetSubPath); err != nil { if _, err = os.Stat(targetSubPath); err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
err = os.Mkdir(targetSubPath, 0755) err = os.Mkdir(targetSubPath, 0755)
@ -374,14 +369,14 @@ RUN exit 5`, ALPINE)
} }
containerfile := fmt.Sprintf(`FROM %s containerfile := fmt.Sprintf(`FROM %s
COPY /* /dir`, ALPINE) COPY /emptydir/* /dir`, ALPINE)
containerfilePath := filepath.Join(cwd, "ContainerfilePathToCopier") containerfilePath := filepath.Join(podmanTest.TempDir, "ContainerfilePathToCopier")
err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) err = os.WriteFile(containerfilePath, []byte(containerfile), 0644)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
defer os.Remove(containerfilePath) defer os.Remove(containerfilePath)
session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "-f", "ContainerfilePathToCopier", targetSubPath}) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "-f", "ContainerfilePathToCopier", podmanTest.TempDir})
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
// NOTE: Docker and buildah both should error when `COPY /* /dir` is done on emptydir // NOTE: Docker and buildah both should error when `COPY /* /dir` is done on emptydir
// as context. However buildkit simply ignores this so when buildah also starts ignoring // as context. However buildkit simply ignores this so when buildah also starts ignoring
@ -614,7 +609,6 @@ subdir**`
Expect(session).To(Exit(0)) Expect(session).To(Exit(0))
output := session.OutputToString() output := session.OutputToString()
Expect(output).NotTo(ContainSubstring("Containerfile"))
Expect(output).To(ContainSubstring("/testfilter/expected")) Expect(output).To(ContainSubstring("/testfilter/expected"))
Expect(output).NotTo(ContainSubstring("subdir")) Expect(output).NotTo(ContainSubstring("subdir"))
}) })