-
Notifications
You must be signed in to change notification settings - Fork 69
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
Treat args the same way docker build
does
#151
Treat args the same way docker build
does
#151
Conversation
Hi @carbonin. Thanks for your PR. I'm waiting for a openshift member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/assign @nalind |
/approve |
@TomSweeneyRedHat PTAL |
@bparees PTAL |
will this handle:
which in docker at least, does substitute in the FROM line, but does not do anything in the RUN:
|
@bparees actually it looks like that's an error with this change. master branch:
This patch:
Will look into that when I get a chance. |
@bparees It looks like Line 165 in 47f96c1
Sorry for the basic question, but how do I run that test case? It doesn't seem to run using
|
i don't think that would fail, it's just going to resolve to which means it's not a great test. |
oh sorry, i see what you mean. i do not know, sorry. this really isn't a repo i deal w/ normally |
Sorry @carbonin I've been buried in a gazillion things recently. Hope to get a good look this weekend. |
builder.go
Outdated
@@ -264,6 +264,16 @@ func extractNameFromNode(node *parser.Node) (string, bool) { | |||
return n.Next.Value, true | |||
} | |||
|
|||
func argsForStage(stageRoot *parser.Node, allArgs map[string]string) map[string]string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For history's sake, it would be good to have a comment for this function talking about what you expect it to do.
I too have not been in this project for several months, but I know @nalin has been quite a bit. So if he says anything different than I, trust his word. First off, something is off with archive.go. I've just fixed that in #152, however now the conformance tests are failing in a number of places with that fix in play. I'm guessing that the conformance tests are not being regularly run. To run a particular test in builder_test.go, you need to do (-v (verbose) is optional, but very helpful):
But those too are also not passing. However, your new test seems to be working:
Once you chase down the problem above, it would be good to get @nalin to eyeball this. |
37304af
to
0032c32
Compare
Okay I added a commit to alter an existing test case to deal with the situation from @bparees's comment But while investigating this behavior and how to deal with it I found https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact#understand-how-arg-and-from-interact which complicates things a bit. What behavior should we be striving for here? Are we trying to emulate docker exactly? There seems to be considerable confusion around this particular command combination: moby/moby#34129 Right now we're treating the "heading" args as global and applying them to all the following commands, but Docker's handling is only applying the heading args to Is it safe to assume we don't want to tackle all of that in this patch? With that assumption, how far should I take this one? Just fix the test in the new commit I added? I think restricting the scope of the heading args would be a rather breaking change for users of |
Oh and the edited test now fails like this with my changes:
|
for imagebuilder itself i don't have a strong opinion, but for buildah as a consumer of imagebuilder, i think buildah should be emulating docker including all its...idiosyncrasies, since it is routed as a drop-in/aliasable replacement for "docker build" it may be worth buildah having a "--sane" mode which drops those compatbility behaviors in deference to preferred behavior. (thinking about the recent COPY behavior discoveries we have made) |
I'd just tweak @bparees expectation comment slightly. |
Okay, so let me ask a more specific question. How do we want Each stage returned by that function has a Builder with args. Should every builder have access to the args defined before the first ARG FOO=centos
ARG BAZ=things
FROM $FOO
RUN echo hello $FOO
FROM alpine
RUN echo hello $FOO
ARG FOO=alpine
FROM $FOO
ARG BAZ
RUN echo hello $FOO
RUN echo hello $BAZ For what it's worth, right now it's like this:
Buildah can post-process those stages to get what we want there. But what, for this project, do we want the "correct" behavior to be? |
Note that in the previous example the first |
We need to match |
0032c32
to
f2e3dd0
Compare
Okay, this now tries to tackle all of the gaps I could find between I found one more bug that I'm still trying to work out, but would appreciate a look at what I have here as this is getting quite involved. |
@carbonin Could you open a WIP vendor of this in Buildah to make sure it passes the Buildah CI tests. |
The code looks good to me, and I like that there are lots of tests. The issue is probably getting people more in the know of the deep level of how this is supposed to work. @kolyshkin PTAL |
/ok-to-test |
docker build
does
I've went full circle here and removed the method I added in the first commit 😅 I can squash these if that's preferred ... |
@rhatdan added a commit in containers/buildah#2220 to include my branch as the imagebuilder source |
@carbonin Thanks, it will give me better confidence on this if it can pass Buildah and imagebuilder tests. |
@rhatdan Seeing as how this is passing tests here and the only tests failing in buildah with this branch are the ones I added to expose this problem, can we move forward with this patch? Is there someone else I should contact for review? |
lgtm |
There were a few inconsistencies in the way imagebuilder handled arguments vs the way that docker handles them. This commit addresses those gaps. Specifically: - Subsequent ARG commands with default values override previous ones, but they don't override the values passed on the command line. - Heading args (ARG commands before the first FROM) are applied only to FROM commands unless a matching ARG command exists in a particular stage in which case the value from the heading arg carries forward into that stage. This was accomplished by creating a dedicated Builder struct field for user args and heading args so that they can be tracked separately from args declared with ARG commands in individual stages. Tracking these all separately allows us to apply these priority rules as the build progresses. Signed-off-by: Nick Carboni <ncarboni@redhat.com>
a7abcba
to
d569093
Compare
Patches look reasonable, and the behavior is consistent with what I can observe with the moby-engine-18.09.7-5.ce.git2d0083d.fc30 package on Fedora 30. LGTM. |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: carbonin, rhatdan 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 |
2220: Scope build args to a single stage in a multi-stage build r=rhatdan a=carbonin <!-- Thanks for sending a pull request! Please make sure you've read and understood our contributing guidelines (https://github.com/containers/buildah/blob/master/CONTRIBUTING.md) as well as ensuring that all your commits are signed with `git commit -s`. --> #### What type of PR is this? <!-- Please label this pull request according to what type of issue you are addressing, especially if this is a release targeted pull request. Uncomment only one `/kind <>` line, hit enter to put that in a new line, and remove leading whitespace from that line: --> /kind bug #### What this PR does / why we need it: This PR uses the changes made in openshift/imagebuilder#151 to handle arguments the same way `docker build` does. In particular, it scopes arguments to the stage in which they are defined and only records arguments in a layer's history if they could have been used in that layer. #### How to verify it ``` $ cat Dockerfile FROM alpine ARG THING FROM alpine RUN echo "$THING" > things $ buildah bud --layers --build-arg THING=things STEP 1: FROM alpine STEP 2: ARG THING --> Using cache 232af6ca4a94e52dbef13f6da08c62b4172eaff7ee2e93cab08aceb4b00e6f81 STEP 3: FROM alpine STEP 4: RUN echo "$THING" > things --> Using cache fad9788d65a3062cc823516c8fff73b39e914463c709149a2855cbea61a10abe fad9788d65a3062cc823516c8fff73b39e914463c709149a2855cbea61a10abe $ podman run --rm fad9788d65a3062cc823516c8fff73b39e914463c709149a2855cbea61a10abe cat things things ``` The above `podman run` command should return an empty file #### Which issue(s) this PR fixes: <!-- Automatically closes linked issue when PR is merged. Uncomment the following comment block and include the issue number or None on one line. Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`, or `None`. --> Fixes #2210 #### Does this PR introduce a user-facing change? <!-- If no, just write `None` in the release-note block below. If yes, a release note is required: Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required". For more information on release notes please follow the kubernetes model: https://git.k8s.io/community/contributors/guide/release-notes.md --> Yes, it significantly changes the way arguments behave. While it's not a change to how `buildah` would be used. Images built with the same Dockerfile before and after this change could be very different. ```release-note Altered the behavior of the `--build-arg` flag and `ARG` commands to mirror `docker build`. In particular, the following behaviors have changed: - An ARG is only available after its ARG command in the current stage. - Previously, anything provided using the --build-arg flag could be accessed in any stage. After this change, accessing a build arg provided on the command line will require a corresponding `ARG` command in the stage before it is accessed. - Additionally, "heading" args (ARG commands before the first FROM) also now require an additional ARG declaration in the stage to be accessed. Previously, they were accessible without the additional ARG command. - A later ARG default value should override an earlier one in the same stage FROM alpine ARG FOO=foo ARG FOO=bar RUN echo "$FOO" The above Dockerfile should print "bar". Previously, the behavior was the opposite, an arg was not changed once set. Generally this makes buildah handle args as described in https://docs.docker.com/engine/reference/builder/#arg ``` Co-authored-by: Nick Carboni <ncarboni@redhat.com>
Before this change a Dockerfile like this:
would expose the arg "SECRET" in every layer of the build.
Now the ARG is only accessible in the layer it is defined.
This gives us parity with the Docker behavior described in
https://docs.docker.com/engine/reference/builder/#scope
"An ARG instruction goes out of scope at the end of the build
stage where it was defined. To use an arg in multiple stages,
each stage must include the ARG instruction."
This was originally reported as containers/buildah#2210
cc @rhatdan
I wasn't sure how to run the tests locally so I hope this one works... 😆
EDIT:
This PR now attempts to handle all the gaps between
imagebuilder
's ARG handling anddocker build
's, one of which was the issue described above and in containers/buildah#2210I have tried to create test cases or edit existing ones to cover all of the cases, but I'll also list them here.
An ARG should only be available after its ARG command in the current stage
This is the original problem, described above. As well as the issue raised by @bparees in #151 (comment)
A later ARG default value should override an earlier one in the same stage
The above Dockerfile should print "bar". Before this patch, the behavior was the opposite, an arg was not changed once set (this old behavior effectively achieved the user-provided case, but the combination of the two necessitated a new Builder struct field for user args).
User provided args should override all args default values
Building the above Docerfile with
--build-arg TAG=7
should build the first stage fromcentos:7
and print "7" in both stages.