Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

buildah: add heredoc support for RUN, COPY and ADD #5092

Merged
merged 2 commits into from Nov 17, 2023

Conversation

flouthoc
Copy link
Collaborator

Following PR is a attempt to add Heredoc support to buildah.

Once this PR is merged buildah is supposed to honor heredoc syntax while processing containerfiles

Expected syntax to work

FROM docker.io/library/python:latest
RUN <<EOF
echo "Hello" >> /hello
echo "World!" >> /hello
EOF

RUN python3 <<EOF
with open("/hello", "w") as f:
    print("Hello", file=f)
    print("Something", file=f)
EOF

RUN ls -a
RUN cat hello

What type of PR is this?

/kind api-change
/kind bug
/kind cleanup
/kind deprecation
/kind design
/kind documentation
/kind failing-test
/kind feature
/kind flake
/kind other

What this PR does / why we need it:

How to verify it

Which issue(s) this PR fixes:

Special notes for your reviewer:

Does this PR introduce a user-facing change?

buildah: add heredoc support for RUN, COPY and ADD

Closes: #3474

@flouthoc
Copy link
Collaborator Author

Needs: openshift/imagebuilder#264

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 19, 2023

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: flouthoc

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@packit-as-a-service
Copy link

Ephemeral COPR build failed. @containers/packit-build please check.

@flouthoc flouthoc force-pushed the heredoc-experiment branch 3 times, most recently from 891a27f to ab6f1fd Compare October 23, 2023 09:01
@flouthoc flouthoc marked this pull request as ready for review October 23, 2023 09:02
@flouthoc flouthoc changed the title [WIP] buildah: add heredoc support for RUN, COPY and ADD buildah: add heredoc support for RUN, COPY and ADD Oct 23, 2023
@flouthoc
Copy link
Collaborator Author

This needs: openshift/imagebuilder#264

Other then the imagebuilder PR, following PR is ready to review.

@nalind @rhatdan @TomSweeneyRedHat @vrothberg @giuseppe @containers/buildah-maintainers PTAL

/hold wait till openshift/imagebuilder#264

@TomSweeneyRedHat
Copy link
Member

Changes here LGTM in general. I assume you'll also be updating the Containerfile man page in in c/common with the heredocs examples?

@flouthoc
Copy link
Collaborator Author

Changes here LGTM in general. I assume you'll also be updating the Containerfile man page in in c/common with the heredocs examples?

@TomSweeneyRedHat Yes I'll open a PR in c/common once this gets merged. As of now I am waiting for openshift/imagebuilder#264

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 26, 2023
@flouthoc flouthoc force-pushed the heredoc-experiment branch 2 times, most recently from 9828aad to b6bf870 Compare November 7, 2023 06:47
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 7, 2023
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 10, 2023
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 10, 2023
@flouthoc flouthoc force-pushed the heredoc-experiment branch 2 times, most recently from cf0e396 to bc1f310 Compare November 10, 2023 15:42
@flouthoc
Copy link
Collaborator Author

This PR is read for review.

@flouthoc flouthoc requested a review from nalind November 10, 2023 15:43
Copy link
Member

@nalind nalind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly nits and a conformance test question.

