Skip to content

Commit 901b905

Browse files
committed
client: NegotiateAPIVersion: do not ignore (connection) errors from Ping
NegotiateAPIVersion was ignoring errors returned by Ping. The intent here was to handle API responses from a daemon that may be in an unhealthy state, however this case is already handled by Ping itself. Ping only returns an error when either failing to connect to the API (daemon not running or permissions errors), or when failing to parse the API response. Neither of those should be ignored in this code, or considered a successful "ping", so update the code to return Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent 349abc6 commit 901b905

3 files changed

Lines changed: 22 additions & 2 deletions

File tree

client/client.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,11 @@ func (cli *Client) ClientVersion() string {
307307
// added (1.24).
308308
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
309309
if !cli.manualOverride {
310-
ping, _ := cli.Ping(ctx)
310+
ping, err := cli.Ping(ctx)
311+
if err != nil {
312+
// FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it.
313+
return
314+
}
311315
cli.negotiateAPIVersionPing(ping)
312316
}
313317
}

client/client_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,19 @@ func TestNegotiateAPVersionOverride(t *testing.T) {
354354
assert.Equal(t, client.ClientVersion(), expected)
355355
}
356356

357+
// TestNegotiateAPVersionConnectionFailure asserts that we do not modify the
358+
// API version when failing to connect.
359+
func TestNegotiateAPVersionConnectionFailure(t *testing.T) {
360+
const expected = "9.99"
361+
362+
client, err := NewClientWithOpts(WithHost("unix:///no-such-socket"))
363+
assert.NilError(t, err)
364+
365+
client.version = expected
366+
client.NegotiateAPIVersion(context.Background())
367+
assert.Equal(t, client.ClientVersion(), expected)
368+
}
369+
357370
func TestNegotiateAPIVersionAutomatic(t *testing.T) {
358371
var pingVersion string
359372
httpClient := newMockClient(func(req *http.Request) (*http.Response, error) {

client/ping.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ import (
1414
// Ping pings the server and returns the value of the "Docker-Experimental",
1515
// "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use
1616
// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported
17-
// by the daemon.
17+
// by the daemon. It ignores internal server errors returned by the API, which
18+
// may be returned if the daemon is in an unhealthy state, but returns errors
19+
// for other non-success status codes, failing to connect to the API, or failing
20+
// to parse the API response.
1821
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
1922
var ping types.Ping
2023

0 commit comments

Comments
 (0)