diff --git a/client/client_test.go b/client/client_test.go index 844197e2d3..c8bf9eae6f 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -437,19 +437,28 @@ func TestNegotiateAPIVersionWithEmptyVersion(t *testing.T) { // TestNegotiateAPIVersionWithFixedVersion asserts that initializing a client // with a fixed version disables API-version negotiation func TestNegotiateAPIVersionWithFixedVersion(t *testing.T) { - const customVersion = "1.50" + const ( + customVersion = "1.50" + pingVersion = "1.49" + ) client, err := New( WithAPIVersion(customVersion), - WithMockClient(mockResponse(http.StatusOK, http.Header{"Api-Version": []string{"1.49"}}, "OK")), + WithMockClient(mockResponse(http.StatusOK, http.Header{"Api-Version": []string{pingVersion}}, "OK")), ) assert.NilError(t, err) + _, err = client.Ping(t.Context(), PingOptions{ + NegotiateAPIVersion: true, + }) + assert.NilError(t, err) + assert.Check(t, is.Equal(client.ClientVersion(), customVersion)) + _, err = client.Ping(t.Context(), PingOptions{ NegotiateAPIVersion: true, ForceNegotiate: true, }) assert.NilError(t, err) - assert.Check(t, is.Equal(client.ClientVersion(), customVersion)) + assert.Check(t, is.Equal(client.ClientVersion(), pingVersion)) } func TestClientRedirect(t *testing.T) { diff --git a/client/ping.go b/client/ping.go index 688b9fa00c..3238f29567 100644 --- a/client/ping.go +++ b/client/ping.go @@ -29,9 +29,8 @@ type PingOptions struct { NegotiateAPIVersion bool // ForceNegotiate forces the client to re-negotiate the API version, even if - // API-version negotiation already happened. This option cannot be - // used if the client is configured with a fixed version using (using - // [WithAPIVersion] or [WithAPIVersionFromEnv]). + // API-version negotiation already happened or it the client is configured + // with a fixed version (using [WithAPIVersion] or [WithAPIVersionFromEnv]). // // This option has no effect if NegotiateAPIVersion is not set. ForceNegotiate bool @@ -72,7 +71,8 @@ type SwarmStatus struct { // for other non-success status codes, failing to connect to the API, or failing // to parse the API response. func (cli *Client) Ping(ctx context.Context, options PingOptions) (PingResult, error) { - if cli.manualOverride { + if (cli.manualOverride || cli.negotiated.Load()) && !options.ForceNegotiate { + // API version was already negotiated or manually set. return cli.ping(ctx) } if !options.NegotiateAPIVersion && !cli.negotiateVersion { diff --git a/vendor/github.com/moby/moby/client/ping.go b/vendor/github.com/moby/moby/client/ping.go index 688b9fa00c..3238f29567 100644 --- a/vendor/github.com/moby/moby/client/ping.go +++ b/vendor/github.com/moby/moby/client/ping.go @@ -29,9 +29,8 @@ type PingOptions struct { NegotiateAPIVersion bool // ForceNegotiate forces the client to re-negotiate the API version, even if - // API-version negotiation already happened. This option cannot be - // used if the client is configured with a fixed version using (using - // [WithAPIVersion] or [WithAPIVersionFromEnv]). + // API-version negotiation already happened or it the client is configured + // with a fixed version (using [WithAPIVersion] or [WithAPIVersionFromEnv]). // // This option has no effect if NegotiateAPIVersion is not set. ForceNegotiate bool @@ -72,7 +71,8 @@ type SwarmStatus struct { // for other non-success status codes, failing to connect to the API, or failing // to parse the API response. func (cli *Client) Ping(ctx context.Context, options PingOptions) (PingResult, error) { - if cli.manualOverride { + if (cli.manualOverride || cli.negotiated.Load()) && !options.ForceNegotiate { + // API version was already negotiated or manually set. return cli.ping(ctx) } if !options.NegotiateAPIVersion && !cli.negotiateVersion {