for _, src := range copy.Src {
// If this source is not a heredoc, then it is a regular file from
// build context or from another stage (`--from=`) so treat this differently.
if !strings.HasPrefix(src, "<<") && !strings.HasPrefix(src, "<<-") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the value doesn't have << as a prefix, it can't have <<- as a prefix, so I don't think we need to be checking for both of these.

imagebuildah/stage_executor.go Show resolved Hide resolved
data = strings.TrimPrefix(data, "\n")
// add breakline when heredoc ends for docker compat
data = data + "\n"
tmpFile, err := os.Create(filepath.Join(parse.GetTempDir(), filepath.Base(filepath.ToSlash(file.Name))))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After passing a pathname through filepath.ToSlash(), the result should be manipulated using the path package rather than filepath, since filepath expects the platform-specific path separator, which isn't / on Windows hosts.

"(dir):test2:(dir):robots.txt:mtime",
"(dir):test2:(dir):image_file:mtime",
"(dir):test2:(dir):image_file:uid", /* buildkit's regular COPY sets UID which is inconsistent with docker and buildah*/
"(dir):test2:(dir):image_file:gid", /* buildkit's regular COPY sets GID which is inconsistent with docker and buildah*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What values does it use? Why is it okay to ignore the differences?

Copy link
Collaborator Author

@flouthoc flouthoc Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buildkit sets uid and gid to 1000 with COPY instruction in conformance test and buildah/docker keeps it 0, i suspect either problem is with buildkit client in conformance test or could be a buildkit issue, this happens on upstream as well so I was not able to spend time on it to figure out root cause for it. Since this was not related to this PR hence I did not touch it for now ( will investigate issue in a different PR )

Issue reproducer for upstream:

Following problem is with all the COPY ( where uid and gid are not modified ) related tests included in conformance_test.go

For example a try out example is

diff --git a/tests/conformance/conformance_test.go b/tests/conformance/conformance_test.go
index 6ec8f3837..e494cb116 100644
--- a/tests/conformance/conformance_test.go
+++ b/tests/conformance/conformance_test.go
@@ -2784,6 +2784,7 @@ var internalTestCases = []testCase{
        {
                name:       "copy-for-user", // flip side of issue #2518
                contextDir: "copy",
+               dockerUseBuildKit: true,
                dockerfileContents: strings.Join([]string{
                        `FROM alpine`,
                        `USER 66:66`,

and output fails

[fl@fedora buildah]$ sudo GOROOT=/usr/local/go go test -v -timeout=30m -run TestConformance/copy-for-user ./tests/conformance
=== RUN   TestConformance
=== RUN   TestConformance/copy-for-user
    conformance_test.go:482: 
        	Error Trace:	/home/fl/heredoc-exp/buildah/tests/conformance/conformance_test.go:482
        	            				/home/fl/heredoc-exp/buildah/tests/conformance/conformance_test.go:333
        	            				/home/fl/heredoc-exp/buildah/tests/conformance/conformance_test.go:151
        	Error:      	Filesystem contents differ
        	Test:       	TestConformance/copy-for-user
        	Messages:   	File attributes in both versions have different values:
        	            	File:attr          Docker        buildah
        	            	/script:uid        1000          0
        	            	/script:gid        1000          0
    conformance_test.go:355: Context "/home/fl/heredoc-exp/buildah/tests/conformance/testdata/copy"
    conformance_test.go:367: Dockerfile contents:
        FROM alpine
        USER 66:66
        COPY /script /script
        (no final end-of-line)
=== RUN   TestConformance/copy-for-user-with-chown
--- FAIL: TestConformance (13.23s)
    --- FAIL: TestConformance/copy-for-user (6.97s)
    --- PASS: TestConformance/copy-for-user-with-chown (6.26s)
FAIL
FAIL	github.com/containers/buildah/tests/conformance	13.244s
FAIL

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So BuildKit is retaining the uid/gid of the files in the context directory, which are owned by your unprivileged user, instead of setting them to 0?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's expecting the client to hand it an archive with ownerships set to 0:0 and go-dockerclient isn't doing that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #5171 to generate the buildcontext archive we hand to dockerd with imagebuilder's helper, which sets ownerships in it to 0:0.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks I verified against #5171 and it works, I have removed uid and gid skips, will rebase after #5171

@flouthoc flouthoc force-pushed the heredoc-experiment branch 3 times, most recently from 34a2111 to d90ffec Compare November 16, 2023 18:11
"(dir):test2:mtime",
"(dir):test:(dir):humans.txt:mtime",
"(dir):test:(dir):robots.txt:mtime",
"(dir):test:(dir):file:mtime",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file comes from the build context, so I'd expect its datestamp to be consistent between different builds.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct, this skip is not needed.

@@ -348,6 +350,7 @@ func (s *StageExecutor) volumeCacheRestore() error {
// imagebuilder tells us the instruction was "ADD" and not "COPY".
func (s *StageExecutor) Copy(excludes []string, copies ...imagebuilder.Copy) error {
s.builder.ContentDigester.Restart()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the impact of this getting called in between adding heredocs and adding other content on the history and build caching?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored now digester does not restarts between heredoc and regular copy. Before this it was affecting history of the image keeping only the most recent copy in the history.

@flouthoc
Copy link
Collaborator Author

@nalind Could you PTAL again.

Copy link
Member

@nalind nalind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking nit, could probably use a rebase.

imagebuildah/stage_executor.go Outdated Show resolved Hide resolved
Signed-off-by: Aditya R <arajan@redhat.com>
Following PR is a attempt to add `Heredoc` support to buildah.

Once this PR is merged buildah is supposed to honor heredoc syntax while
processing containerfiles

Expected syntax to work

```Dockerfile
FROM docker.io/library/python:latest
RUN <<EOF
echo "Hello" >> /hello
echo "World!" >> /hello
EOF

RUN python3 <<EOF
with open("/hello", "w") as f:
    print("Hello", file=f)
    print("Something", file=f)
EOF

RUN ls -a
RUN cat hello
```

Signed-off-by: Aditya R <arajan@redhat.com>
@nalind
Copy link
Member

nalind commented Nov 17, 2023

/lgtm

@TomSweeneyRedHat
Copy link
Member

LGTM
Now play nicely CI!

@flouthoc
Copy link
Collaborator Author

/hold cancel

@openshift-merge-bot openshift-merge-bot bot merged commit 07482ae into containers:main Nov 17, 2023
36 checks passed
@TomSweeneyRedHat
Copy link
Member

Grats on getting this in @flouthoc ! Nice work again!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Heredoc notation doesn't work
6 participants