Skip to content

Commit 41da570

Browse files
committed
client: define default (and maximum) API version
With the client and API migrating to separate modules, users of the Client module may upgrade the API module to higher versions. Currently, the Client uses the API's Default version. While the version of the API module is allowed to be updated (following SemVer), we should not allow the Client to support higher API versions than it was written for. This patch introduces a DefaultAPIVersion in the client package that is used as default version of the API for the client to use. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 4c6f586 commit 41da570

File tree

4 files changed

+34
-19
lines changed

4 files changed

+34
-19
lines changed

client/client.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ import (
5353
"sync/atomic"
5454
"time"
5555

56-
"github.com/docker/docker/api"
5756
"github.com/docker/docker/api/types"
5857
"github.com/docker/docker/api/types/versions"
5958
"github.com/docker/go-connections/sockets"
@@ -91,6 +90,16 @@ import (
9190
// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569
9291
const DummyHost = "api.moby.localhost"
9392

93+
// DefaultAPIVersion is the highest REST API version supported by the client.
94+
// If API-version negotiation is enabled (see [WithAPIVersionNegotiation],
95+
// [Client.NegotiateAPIVersion]), the client may downgrade its API version.
96+
// Similarly, the [WithVersion] and [WithVersionFromEnv] allow overriding
97+
// the version.
98+
//
99+
// This version may be lower than the [api.DefaultVersion], which is the default
100+
// (and highest supported) version of the api library module used.
101+
const DefaultAPIVersion = "1.52"
102+
94103
// fallbackAPIVersion is the version to fallback to if API-version negotiation
95104
// fails. This version is the highest version of the API before API-version
96105
// negotiation was introduced. If negotiation fails (or no API version was
@@ -198,7 +207,7 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) {
198207
}
199208
c := &Client{
200209
host: DefaultDockerHost,
201-
version: api.DefaultVersion,
210+
version: DefaultAPIVersion,
202211
client: client,
203212
proto: hostURL.Scheme,
204213
addr: hostURL.Host,
@@ -381,7 +390,7 @@ func (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) {
381390

382391
// if the client is not initialized with a version, start with the latest supported version
383392
if cli.version == "" {
384-
cli.version = api.DefaultVersion
393+
cli.version = DefaultAPIVersion
385394
}
386395

387396
// if server version is lower than the client version, downgrade

client/client_test.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"strings"
1212
"testing"
1313

14-
"github.com/docker/docker/api"
1514
"github.com/docker/docker/api/types"
1615
"gotest.tools/v3/assert"
1716
is "gotest.tools/v3/assert/cmp"
@@ -30,7 +29,7 @@ func TestNewClientWithOpsFromEnv(t *testing.T) {
3029
{
3130
doc: "default api version",
3231
envs: map[string]string{},
33-
expectedVersion: api.DefaultVersion,
32+
expectedVersion: DefaultAPIVersion,
3433
},
3534
{
3635
doc: "invalid cert path",
@@ -44,23 +43,23 @@ func TestNewClientWithOpsFromEnv(t *testing.T) {
4443
envs: map[string]string{
4544
"DOCKER_CERT_PATH": "testdata/",
4645
},
47-
expectedVersion: api.DefaultVersion,
46+
expectedVersion: DefaultAPIVersion,
4847
},
4948
{
5049
doc: "default api version with cert path and tls verify",
5150
envs: map[string]string{
5251
"DOCKER_CERT_PATH": "testdata/",
5352
"DOCKER_TLS_VERIFY": "1",
5453
},
55-
expectedVersion: api.DefaultVersion,
54+
expectedVersion: DefaultAPIVersion,
5655
},
5756
{
5857
doc: "default api version with cert path and host",
5958
envs: map[string]string{
6059
"DOCKER_CERT_PATH": "testdata/",
6160
"DOCKER_HOST": "https://notaunixsocket",
6261
},
63-
expectedVersion: api.DefaultVersion,
62+
expectedVersion: DefaultAPIVersion,
6463
},
6564
{
6665
doc: "invalid docker host",
@@ -74,7 +73,7 @@ func TestNewClientWithOpsFromEnv(t *testing.T) {
7473
envs: map[string]string{
7574
"DOCKER_HOST": "invalid://url",
7675
},
77-
expectedVersion: api.DefaultVersion,
76+
expectedVersion: DefaultAPIVersion,
7877
},
7978
{
8079
doc: "override api version",
@@ -117,17 +116,17 @@ func TestGetAPIPath(t *testing.T) {
117116
}{
118117
{
119118
path: "/containers/json",
120-
expected: "/v" + api.DefaultVersion + "/containers/json",
119+
expected: "/v" + DefaultAPIVersion + "/containers/json",
121120
},
122121
{
123122
path: "/containers/json",
124123
query: url.Values{},
125-
expected: "/v" + api.DefaultVersion + "/containers/json",
124+
expected: "/v" + DefaultAPIVersion + "/containers/json",
126125
},
127126
{
128127
path: "/containers/json",
129128
query: url.Values{"s": []string{"c"}},
130-
expected: "/v" + api.DefaultVersion + "/containers/json?s=c",
129+
expected: "/v" + DefaultAPIVersion + "/containers/json?s=c",
131130
},
132131
{
133132
version: "1.22",
@@ -235,7 +234,7 @@ func TestNewClientWithOpsFromEnvSetsDefaultVersion(t *testing.T) {
235234

236235
client, err := NewClientWithOpts(FromEnv)
237236
assert.NilError(t, err)
238-
assert.Check(t, is.Equal(client.ClientVersion(), api.DefaultVersion))
237+
assert.Check(t, is.Equal(client.ClientVersion(), DefaultAPIVersion))
239238

240239
const expected = "1.22"
241240
t.Setenv("DOCKER_API_VERSION", expected)
@@ -375,8 +374,8 @@ func TestNegotiateAPIVersionAutomatic(t *testing.T) {
375374
)
376375
assert.NilError(t, err)
377376

378-
// Client defaults to use api.DefaultVersion before version-negotiation.
379-
expected := api.DefaultVersion
377+
// Client defaults to use DefaultAPIVersion before version-negotiation.
378+
expected := DefaultAPIVersion
380379
assert.Check(t, is.Equal(client.ClientVersion(), expected))
381380

382381
// First request should trigger negotiation
@@ -423,7 +422,7 @@ func TestCustomAPIVersion(t *testing.T) {
423422
}{
424423
{
425424
version: "",
426-
expected: api.DefaultVersion,
425+
expected: DefaultAPIVersion,
427426
},
428427
{
429428
version: "1.0",
@@ -435,7 +434,7 @@ func TestCustomAPIVersion(t *testing.T) {
435434
},
436435
{
437436
version: "v",
438-
expected: api.DefaultVersion,
437+
expected: DefaultAPIVersion,
439438
},
440439
{
441440
version: "v1.0",

client/options.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ func WithTLSClientConfigFromEnv() Opt {
194194
// WithVersion overrides the client version with the specified one. If an empty
195195
// version is provided, the value is ignored to allow version negotiation
196196
// (see [WithAPIVersionNegotiation]).
197+
//
198+
// WithVersion does not validate if the client supports the given version,
199+
// and callers should verify if the version is in the correct format and
200+
// lower than the maximum supported version as defined by [DefaultAPIVersion].
197201
func WithVersion(version string) Opt {
198202
return func(c *Client) error {
199203
if v := strings.TrimPrefix(version, "v"); v != "" {
@@ -208,6 +212,10 @@ func WithVersion(version string) Opt {
208212
// the DOCKER_API_VERSION ([EnvOverrideAPIVersion]) environment variable.
209213
// If DOCKER_API_VERSION is not set, or set to an empty value, the version
210214
// is not modified.
215+
//
216+
// WithVersion does not validate if the client supports the given version,
217+
// and callers should verify if the version is in the correct format and
218+
// lower than the maximum supported version as defined by [DefaultAPIVersion].
211219
func WithVersionFromEnv() Opt {
212220
return func(c *Client) error {
213221
return WithVersion(os.Getenv(EnvOverrideAPIVersion))(c)

client/options_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"testing"
88
"time"
99

10-
"github.com/docker/docker/api"
1110
"gotest.tools/v3/assert"
1211
is "gotest.tools/v3/assert/cmp"
1312
)
@@ -50,7 +49,7 @@ func TestOptionWithVersionFromEnv(t *testing.T) {
5049
c, err := NewClientWithOpts(WithVersionFromEnv())
5150
assert.NilError(t, err)
5251
assert.Check(t, c.client != nil)
53-
assert.Check(t, is.Equal(c.version, api.DefaultVersion))
52+
assert.Check(t, is.Equal(c.version, DefaultAPIVersion))
5453
assert.Check(t, is.Equal(c.manualOverride, false))
5554

5655
t.Setenv("DOCKER_API_VERSION", "2.9999")

0 commit comments

Comments
 (0)