-
Notifications
You must be signed in to change notification settings - Fork 18.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
Fix to address regression caused by PR 30897 #36316
Conversation
daemon/network.go
Outdated
return nil, errdefs.Forbidden(err) | ||
if runconfig.IsPreDefinedNetwork(create.Name) { | ||
logrus.Debugf("%s is a pre-defined network and cannot be created", create.Name) | ||
return nil, libnetwork.NetworkNameError(create.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.
I still think this should be wrapped in a errdefs.Forbidden(err)
, but callers that need to check the error for NetworkNameError
should check against errors.Cause(err)
In the same function below we do exact same logic. May I know is there any
advantage are we going to get by throwing errdefs.Forbidden instead of
NetworkNameError ?
I can go ahead and modify but just trying to understand if I am missing
anything with your suggestion.
Thanks in advance.
…On Thu, Feb 15, 2018 at 9:42 AM, Brian Goff ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In daemon/network.go
<#36316 (comment)>:
> @@ -267,9 +267,9 @@ func (daemon *Daemon) CreateNetwork(create types.NetworkCreateRequest) (*types.N
}
func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string, agent bool) (*types.NetworkCreateResponse, error) {
- if runconfig.IsPreDefinedNetwork(create.Name) && !agent {
- err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
- return nil, errdefs.Forbidden(err)
+ if runconfig.IsPreDefinedNetwork(create.Name) {
+ logrus.Debugf("%s is a pre-defined network and cannot be created", create.Name)
+ return nil, libnetwork.NetworkNameError(create.Name)
I still think this should be wrapped in a errdefs.Forbidden(err), but
callers that need to check the error for NetworkNameError should check
against errors.Cause(err)
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#36316 (review)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AKEKn92DPPcEFbVntH57NweWvS5KcrvTks5tVEJqgaJpZM4SGU62>
.
|
The error wrapping in this case is so that we return the correct error code to the API. |
|
That make sense. will change it as per your suggestion and let the caller
handle error case according to their requirement.
Thanks.
…On Thu, Feb 15, 2018 at 10:25 AM, Brian Goff ***@***.***> wrote:
04:57:16 FAIL: docker_api_network_test.go:241: DockerSuite.TestAPICreateDeletePredefinedNetworks
04:57:16
04:57:16 docker_api_network_test.go:243:
04:57:16 createDeletePredefinedNetwork(c, "bridge")
04:57:16 docker_api_network_test.go:323:
04:57:16 c.Assert(resp.StatusCode, checker.Equals, expectedStatusCode)
04:57:16 ... obtained int = 409
04:57:16 ... expected int = 403
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#36316 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AKEKnwDqCQfhNbd85pBw7MGJPXSpmPCmks5tVEx4gaJpZM4SGU62>
.
|
You mean 36247 ??? Yes.
…On Thu, Feb 15, 2018 at 11:20 AM, Sebastiaan van Stijn < ***@***.***> wrote:
@selansen <https://github.com/selansen> this fixes #36316
<#36316> correct?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#36316 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AKEKn-y8jexGn8FMZKLnex9w8Y_R96Dnks5tVFldgaJpZM4SGU62>
.
|
errr, copy/pasta error, yes, meant #36247 |
Yes. But looks like fix is causing existing test case failure. Let me dig
deeper while addressing cpuguy83 suggestion.
…On Thu, Feb 15, 2018 at 11:28 AM, Sebastiaan van Stijn < ***@***.***> wrote:
errr, copy/pasta error, yes, meant #36247
<#36247>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#36316 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AKEKnzzJJa-xgWXCu5EV94sFg7Rb456Tks5tVFtEgaJpZM4SGU62>
.
|
We also need a test to make sure similar regression does not happen. Maybe add a test to make sure attaching to |
@@ -153,6 +154,11 @@ func (c *containerAdapter) createNetworks(ctx context.Context) error { | |||
if _, ok := err.(libnetwork.NetworkNameError); ok { | |||
continue | |||
} | |||
// We will continue if CreateManagedNetwork returns forbidden error. | |||
// Other callers still can treat it as Error. | |||
if errdefs.IsForbidden(err) { |
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’ll have to give this more thinking (haven’t looked at what other situations return), but isn’t the case where we try to create a pre-defined network a conflict (i.e. the network already “exists”).
Forbidden sounds like “you don’t have access to this endpoint” (but you do). Other options would be “invalid argument” (passed value is not valid)
Just dumping my thinking here, so that I don’t forget 😄
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.
Conflict would imply that if the state changed then it would be possible to perform the action. In this case it is not allowed.
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.
Predefined networks are created when Daemon starts. When user creates service with predefined network, we know that network already exists and return saying you can't create. But service creation still can go ahead as the predefined network exists already. so we can ignore this error and continue in this scenario.
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.
Conflict would imply that if the state changed then it would be possible to perform the action. In this case it is not allowed.
Right, yes. I was looking at the 403 because I wondered if it could cause issues in situations where a 403 could also occur due to authentication issues to the API. A generic 400
(bad request - the name is reserved/invalid) could've been an option for that.
Looking at NetworkNameError
, I see that is also a "Forbidden" error; should we be more specific in this case, and check if it's actually a "forbidden" error, because it's a predefined network?
Given that we already walk different paths inside createNetwork()
if the caller is agent
, we could also use the agent
option to just return a nil
instead;
if runconfig.IsPreDefinedNetwork(create.Name) {
if agent {
return nil, nil
}
err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
return nil, errdefs.Forbidden(err)
}
I still believe instead of returning nil in case of agent is true, we let
the caller decides the error information. Because setupIngress() also calls
createNetwork with agent=true option.
…On Wed, Feb 21, 2018 at 10:38 AM, Sebastiaan van Stijn < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In daemon/cluster/executor/container/adapter.go
<#36316 (comment)>:
> @@ -153,6 +154,11 @@ func (c *containerAdapter) createNetworks(ctx context.Context) error {
if _, ok := err.(libnetwork.NetworkNameError); ok {
continue
}
+ // We will continue if CreateManagedNetwork returns forbidden error.
+ // Other callers still can treat it as Error.
+ if errdefs.IsForbidden(err) {
Conflict would imply that if the state changed then it would be possible
to perform the action. In this case it is not allowed.
Right, yes. I was looking at the 403 because I wondered if it could cause
issues in situations where a 403 could also occur due to authentication
issues to the API. A generic 400 (bad request - the name is
reserved/invalid) could've been an option for that.
Looking at NetworkNameError
<https://github.com/docker/libnetwork/blob/cb09a3770a365d8a4ed54f66e284041daf09ddef/error.go#L101-L108>,
I see that is also a "Forbidden" error; should we be more specific in this
case, and check if it's actually a "forbidden" error, because it's a
predefined network?
Given that we already walk different paths inside createNetwork() if the
caller is agent, we could also use the agent option to just return a nil
instead;
if runconfig.IsPreDefinedNetwork(create.Name) {
if agent {
return nil, nil
}
err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
return nil, errdefs.Forbidden(err)
}
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#36316 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AKEKn1dgfgbWifcKU0D_SJ5coI3v5QX4ks5tXDhrgaJpZM4SGU62>
.
|
Yeah not a big fan of the If we keep the check in the other location, should we be more specific though (as I mentioned above)? |
@thaJeztah , I can add new Forbidden Error type say "PredefinedNetworkExistError" and use it in all the places accordingly. Would that be ok with you? |
@selansen yes, if you can add an error so that we can distinguish if the error was due to "predefined network" and not some other "forbidden" error, that would be good. |
daemon/network.go
Outdated
@@ -267,7 +267,7 @@ func (daemon *Daemon) CreateNetwork(create types.NetworkCreateRequest) (*types.N | |||
} | |||
|
|||
func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string, agent bool) (*types.NetworkCreateResponse, error) { | |||
if runconfig.IsPreDefinedNetwork(create.Name) && !agent { | |||
if runconfig.IsPreDefinedNetwork(create.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.
Sorry for this late comment. Do we really need the IsPreDefinedNetwork
logic here? I was discussing with Flavio a bit and it seems the logic around daemon.GetNetworkByName
right below should be able to reject all PreDefined networks (besides user defined networks). This way, we will not even need IsPreDefinedNetwork
above.
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.
Just discussed a bit and we do need separate code paths for Pre-Defined vs User-defined as we do allow name conflicts for the latter category.
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.
Thats is what I h added originally. I was reluctant to change. But we need to be able to differentiate regular network name exist and predefined network exist . Review comments were asking me to be more specific to error reports to the callers. Hence I added new type .
Codecov Report
@@ Coverage Diff @@
## master #36316 +/- ##
=========================================
Coverage ? 34.89%
=========================================
Files ? 613
Lines ? 45413
Branches ? 0
=========================================
Hits ? 15847
Misses ? 27465
Partials ? 2101 |
@thaJeztah CI tests results looks good. only one test is failing . That is failing due to below test case. I looked into it. Its not related to above changes.18:25:05 FAIL: check_test.go:366: DockerSwarmSuite.TearDownTest |
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.
one nit/question, but otherwise looks good
daemon/network.go
Outdated
@@ -528,6 +537,7 @@ func (daemon *Daemon) deleteNetwork(nw libnetwork.Network, dynamic bool) error { | |||
if runconfig.IsPreDefinedNetwork(nw.Name()) && !dynamic { | |||
err := fmt.Errorf("%s is a pre-defined network and cannot be removed", nw.Name()) | |||
return errdefs.Forbidden(err) | |||
//return PredefinedNetworkError(nw.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.
Can you remove this? (or should this be a PredefinedNetworkError?)
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.
Let me remove it. I was testing it . but forgot to remove 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.
LGTM
@selansen looks like there's a golint failure:
|
return poll.Error(err) | ||
} | ||
|
||
if len(services) != int(instances) { |
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.
To make golint happy, change this to
if len(services) != int(instances) {
return poll.Continue("Service count at %d waiting for %d", len(services), instances)
}
return poll.Success()
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.
Already fixed golint issue and all test cases passed now.
With the inclusion of PR 30897, creating service for host network fails in 18.02. Modified IsPreDefinedNetwork check and return NetworkNameError instead of errdefs.Forbidden to address this issue Signed-off-by: selansen <[email protected]>
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 🐯
func serviceRunningCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result { | ||
return func(log poll.LogT) poll.Result { | ||
filter := filters.NewArgs() | ||
filter.Add("service", serviceID) |
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 filter
is not used. Was it supposed to be set in ServiceListOptions
?
You can build these inline now, which would prevent such an issue:
filters.NewArgs(filter.Arg("service", serviceID))
fixes #36247
With the inclusion of PR #30897, creating service for host network fails in 18.02. Modified IsPreDefinedNetwork check and return NetworkNameError instead of errdefs.Forbidden to address this issue
Signed-off-by: selansen [email protected]
- What I did
- How I did it
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)