From d959049b3ffcb2a57539ceddf9b659402d1c33fe Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sun, 3 Mar 2024 08:52:55 -0800 Subject: [PATCH] dockerfile: allow pivot point for --parents flag This replicates similar functionality in rsync. Signed-off-by: Tonis Tiigi (cherry picked from commit 6f8bd4cb0e7ccf773d692beb9bc89032099881b2) --- frontend/dockerfile/dockerfile2llb/convert.go | 26 +++-- .../dockerfile/dockerfile_parents_test.go | 106 ++++++++++++++++++ 2 files changed, 125 insertions(+), 7 deletions(-) diff --git a/frontend/dockerfile/dockerfile2llb/convert.go b/frontend/dockerfile/dockerfile2llb/convert.go index 531aa09484bd..b79407955542 100644 --- a/frontend/dockerfile/dockerfile2llb/convert.go +++ b/frontend/dockerfile/dockerfile2llb/convert.go @@ -1252,18 +1252,30 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error { a = a.Copy(st, f, dest, opts...) } } else { + var patterns []string + if cfg.parents { + // detect optional pivot point + parent, pattern, ok := strings.Cut(src, "/./") + if !ok { + pattern = src + src = "/" + } else { + src = parent + } + + pattern, err = system.NormalizePath("/", pattern, d.platform.OS, false) + if err != nil { + return errors.Wrap(err, "removing drive letter") + } + + patterns = []string{strings.TrimPrefix(pattern, "/")} + } + src, err = system.NormalizePath("/", src, d.platform.OS, false) if err != nil { return errors.Wrap(err, "removing drive letter") } - var patterns []string - if cfg.parents { - path := strings.TrimPrefix(src, "/") - patterns = []string{path} - src = "/" - } - opts := append([]llb.CopyOption{&llb.CopyInfo{ Mode: mode, FollowSymlinks: true, diff --git a/frontend/dockerfile/dockerfile_parents_test.go b/frontend/dockerfile/dockerfile_parents_test.go index 4400a27781eb..47f06e803924 100644 --- a/frontend/dockerfile/dockerfile_parents_test.go +++ b/frontend/dockerfile/dockerfile_parents_test.go @@ -18,6 +18,7 @@ import ( var parentsTests = integration.TestFuncs( testCopyParents, + testCopyRelativeParents, ) func init() { @@ -75,3 +76,108 @@ COPY --parents foo1/foo2/ba* . require.NoError(t, err) require.Equal(t, "testing2", string(dt)) } + +func testCopyRelativeParents(t *testing.T, sb integration.Sandbox) { + f := getFrontend(t, sb) + + dockerfile := []byte(` +FROM alpine AS base +WORKDIR /test +RUN <