-
Notifications
You must be signed in to change notification settings - Fork 18.6k
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
[Builder] Cleanup unnecessary mutate then revert of b.runConfig #32773
[Builder] Cleanup unnecessary mutate then revert of b.runConfig #32773
Conversation
c47106d
to
d6ff7b2
Compare
builder/dockerfile/internals.go
Outdated
if id == "" { | ||
cmd := b.runConfig.Cmd | ||
b.runConfig.Cmd = strslice.StrSlice(append(getShell(b.runConfig), "#(nop) ", comment)) | ||
defer func(cmd strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd) |
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 an inconsistency here. The other two places that added a #(nop)
comment did it with string concat, where as this adds it as another item in the slice.
I'm not sure if this will cause a cache miss, but at least it's consistent now.
d5a2cc4
to
510b888
Compare
builder/dockerfile/dispatchers.go
Outdated
// daemon.Commit() does a daemon.getContainer() to build the history, and | ||
// this modifies the config after the container has been run, changing it | ||
// to the updated Cmd | ||
// saveCmd |
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.
@tonistiigi this is a big surprise to me. I wonder if it is to you as well.
I guess this has been the case for a while, but nothing relied on it until #31584. It looks like there was lots of discussion about design and docs in that issue, but not much about the implementation.
This was relying of the fact ContainerCreate used the reference directly, so it was possible for the builder to modify runConfig
and it would change the config of the already created container!
I'm trying to find a way to implement this without this hack. I think Commit()
will need to change to accept more args? Maybe it should accept the history?
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.
Ok, I fixed this by adding a CreatedBy
field to ContainerCommitConfig
.
27cdc24
to
13b64e1
Compare
13b64e1
to
e1eebec
Compare
e1eebec
to
f87e629
Compare
4614f99
to
5f00665
Compare
caa55c2
to
ec27c6f
Compare
@@ -316,6 +316,10 @@ func (b *Builder) hasFromImage() bool { | |||
// | |||
// TODO: Remove? | |||
func BuildFromConfig(config *container.Config, changes []string) (*container.Config, error) { | |||
if len(changes) == 0 { | |||
return config, nil | |||
} |
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 change wasn't strictly necessary, but I think it helps clarify the behaviour of this function when changes is empty.
BuildFromConfig()
needs a much larger cleanup, but this PR isn't the place.
defer func(cmd strslice.StrSlice) { req.runConfig.Cmd = cmd }(cmd) | ||
// TODO: why is this done here. This seems to be done at random places all over | ||
// the builder | ||
req.runConfig.Image = req.builder.image |
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.
These TODO comments about setting runConfig.Image from b.Image are addressed in a follow up PR #32749
0f7bb0f
to
f452a2e
Compare
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.
LGTM
@@ -98,6 +99,9 @@ type ExecProcessConfig struct { | |||
type ContainerCommitConfig struct { | |||
types.ContainerCommitConfig | |||
Changes []string | |||
// TODO: ContainerConfig is only used by the dockerfile Builder, so remove it | |||
// once the Builder has been updated to use a different interface | |||
ContainerConfig *container.Config |
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.
Should we mark in the name that this should not be used by the API so we don't need to deprecate it? Or maybe it could be useful for docker commit
as well.
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 not actually part of the HTTP API (even though it's under api/types
). It's only in the interface between the router and the daemon. I don't think we'll have to deprecate it, we can just remove it at some point.
f452a2e
to
9f738cc
Compare
Instead of mutating and reverting, just create a copy and pass the copy around. Add a unit test for builder dispatcher.run Fix two test failures Fix image history by adding a CreatedBy to commit options. Previously the createdBy field was being created by modifying a reference to the runConfig that was held from when the container was created. Fix a test that expected a trailing slash. Previously the runConfig was being modified by container create. Now that we're creating a copy of runConfig instead of sharing a reference the runConfig retains the trailing slash. Signed-off-by: Daniel Nephin <dnephin@docker.com>
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.
LGTM 🐯
This PR changes how runConfig is modified by the builder dispatchers. Previously a single runConfig reference was passed around everywhere. This made it possible for the builder to modify (either accidentally or intentionally) the config of an already created container without using the established interface.
Instead of passing around a single reference, copies of runConfig are created when the dispatcher needs to make a temporary modification to runConfig. Creating a copy removes the need to setup a defer to revert the temporary modification. It also avoids any accidental modification of a container configuration.
ContainerConfig
was added to the commit options to support the existing behaviour ofdispatchers.run()
.Cmd
was modified after the container was created, and this change was picked up bycommit()
because of the shared reference. With this API change the behaviour is a lot more obvious.I think this changes makes the dispatchers and builder internals much easier to understand. It also removes some dead code from
run()
which wasn't obvious because of the clutter.