-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Added support for Docker ARG values. #12439
Added support for Docker ARG values. #12439
Conversation
[test] |
pkg/build/api/types.go
Outdated
@@ -937,6 +941,10 @@ type BuildRequest struct { | |||
// Env contains additional environment variables you want to pass into a builder container. | |||
Env []kapi.EnvVar | |||
|
|||
// Args contains any build arguments that are to be passed to Docker. |
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.
This doesn't belong in this structure unless build args are going to be generic to all strategies.
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.
Roger, it has been removed
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.
@smarterclayton Looking for a different solution, maybe we should have a strategy specific struct in BuildRequest that doesn't always have to be present? Spoke with @csrwng about it for a bit, seems that this may be a good option.
pkg/build/api/types.go
Outdated
@@ -562,6 +562,10 @@ type DockerBuildStrategy struct { | |||
// Env contains additional environment variables you want to pass into a builder container | |||
Env []kapi.EnvVar | |||
|
|||
// Args contains any build arguments that are to be passed to Docker. See |
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.
Why are Env and BuildArgs distinct?
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.
They are consumed at different parts of the build process. Env variables are put into the build container, the Build Args would be consumed by the docker invocation. Perhaps Env isn't used by Docker Strategies? In that case, we could use Env, but I think that would be a bit confusing in the future.
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.
Env is used already, I don't think we could consolidate BuildArgs and Env together
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.
Is Env used by docker build strategies today?
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.
Yes, here
Putting this on hold until next sprint |
@smarterclayton I've changed the BuildRequest to have a BuildStrategyOptions struct, which would allow for different options for different strategy types. ptal? |
@smarterclayton ping |
Small change to GenericWebhookEvent, changed |
@openshift/api-review bump please. |
@bparees I separated the api changes from the rest of the PR. This should be it's final state, sans your requests of couse ;) ptal? Removing the WIP tag |
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.
needs tests for new-app/new-build
pkg/build/api/types.go
Outdated
@@ -588,6 +588,11 @@ type DockerBuildStrategy struct { | |||
// Env contains additional environment variables you want to pass into a builder container | |||
Env []kapi.EnvVar | |||
|
|||
// Args contains any build arguments that are to be passed to Docker. See | |||
// https://docs.docker.com/engine/reference/builder/#/arg for more details | |||
// TODO: This should be a docker.BuildArg array, but protobuf has issues w/ it |
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.
i think you can remove this TODO. EnvVar serves the purpose just fine.
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.
i see a thumbs up but the line is still here...
pkg/build/builder/docker.go
Outdated
@@ -318,6 +319,13 @@ func (d *DockerBuilder) dockerBuild(dir string, tag string, secrets []api.Secret | |||
if d.build.Spec.Strategy.DockerStrategy.DockerfilePath != "" { | |||
dockerfilePath = d.build.Spec.Strategy.DockerStrategy.DockerfilePath | |||
} | |||
// TODO: Check for non-existent build args here, if necessary |
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.
?
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.
Currently, if you pass a build arg to Docker which doesn't get used, the build fails. This is only reported in the Build logs, which may be a bit harder to debug. We could, alternatively, check for build args when we parse the Dockerfile, but this may be more complicated than we want.
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.
I've removed this TODO, but the idea was mentioned elsewhere
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.
yeah i'm not a fan of us taking responsibility for sanity checking such things.
pkg/build/builder/docker.go
Outdated
// TODO: Check for non-existent build args here, if necessary | ||
if len(d.build.Spec.Strategy.DockerStrategy.BuildArgs) > 0 { | ||
envVarBuildArgs := d.build.Spec.Strategy.DockerStrategy.BuildArgs | ||
for _, ba := range envVarBuildArgs { |
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.
you don't need to do this assignment or the length check. just range over d.build.Spec.Strategy.DockerStrategy.BuildArgs
it won't do anything if it's nil or empty.
pkg/build/generator/generator.go
Outdated
result = append(result, kapi.EnvVar{Name: k, Value: v}) | ||
} | ||
|
||
*oldArgs = result |
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.
don't mutate the args, return the new array.
pkg/build/generator/generator.go
Outdated
@@ -240,6 +263,19 @@ func (g *BuildGenerator) Instantiate(ctx kapi.Context, request *buildapi.BuildRe | |||
return nil, errors.NewInternalError(err) | |||
} | |||
|
|||
// Check if the user specified |
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.
specified what?
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.
Changed to better describe the following code
pkg/cmd/cli/cmd/startbuild.go
Outdated
@@ -278,6 +283,16 @@ func (o *StartBuildOptions) Complete(f *clientcmd.Factory, in io.Reader, out, er | |||
} | |||
o.EnvVar = env | |||
|
|||
// Handle Docker build arguments. In order to leverage existing logic, we | |||
// first create an EnvVar array, then convert it to []docker.BuildArg | |||
cmdutil.WarnAboutCommaSeparation(o.ErrOut, o.Args, "--build-args") |
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.
we don't need to warn about comma separate for this flag because it never supported comma separation before.
pkg/cmd/cli/cmd/startbuild.go
Outdated
// Handle Docker build arguments. In order to leverage existing logic, we | ||
// first create an EnvVar array, then convert it to []docker.BuildArg | ||
cmdutil.WarnAboutCommaSeparation(o.ErrOut, o.Args, "--build-args") | ||
// TODO: This prints some stuff that's Env specific, need to change |
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.
?
pkg/generate/app/pipeline.go
Outdated
@@ -90,6 +92,8 @@ func (pb *pipelineBuilder) NewBuildPipeline(from string, input *ImageRef, source | |||
} | |||
source.Name = name | |||
|
|||
// TODO: We could possibly pre-populate a list of build-args here to prevent | |||
// incorrect use |
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.
?
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.
Removed
test/extended/builds/start.go
Outdated
buildLog, err := br.Logs() | ||
o.Expect(err).NotTo(o.HaveOccurred()) | ||
g.By(fmt.Sprintf("verifying the build failed due to Docker.", br.BuildPath)) | ||
o.Expect(buildLog).To(o.ContainSubstring("FOO")) |
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.
isn't the successful build also going to contain "FOO"? seems like we need a more stringent expected text to check for.
test/externals.txt
Outdated
https://github.com/gabemontero/forcepull-extended-test-builder.git | ||
[email protected]:mfojtik/sinatra-app-example | ||
git://github.com/mfojtik/sinatra-example-2 | ||
git://github.com/mfojtik/sinatra-example-1 |
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.
I assume you didn't mean to deliver this file...
@bparees Ready for another go, ptal? |
pkg/build/api/types.go
Outdated
@@ -588,6 +588,11 @@ type DockerBuildStrategy struct { | |||
// Env contains additional environment variables you want to pass into a builder container | |||
Env []kapi.EnvVar | |||
|
|||
// Args contains any build arguments that are to be passed to Docker. See | |||
// https://docs.docker.com/engine/reference/builder/#/arg for more details | |||
// TODO: This should be a docker.BuildArg array, but protobuf has issues w/ it |
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.
i see a thumbs up but the line is still here...
pkg/build/api/v1/types.go
Outdated
|
||
// Args contains any build arguments that are to be passed to Docker. See | ||
// https://docs.docker.com/engine/reference/builder/#/arg for more details | ||
// TODO: This should be a docker.BuildArg array, but protobuf has issues w/ it |
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.
get rid of the todo.
pkg/build/generator/generator.go
Outdated
if newBuild.Spec.Strategy.DockerStrategy != nil { | ||
newBuild.Spec.Strategy.DockerStrategy.BuildArgs = updateBuildArgs(&newBuild.Spec.Strategy.DockerStrategy.BuildArgs, dockerOpts.BuildArgs) | ||
} else { | ||
errors.NewBadRequest(fmt.Sprintf("Cannot specify build args on %s/%s, not a Docker build.", bc.Namespace, bc.ObjectMeta.Name)) |
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.
don't you need to return this?
pkg/build/generator/generator.go
Outdated
newBuild.Spec.Strategy.DockerStrategy.BuildArgs = updateBuildArgs(&newBuild.Spec.Strategy.DockerStrategy.BuildArgs, dockerOpts.BuildArgs) | ||
} else { | ||
return nil, errors.NewBadRequest(fmt.Sprintf("Cannot specify build args on %s/%s, not a Docker build.", buildConfig.Namespace, buildConfig.ObjectMeta.Name)) | ||
} |
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.
if not_a_docker_build {
return nil, errors.blahblah
}
newbuild.blahblah=updateblahblah()
pkg/cmd/cli/cmd/newbuild.go
Outdated
@@ -95,6 +96,8 @@ type NewBuildOptions struct { | |||
Output string | |||
PrintObject func(obj runtime.Object) error | |||
LogsForObject LogsForObjectFunc | |||
|
|||
BuildArgs []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.
why isn't this part of Config like everything else?
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.
I figured since it was new-build specific, it would be better here
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.
i'd treat it the same way we treat BinaryBuild (which is also specific to new-build).
pkg/cmd/cli/cmd/newbuild.go
Outdated
if err != nil { | ||
return fmt.Errorf(strings.Replace(err.Error(), "environment variable", "build arg", -1)) | ||
} | ||
o.Config.BuildArgs = buildArgs |
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.
i would expect this to be handled in the same place/manner as we handle o.Config.Environment
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.
I didn't add handling of BuildArgs to (AppConfig) validate(), but we are now processing the BuildArgs in buildPipeline, where BuildEnvironment is handled.
pkg/cmd/cli/cmd/startbuild.go
Outdated
// first create an EnvVar array, then convert it to []docker.BuildArg | ||
buildArgs, _, err := cmdutil.ParseEnv(o.Args, in) | ||
if err != nil { | ||
return fmt.Errorf(strings.Replace(err.Error(), "environment variable", "build arg", -1)) |
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.
this is fragile. better to just change ParseEnv to be more generic in its error messages.
test/cmd/newapp.sh
Outdated
@@ -163,6 +163,12 @@ os::cmd::expect_success "oc new-build --binary php --build-env-file /dev/null -- | |||
os::cmd::expect_failure_and_text "echo 'fo%(o=bar' | oc new-build --binary php --build-env-file -" 'invalid parameter assignment' | |||
os::cmd::expect_failure_and_text "echo 'S P A C E S=test' | oc new-build --binary php --build-env-file -" 'invalid parameter assignment' | |||
|
|||
# new-build | |||
# check that env vars are not split on commas and warning is printed where they previously have |
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.
comment is wrong.
@bparees I've updated the PR, ptal? |
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.
@oatmealraisin one last thing and then lgtm. @openshift/api-review bump. this is for 3.6.
} | ||
newBuild.Spec.Strategy.DockerStrategy.BuildArgs = updateBuildArgs(&newBuild.Spec.Strategy.DockerStrategy.BuildArgs, dockerOpts.BuildArgs) | ||
} | ||
} |
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.
is the clone path ignoring the request.environment field? it looks like it is. that should be fixed while you're in here.
pkg/build/api/types.go
Outdated
@@ -936,6 +943,43 @@ type BuildLog struct { | |||
unversioned.TypeMeta | |||
} | |||
|
|||
// DockerStrategyOptions contains extra strategy options for Docker builds | |||
type DockerStrategyOptions struct { | |||
unversioned.TypeMeta |
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.
Why do these include TypeMeta
? Are you using them somewhere as a RawExtension
or a runtime.Object
directly?
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.
A couple reasons, none of which are important.
./hack/update-generated-deep-copies.sh
threw an error when it wasn't there.- I couldn't find a reason why/why not to have them, and I saw that many similar structs had it.
- Some structs that are created have no fields, which also caused
make update
to fail
I've been able to remove it from DockerStrategyOptions and BuildStrategyOptions, but not from the empty stucts.
@oatmealraisin lgtm, clean up whatever is causing the test failures and squash. @openshift/api-review need signoff. this is for 1.6. |
Squashed. Looks like there is a mix of flakes and stuff that is from the code, am working to resolve |
@bparees Tests passing now. I've added a Dockerfile to test/testdata FYI |
@openshift/api-review bump |
pkg/build/api/types.go
Outdated
@@ -911,6 +915,9 @@ type GenericWebHookEvent struct { | |||
|
|||
// Env contains additional environment variables you want to pass into a builder container | |||
Env []kapi.EnvVar | |||
|
|||
// StrategyOptions contains additional strategy-specific options for the build | |||
StrategyOptions *BuildStrategyOptions |
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.
I don't like the use of "options" - is there an example from elsewhere that had this? I don't know that this makes sense nested, it's just extra abstraction.
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.
yes, BinaryBuildRequestOptions and BuildLogOptions, in this file.
The nesting has value for options that are common across the strategies (if we had it to do over again, Env would probably go into BuildStrategyOptions), but i'm not going to fight unnesting it into an options field per strategy, as you suggest for the BuildRequest object below.
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.
Then DockerStrategy *DockerStrategyOptions
. We don't use Options
in any field names that I see and I'm not sure it adds anything.
Let's avoid nesting.
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.
DockerStrategy doesn't sound like a good name for a field that doesn't hold a DockerStrategy object. That is what i'd expect a field with that name to hold.
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.
@smarterclayton bump. i'm open to other naming suggestions but i don't want to just call it DockerStrategy.
pkg/build/api/types.go
Outdated
@@ -966,6 +987,9 @@ type BuildRequest struct { | |||
// TriggeredBy describes which triggers started the most recent update to the | |||
// buildconfig and contains information about those triggers. | |||
TriggeredBy []BuildTriggerCause | |||
|
|||
// StrategyOptions contains additional strategy-specific options for the build | |||
StrategyOptions *BuildStrategyOptions |
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.
This seems better as per strategy options:
DockerStrategy *DockerStrategyOptions
SourceStrategy *SourceStrategyOptions
However, this is really starting to fray the design - build requests was never intended to grow to match the build in complexity. The more we allow here the more we distract from Build as the intended unit of submission.
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.
w/o fundamentally changing how start-build works (to have it create a build object instead of a buildrequest object), I don't know how we get there at this point.
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.
It's fine for now.
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.
I've been implementing de-nesting this struct, but now anything that asks for a BuildStrategyOptions would need to ask for a SourceStrategyOptions, DockerStrategyOptions, etc. It's not an issue right now, but I think it will be a bit cumbersome in the future.
Maybe instead of having a containing struct (BuildStrategyOptions), we have an interface that each strategyoption implements?
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.
how would the strategies implement that interface? you'd have to introduce getters and it would have to be the same getters on every implementation, implying they have the same fields.
we can introduce wrapper structs if desired in the future for passing things between methods, they don't have to be part of the api though.
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.
true, sounds good
@smarterclayton @bparees I de-nested DockerStrategyArgs and re-generated everything. ptal? What is the decision on renaming DockerStrategyOptions |
I still prefer DockerStrategyOptions, or a compromise alternative, over DockerStrategy... so waiting on @smarterclayton to either suggest an alternative or overrule me. |
I split the PR into two commits for generated code for now, will squash before merge. This makes it easier for me to re-generate things. |
@openshift/api-review bump |
API approved |
@oatmealraisin squash |
This includes a generic BuildStrategyOptions that will allow us to add additional information to BuildRequest objects, such as BuildArgs for Docker strategies. Added support for Docker ARG values. Through start-build, new-build, and generic webhooks, users are now able to fill ARG values in Dockerfiles. For more information, see https://docs.docker.com/engine/reference/builder/#/arg For start-build, we add the BuildArgs to the DockerStrategyOptions of the BuildRequest. This field was added in an earlier commit to support this. For new-build, we add BuildArgs to the AppConfig, which is then added to a DockerStrategyOptions in buildPipeline(), and is added to the BuildConfig that is created. These BuildArgs will be consumed when the Build is triggered. For webhook, we added a BuildStrategyOptions to the GenericWebhookEvent object. This is consumed by the webhook code, and put into the resulting BuildRequest, similarly to start-build. Internally, the kapi.EnvVar BuildArgs are converted to docker.BuildArg before being consumed by the Docker client. Originally, we used docker.BuildArg throughout the code. However, due to Protobuf complications, it is easier to convert kapi.EnvVar's into docker.BuildArg when we need to.
@bparees Squashed |
[testextended][extended:core(builds)] |
Evaluated for origin testextended up to ce319b2 |
@bparees Thanks |
Evaluated for origin test up to ce319b2 |
continuous-integration/openshift-jenkins/testextended FAILURE (https://ci.openshift.redhat.com/jenkins/job/test_pr_origin_extended/1139/) (Base Commit: cb5d93e) (Extended Tests: core(builds)) |
the extended test failures look like all thin pool related issues which @csrwng is working on. |
Evaluated for origin merge up to ce319b2 |
continuous-integration/openshift-jenkins/test SUCCESS (https://ci.openshift.redhat.com/jenkins/job/test_pull_requests_origin_future/701/) (Base Commit: 0fa7a48) |
continuous-integration/openshift-jenkins/merge SUCCESS (https://ci.openshift.redhat.com/jenkins/job/test_pull_requests_origin_future/776/) (Base Commit: 79264a2) (Image: devenv-rhel7_6025) |
https://trello.com/c/Yh9BPAGi/1051-5-support-dockerfile-args-in-docker-build-techdebt-builds
Through start-build, users are now able to fill ARG values in
Dockerfiles. For more information, see
https://docs.docker.com/engine/reference/builder/#/arg
This adds
buildsArgs
to the DockerBuildStrategy definition, andBuildRequest
definition.@csrwng ptal?