Browse code

client: rename/deprecate WithVersion, WithVersionFromEnv

Add WithAPIVersion and WithAPIVersionFromEnv to be more clear on
the intent, and to align with other related options and fields.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2025/11/13 00:39:20
Showing 34 changed files
... ...
@@ -104,9 +104,8 @@ const DummyHost = "api.moby.localhost"
104 104
 
105 105
 // MaxAPIVersion is the highest REST API version supported by the client.
106 106
 // If API-version negotiation is enabled (see [WithAPIVersionNegotiation],
107
-// [Client.NegotiateAPIVersion]), the client may downgrade its API version.
108
-// Similarly, the [WithVersion] and [WithVersionFromEnv] allow overriding
109
-// the version.
107
+// the client may downgrade its API version. Similarly, the [WithAPIVersion]
108
+// and [WithAPIVersionFromEnv] options allow overriding the version.
110 109
 //
111 110
 // This version may be lower than the version of the api library module used.
112 111
 const MaxAPIVersion = "1.52"
... ...
@@ -56,7 +56,7 @@ type Opt func(*clientConfig) error
56 56
 
57 57
 // FromEnv configures the client with values from environment variables. It
58 58
 // is the equivalent of using the [WithTLSClientConfigFromEnv], [WithHostFromEnv],
59
-// and [WithVersionFromEnv] options.
59
+// and [WithAPIVersionFromEnv] options.
60 60
 //
61 61
 // FromEnv uses the following environment variables:
62 62
 //
... ...
@@ -71,7 +71,7 @@ func FromEnv(c *clientConfig) error {
71 71
 	ops := []Opt{
72 72
 		WithTLSClientConfigFromEnv(),
73 73
 		WithHostFromEnv(),
74
-		WithVersionFromEnv(),
74
+		WithAPIVersionFromEnv(),
75 75
 	}
76 76
 	for _, op := range ops {
77 77
 		if err := op(c); err != nil {
... ...
@@ -241,14 +241,15 @@ func WithTLSClientConfigFromEnv() Opt {
241 241
 	}
242 242
 }
243 243
 
244
-// WithVersion overrides the client version with the specified one. If an empty
245
-// version is provided, the value is ignored to allow version negotiation
246
-// (see [WithAPIVersionNegotiation]).
244
+// WithAPIVersion overrides the client's API version with the specified one,
245
+// and disables API version negotiation. If an empty version is provided,
246
+// this option is ignored to allow version negotiation. The given version
247
+// should be formatted "<major>.<minor>" (for example, "1.52").
247 248
 //
248
-// WithVersion does not validate if the client supports the given version,
249
+// WithAPIVersion does not validate if the client supports the given version,
249 250
 // and callers should verify if the version is in the correct format and
250 251
 // lower than the maximum supported version as defined by [MaxAPIVersion].
251
-func WithVersion(version string) Opt {
252
+func WithAPIVersion(version string) Opt {
252 253
 	return func(c *clientConfig) error {
253 254
 		if v := strings.TrimPrefix(version, "v"); v != "" {
254 255
 			c.version = v
... ...
@@ -258,17 +259,34 @@ func WithVersion(version string) Opt {
258 258
 	}
259 259
 }
260 260
 
261
-// WithVersionFromEnv overrides the client version with the version specified in
261
+// WithVersion overrides the client version with the specified one.
262
+//
263
+// Deprecated: use [WithAPIVersion] instead.
264
+func WithVersion(version string) Opt {
265
+	return WithAPIVersion(version)
266
+}
267
+
268
+// WithAPIVersionFromEnv overrides the client version with the version specified in
262 269
 // the DOCKER_API_VERSION ([EnvOverrideAPIVersion]) environment variable.
263 270
 // If DOCKER_API_VERSION is not set, or set to an empty value, the version
264 271
 // is not modified.
265 272
 //
266
-// WithVersion does not validate if the client supports the given version,
273
+// WithAPIVersionFromEnv does not validate if the client supports the given version,
267 274
 // and callers should verify if the version is in the correct format and
268 275
 // lower than the maximum supported version as defined by [MaxAPIVersion].
276
+func WithAPIVersionFromEnv() Opt {
277
+	return func(c *clientConfig) error {
278
+		return WithAPIVersion(os.Getenv(EnvOverrideAPIVersion))(c)
279
+	}
280
+}
281
+
282
+// WithVersionFromEnv overrides the client version with the version specified in
283
+// the DOCKER_API_VERSION ([EnvOverrideAPIVersion]) environment variable.
284
+//
285
+// Deprecated: use [WithAPIVersionFromEnv] instead.
269 286
 func WithVersionFromEnv() Opt {
270 287
 	return func(c *clientConfig) error {
271
-		return WithVersion(os.Getenv(EnvOverrideAPIVersion))(c)
288
+		return WithAPIVersion(os.Getenv(EnvOverrideAPIVersion))(c)
272 289
 	}
273 290
 }
274 291
 
... ...
@@ -44,8 +44,8 @@ func TestOptionWithTimeout(t *testing.T) {
44 44
 	assert.Check(t, is.Equal(c.client.Timeout, timeout))
45 45
 }
46 46
 
47
-func TestOptionWithVersionFromEnv(t *testing.T) {
48
-	c, err := New(WithVersionFromEnv())
47
+func TestOptionAPIWithVersionFromEnv(t *testing.T) {
48
+	c, err := New(WithAPIVersionFromEnv())
49 49
 	assert.NilError(t, err)
50 50
 	assert.Check(t, c.client != nil)
51 51
 	assert.Check(t, is.Equal(c.version, MaxAPIVersion))
... ...
@@ -53,7 +53,7 @@ func TestOptionWithVersionFromEnv(t *testing.T) {
53 53
 
54 54
 	t.Setenv("DOCKER_API_VERSION", "2.9999")
55 55
 
56
-	c, err = New(WithVersionFromEnv())
56
+	c, err = New(WithAPIVersionFromEnv())
57 57
 	assert.NilError(t, err)
58 58
 	assert.Check(t, c.client != nil)
59 59
 	assert.Check(t, is.Equal(c.version, "2.9999"))
... ...
@@ -175,7 +175,7 @@ func TestGetAPIPath(t *testing.T) {
175 175
 	ctx := context.TODO()
176 176
 	for _, tc := range tests {
177 177
 		client, err := New(
178
-			WithVersion(tc.version),
178
+			WithAPIVersion(tc.version),
179 179
 			WithHost("tcp://localhost:2375"),
180 180
 		)
181 181
 		assert.NilError(t, err)
... ...
@@ -338,7 +338,7 @@ func TestNegotiateAPIVersion(t *testing.T) {
338 338
 				// Note that this check is redundant, as WithVersion() considers
339 339
 				// an empty version equivalent to "not setting a version", but
340 340
 				// doing this just to be explicit we are using the default.
341
-				opts = append(opts, WithVersion(tc.clientVersion))
341
+				opts = append(opts, WithAPIVersion(tc.clientVersion))
342 342
 			}
343 343
 			client, err := New(opts...)
344 344
 			assert.NilError(t, err)
... ...
@@ -422,7 +422,7 @@ func TestNegotiateAPIVersionAutomatic(t *testing.T) {
422 422
 // with an empty version string does still allow API-version negotiation
423 423
 func TestNegotiateAPIVersionWithEmptyVersion(t *testing.T) {
424 424
 	client, err := New(
425
-		WithVersion(""),
425
+		WithAPIVersion(""),
426 426
 		WithMockClient(mockResponse(http.StatusOK, http.Header{"Api-Version": []string{"1.50"}}, "OK")),
427 427
 	)
428 428
 	assert.NilError(t, err)
... ...
@@ -439,7 +439,7 @@ func TestNegotiateAPIVersionWithEmptyVersion(t *testing.T) {
439 439
 func TestNegotiateAPIVersionWithFixedVersion(t *testing.T) {
440 440
 	const customVersion = "1.50"
441 441
 	client, err := New(
442
-		WithVersion(customVersion),
442
+		WithAPIVersion(customVersion),
443 443
 		WithMockClient(mockResponse(http.StatusOK, http.Header{"Api-Version": []string{"1.49"}}, "OK")),
444 444
 	)
445 445
 	assert.NilError(t, err)
... ...
@@ -515,12 +515,12 @@ func TestCustomAPIVersion(t *testing.T) {
515 515
 	}
516 516
 	for _, tc := range tests {
517 517
 		t.Run(tc.doc, func(t *testing.T) {
518
-			client, err := New(WithVersion(tc.version))
518
+			client, err := New(WithAPIVersion(tc.version))
519 519
 			assert.NilError(t, err)
520 520
 			assert.Check(t, is.Equal(client.ClientVersion(), tc.expected))
521 521
 
522 522
 			t.Setenv(EnvOverrideAPIVersion, tc.expected)
523
-			client, err = New(WithVersionFromEnv())
523
+			client, err = New(WithAPIVersionFromEnv())
524 524
 			assert.NilError(t, err)
525 525
 			assert.Check(t, is.Equal(client.ClientVersion(), tc.expected))
526 526
 		})
... ...
@@ -13,7 +13,7 @@ const (
13 13
 	// be used to override the API version to use. Value must be
14 14
 	// formatted as MAJOR.MINOR, for example, "1.19".
15 15
 	//
16
-	// This env-var is read by [FromEnv] and [WithVersionFromEnv] and when set to a
16
+	// This env-var is read by [FromEnv] and [WithAPIVersionFromEnv] and when set to a
17 17
 	// non-empty value, takes precedence over API version negotiation.
18 18
 	//
19 19
 	// This environment variable should be used for debugging purposes only, as
... ...
@@ -116,7 +116,7 @@ func TestImageListWithSharedSize(t *testing.T) {
116 116
 			client, err := New(WithMockClient(func(req *http.Request) (*http.Response, error) {
117 117
 				query = req.URL.Query()
118 118
 				return mockResponse(http.StatusOK, nil, "[]")(req)
119
-			}), WithVersion(tc.version))
119
+			}), WithAPIVersion(tc.version))
120 120
 			assert.NilError(t, err)
121 121
 			_, err = client.ImageList(t.Context(), tc.options)
122 122
 			assert.NilError(t, err)
... ...
@@ -20,7 +20,7 @@ type PingOptions struct {
20 20
 	//
21 21
 	// If a manual override is in place, either through the "DOCKER_API_VERSION"
22 22
 	// ([EnvOverrideAPIVersion]) environment variable, or if the client is initialized
23
-	// with a fixed version ([WithVersion]), no negotiation is performed.
23
+	// with a fixed version ([WithAPIVersion]), no negotiation is performed.
24 24
 	//
25 25
 	// If the API server's ping response does not contain an API version, or if the
26 26
 	// client did not get a successful ping response, it assumes it is connected with
... ...
@@ -31,7 +31,7 @@ type PingOptions struct {
31 31
 	// ForceNegotiate forces the client to re-negotiate the API version, even if
32 32
 	// API-version negotiation already happened. This option cannot be
33 33
 	// used if the client is configured with a fixed version using (using
34
-	// [WithVersion] or [WithVersionFromEnv]).
34
+	// [WithAPIVersion] or [WithAPIVersionFromEnv]).
35 35
 	//
36 36
 	// This option has no effect if NegotiateAPIVersion is not set.
37 37
 	ForceNegotiate bool
... ...
@@ -199,7 +199,7 @@ func TestResponseErrors(t *testing.T) {
199 199
 				return mockResponse(http.StatusBadRequest, http.Header{"Content-Type": []string{tc.contentType}}, tc.response)(req)
200 200
 			}))
201 201
 			if tc.apiVersion != "" {
202
-				client, err = New(WithHTTPClient(client.client), WithVersion(tc.apiVersion))
202
+				client, err = New(WithHTTPClient(client.client), WithAPIVersion(tc.apiVersion))
203 203
 			}
204 204
 			assert.NilError(t, err)
205 205
 			_, err = client.Ping(t.Context(), PingOptions{})
... ...
@@ -133,7 +133,7 @@ func TestLegacyDiskUsage(t *testing.T) {
133 133
 	const legacyVersion = "1.51"
134 134
 	const expectedURL = "/system/df"
135 135
 	client, err := New(
136
-		WithVersion(legacyVersion),
136
+		WithAPIVersion(legacyVersion),
137 137
 		WithMockClient(func(req *http.Request) (*http.Response, error) {
138 138
 			if err := assertRequest(req, http.MethodGet, "/v"+legacyVersion+expectedURL); err != nil {
139 139
 				return nil, err
... ...
@@ -109,7 +109,7 @@ func (s *DockerAPISuite) TestAPIImagesSizeCompatibility(c *testing.T) {
109 109
 		assert.Assert(c, img.Size != int64(-1))
110 110
 	}
111 111
 
112
-	apiclient, err = client.New(client.FromEnv, client.WithVersion("v1.24"))
112
+	apiclient, err = client.New(client.FromEnv, client.WithAPIVersion("v1.24"))
113 113
 	assert.NilError(c, err)
114 114
 	defer apiclient.Close()
115 115
 
... ...
@@ -254,7 +254,7 @@ func waitInspect(name, expr, expected string, timeout time.Duration) error {
254 254
 
255 255
 func getInspectBody(t *testing.T, version, id string) json.RawMessage {
256 256
 	t.Helper()
257
-	apiClient, err := client.New(client.FromEnv, client.WithVersion(version))
257
+	apiClient, err := client.New(client.FromEnv, client.WithAPIVersion(version))
258 258
 	assert.NilError(t, err)
259 259
 	defer apiClient.Close()
260 260
 	inspect, err := apiClient.ContainerInspect(testutil.GetContext(t), id, client.ContainerInspectOptions{})
... ...
@@ -734,7 +734,7 @@ func TestCreateWithMultipleEndpointSettings(t *testing.T) {
734 734
 
735 735
 	for _, tc := range testcases {
736 736
 		t.Run("with API v"+tc.apiVersion, func(t *testing.T) {
737
-			apiClient, err := client.New(client.FromEnv, client.WithVersion(tc.apiVersion))
737
+			apiClient, err := client.New(client.FromEnv, client.WithAPIVersion(tc.apiVersion))
738 738
 			assert.NilError(t, err)
739 739
 
740 740
 			config := container.Config{
... ...
@@ -135,7 +135,7 @@ func TestInspectImageManifestPlatform(t *testing.T) {
135 135
 			assert.Check(t, is.DeepEqual(*inspect.ImageManifestDescriptor.Platform, hostPlatform))
136 136
 
137 137
 			t.Run("pre 1.48", func(t *testing.T) {
138
-				oldClient := request.NewAPIClient(t, client.WithVersion("1.47"))
138
+				oldClient := request.NewAPIClient(t, client.WithAPIVersion("1.47"))
139 139
 				inspect := container.Inspect(ctx, t, oldClient, ctr)
140 140
 				assert.Check(t, is.Nil(inspect.ImageManifestDescriptor))
141 141
 			})
... ...
@@ -328,7 +328,7 @@ func TestIpcModeOlderClient(t *testing.T) {
328 328
 	assert.Check(t, is.Equal(string(inspect.Container.HostConfig.IpcMode), "private"))
329 329
 
330 330
 	// main check: using older client creates "shareable" container
331
-	apiClient = request.NewAPIClient(t, client.WithVersion("1.39"))
331
+	apiClient = request.NewAPIClient(t, client.WithAPIVersion("1.39"))
332 332
 	cID = container.Create(ctx, t, apiClient, container.WithAutoRemove)
333 333
 
334 334
 	inspect, err = apiClient.ContainerInspect(ctx, cID, client.ContainerInspectOptions{})
... ...
@@ -61,7 +61,7 @@ func TestContainerList_Annotations(t *testing.T) {
61 61
 
62 62
 	for _, tc := range testcases {
63 63
 		t.Run(fmt.Sprintf("run with version v%s", tc.apiVersion), func(t *testing.T) {
64
-			apiClient := request.NewAPIClient(t, client.WithVersion(tc.apiVersion))
64
+			apiClient := request.NewAPIClient(t, client.WithAPIVersion(tc.apiVersion))
65 65
 			id := container.Create(ctx, t, apiClient, container.WithAnnotations(annotations))
66 66
 			defer container.Remove(ctx, t, apiClient, id, client.ContainerRemoveOptions{Force: true})
67 67
 
... ...
@@ -186,7 +186,7 @@ func TestContainerList_HealthSummary(t *testing.T) {
186 186
 
187 187
 	for _, tc := range testcases {
188 188
 		t.Run(fmt.Sprintf("run with version v%s", tc.apiVersion), func(t *testing.T) {
189
-			apiClient := request.NewAPIClient(t, client.WithVersion(tc.apiVersion))
189
+			apiClient := request.NewAPIClient(t, client.WithAPIVersion(tc.apiVersion))
190 190
 
191 191
 			cID := container.Run(ctx, t, apiClient, container.WithTty(true), container.WithWorkingDir("/foo"), func(c *container.TestContainerConfig) {
192 192
 				c.Config.Healthcheck = &containertypes.HealthConfig{
... ...
@@ -524,7 +524,7 @@ func TestContainerBindMountReadOnlyDefault(t *testing.T) {
524 524
 			skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), minDaemonVersion), "requires API v"+minDaemonVersion)
525 525
 
526 526
 			if tc.clientVersion != "" {
527
-				c, err := client.New(client.FromEnv, client.WithVersion(tc.clientVersion))
527
+				c, err := client.New(client.FromEnv, client.WithAPIVersion(tc.clientVersion))
528 528
 				assert.NilError(t, err, "failed to create client with version v%s", tc.clientVersion)
529 529
 				apiClient = c
530 530
 			}
... ...
@@ -139,7 +139,7 @@ func TestCgroupNamespacesRunOlderClient(t *testing.T) {
139 139
 	ctx := testutil.StartSpan(baseContext, t)
140 140
 
141 141
 	d := daemon.New(t, daemon.WithEnvVars("DOCKER_MIN_API_VERSION=1.39"), daemon.WithDefaultCgroupNamespaceMode("private"))
142
-	apiClient := d.NewClientT(t, client.WithVersion("1.39"))
142
+	apiClient := d.NewClientT(t, client.WithAPIVersion("1.39"))
143 143
 
144 144
 	d.StartWithBusybox(ctx, t)
145 145
 	defer d.Stop(t)
... ...
@@ -277,7 +277,7 @@ func TestMacAddressIsAppliedToMainNetworkWithShortID(t *testing.T) {
277 277
 	d.StartWithBusybox(ctx, t)
278 278
 	defer d.Stop(t)
279 279
 
280
-	apiClient := d.NewClientT(t, client.WithVersion("1.43"))
280
+	apiClient := d.NewClientT(t, client.WithAPIVersion("1.43"))
281 281
 
282 282
 	n := net.CreateNoError(ctx, t, apiClient, "testnet", net.WithIPAM("192.168.101.0/24", "192.168.101.1"))
283 283
 
... ...
@@ -309,7 +309,7 @@ func TestStaticIPOutsideSubpool(t *testing.T) {
309 309
 	d.StartWithBusybox(ctx, t)
310 310
 	defer d.Stop(t)
311 311
 
312
-	apiClient, err := client.New(client.FromEnv, client.WithVersion("1.43"))
312
+	apiClient, err := client.New(client.FromEnv, client.WithAPIVersion("1.43"))
313 313
 	assert.NilError(t, err)
314 314
 
315 315
 	const netname = "subnet-range"
... ...
@@ -153,7 +153,7 @@ func TestUpdatePidsLimit(t *testing.T) {
153 153
 
154 154
 	ctx := setupTest(t)
155 155
 	apiClient := testEnv.APIClient()
156
-	oldAPIClient := request.NewAPIClient(t, client.WithVersion("1.24"))
156
+	oldAPIClient := request.NewAPIClient(t, client.WithAPIVersion("1.24"))
157 157
 
158 158
 	intPtr := func(i int64) *int64 {
159 159
 		return &i
... ...
@@ -130,7 +130,7 @@ func TestInspectGraphDriverAPIBC(t *testing.T) {
130 130
 			d := daemon.New(t)
131 131
 			defer d.Stop(t)
132 132
 			d.StartWithBusybox(ctx, t, "--iptables=false", "--ip6tables=false", "--storage-driver="+tc.storageDriver)
133
-			c := d.NewClientT(t, client.WithVersion(tc.apiVersion))
133
+			c := d.NewClientT(t, client.WithAPIVersion(tc.apiVersion))
134 134
 
135 135
 			// Check selection of containerd / storage-driver worked.
136 136
 			info := d.Info(t)
... ...
@@ -253,7 +253,7 @@ func TestAPIImagesListManifests(t *testing.T) {
253 253
 
254 254
 	t.Run("unsupported before 1.47", func(t *testing.T) {
255 255
 		// TODO: Remove when MinAPIVersion >= 1.47
256
-		c := d.NewClientT(t, client.WithVersion("1.46"))
256
+		c := d.NewClientT(t, client.WithAPIVersion("1.46"))
257 257
 
258 258
 		imageList, err := c.ImageList(ctx, client.ImageListOptions{Manifests: true})
259 259
 		assert.NilError(t, err)
... ...
@@ -262,7 +262,7 @@ func TestAPIImagesListManifests(t *testing.T) {
262 262
 		assert.Check(t, is.Nil(imageList.Items[0].Manifests))
263 263
 	})
264 264
 
265
-	api147 := d.NewClientT(t, client.WithVersion("1.47"))
265
+	api147 := d.NewClientT(t, client.WithAPIVersion("1.47"))
266 266
 
267 267
 	t.Run("no manifests if not requested", func(t *testing.T) {
268 268
 		imageList, err := api147.ImageList(ctx, client.ImageListOptions{})
... ...
@@ -948,7 +948,7 @@ func TestEmptyPortBindingsBC(t *testing.T) {
948 948
 	defer d.Stop(t)
949 949
 
950 950
 	createInspect := func(t *testing.T, version string, pbs []networktypes.PortBinding) (networktypes.PortMap, []string) {
951
-		apiClient := d.NewClientT(t, client.WithVersion(version))
951
+		apiClient := d.NewClientT(t, client.WithAPIVersion(version))
952 952
 		defer apiClient.Close()
953 953
 
954 954
 		// Skip this subtest if the daemon doesn't support the client version.
... ...
@@ -1074,7 +1074,7 @@ func TestBridgeIPAMStatus(t *testing.T) {
1074 1074
 	d.StartWithBusybox(ctx, t)
1075 1075
 	defer d.Stop(t)
1076 1076
 
1077
-	c := d.NewClientT(t, client.WithVersion("1.52"))
1077
+	c := d.NewClientT(t, client.WithAPIVersion("1.52"))
1078 1078
 
1079 1079
 	checkSubnets := func(
1080 1080
 		netName string, want networktypes.SubnetStatuses,
... ...
@@ -1193,7 +1193,7 @@ func TestBridgeIPAMStatus(t *testing.T) {
1193 1193
 			},
1194 1194
 		})
1195 1195
 
1196
-		oldc := d.NewClientT(t, client.WithVersion("1.51"))
1196
+		oldc := d.NewClientT(t, client.WithAPIVersion("1.51"))
1197 1197
 		res, err := oldc.NetworkInspect(ctx, netName, client.NetworkInspectOptions{})
1198 1198
 		if assert.Check(t, err) {
1199 1199
 			assert.Check(t, res.Network.Status == nil, "expected nil Status with API version 1.51")
... ...
@@ -488,7 +488,7 @@ func TestIpvlanIPAM(t *testing.T) {
488 488
 	for _, tc := range tests {
489 489
 		t.Run(tc.name, func(t *testing.T) {
490 490
 			ctx := testutil.StartSpan(ctx, t)
491
-			c := d.NewClientT(t, client.WithVersion(tc.apiVersion))
491
+			c := d.NewClientT(t, client.WithAPIVersion(tc.apiVersion))
492 492
 
493 493
 			netOpts := []func(*client.NetworkCreateOptions){
494 494
 				net.WithIPvlan("", "l3"),
... ...
@@ -551,13 +551,13 @@ func TestIpvlanIPAM(t *testing.T) {
551 551
 			}
552 552
 			assert.Check(t, is.Equal(strings.TrimSpace(sysctlRes.Combined()), expDisableIPv6))
553 553
 
554
-			cc := d.NewClientT(t, client.WithVersion("1.52"))
554
+			cc := d.NewClientT(t, client.WithAPIVersion("1.52"))
555 555
 			res, err := cc.NetworkInspect(ctx, netName, client.NetworkInspectOptions{})
556 556
 			if assert.Check(t, err) && assert.Check(t, res.Network.Status != nil) {
557 557
 				assert.Check(t, is.DeepEqual(wantSubnetStatus, res.Network.Status.IPAM.Subnets, cmpopts.EquateEmpty()))
558 558
 			}
559 559
 			cc.Close()
560
-			cc = d.NewClientT(t, client.WithVersion("1.51"))
560
+			cc = d.NewClientT(t, client.WithAPIVersion("1.51"))
561 561
 			res, err = cc.NetworkInspect(ctx, netName, client.NetworkInspectOptions{})
562 562
 			assert.Check(t, err)
563 563
 			assert.Check(t, res.Network.Status == nil)
... ...
@@ -484,7 +484,7 @@ func TestMacvlanIPAM(t *testing.T) {
484 484
 	for _, tc := range testcases {
485 485
 		t.Run(tc.name, func(t *testing.T) {
486 486
 			ctx := testutil.StartSpan(ctx, t)
487
-			c := d.NewClientT(t, client.WithVersion(tc.apiVersion))
487
+			c := d.NewClientT(t, client.WithAPIVersion(tc.apiVersion))
488 488
 
489 489
 			netOpts := []func(*client.NetworkCreateOptions){
490 490
 				net.WithMacvlan(""),
... ...
@@ -554,13 +554,13 @@ func TestMacvlanIPAM(t *testing.T) {
554 554
 			}
555 555
 			assert.Check(t, is.Equal(strings.TrimSpace(sysctlRes.Combined()), expDisableIPv6))
556 556
 
557
-			cc := d.NewClientT(t, client.WithVersion("1.52"))
557
+			cc := d.NewClientT(t, client.WithAPIVersion("1.52"))
558 558
 			res, err := cc.NetworkInspect(ctx, netName, client.NetworkInspectOptions{})
559 559
 			if assert.Check(t, err) && assert.Check(t, res.Network.Status != nil) {
560 560
 				assert.Check(t, is.DeepEqual(wantSubnetStatus, res.Network.Status.IPAM.Subnets, cmpopts.EquateEmpty()))
561 561
 			}
562 562
 			_ = cc.Close()
563
-			cc = d.NewClientT(t, client.WithVersion("1.51"))
563
+			cc = d.NewClientT(t, client.WithAPIVersion("1.51"))
564 564
 			res, err = cc.NetworkInspect(ctx, netName, client.NetworkInspectOptions{})
565 565
 			assert.Check(t, err)
566 566
 			assert.Check(t, res.Network.Status == nil)
... ...
@@ -1126,7 +1126,7 @@ func TestDisableIPv4(t *testing.T) {
1126 1126
 
1127 1127
 	for _, tc := range tests {
1128 1128
 		t.Run(tc.name, func(t *testing.T) {
1129
-			c := d.NewClientT(t, client.WithVersion(tc.apiVersion))
1129
+			c := d.NewClientT(t, client.WithAPIVersion(tc.apiVersion))
1130 1130
 
1131 1131
 			const netName = "testnet"
1132 1132
 			network.CreateNoError(ctx, t, c, netName,
... ...
@@ -1277,7 +1277,7 @@ func TestSetInterfaceSysctl(t *testing.T) {
1277 1277
 	d.StartWithBusybox(ctx, t)
1278 1278
 	defer d.Stop(t)
1279 1279
 
1280
-	c := d.NewClientT(t, client.WithVersion("1.46"))
1280
+	c := d.NewClientT(t, client.WithAPIVersion("1.46"))
1281 1281
 	defer c.Close()
1282 1282
 
1283 1283
 	const scName = "net.ipv4.conf.eth0.forwarding"
... ...
@@ -43,7 +43,7 @@ func TestInfoFirewallBackend(t *testing.T) {
43 43
 
44 44
 	// Check FirewallBackend is omitted for API <= 1.48.
45 45
 	t.Run("api 1.48", func(t *testing.T) {
46
-		c148 := request.NewAPIClient(t, client.WithVersion("1.48"))
46
+		c148 := request.NewAPIClient(t, client.WithAPIVersion("1.48"))
47 47
 		result, err := c148.Info(ctx, client.InfoOptions{})
48 48
 		assert.NilError(t, err)
49 49
 		info148 := result.Info
... ...
@@ -194,9 +194,9 @@ func TestInspectCfgdMAC(t *testing.T) {
194 194
 
195 195
 			var copts []client.Opt
196 196
 			if tc.ctrWide {
197
-				copts = append(copts, client.WithVersion("1.43"))
197
+				copts = append(copts, client.WithAPIVersion("1.43"))
198 198
 			} else {
199
-				copts = append(copts, client.WithVersion("1.51"))
199
+				copts = append(copts, client.WithAPIVersion("1.51"))
200 200
 			}
201 201
 			c := d.NewClientT(t, copts...)
202 202
 			defer c.Close()
... ...
@@ -267,7 +267,7 @@ func TestWatchtowerCreate(t *testing.T) {
267 267
 	d.StartWithBusybox(ctx, t)
268 268
 	defer d.Stop(t)
269 269
 
270
-	c := d.NewClientT(t, client.WithVersion("1.25"))
270
+	c := d.NewClientT(t, client.WithAPIVersion("1.25"))
271 271
 	defer c.Close()
272 272
 
273 273
 	// Create a "/29" network, with a single address in iprange for IPAM to
... ...
@@ -30,7 +30,7 @@ func TestDockerNetworkConnectAliasPreV144(t *testing.T) {
30 30
 
31 31
 	d := swarm.NewSwarm(ctx, t, testEnv, daemon.WithEnvVars("DOCKER_MIN_API_VERSION=1.43"))
32 32
 	defer d.Stop(t)
33
-	apiClient := d.NewClientT(t, client.WithVersion("1.43"))
33
+	apiClient := d.NewClientT(t, client.WithAPIVersion("1.43"))
34 34
 	defer apiClient.Close()
35 35
 
36 36
 	name := t.Name() + "test-alias"
... ...
@@ -53,7 +53,7 @@ func TestAPIClientVersionOldNotSupported(t *testing.T) {
53 53
 	assert.NilError(t, err)
54 54
 	vMinInt--
55 55
 	version := fmt.Sprintf("%s.%d", major, vMinInt)
56
-	apiClient := request.NewAPIClient(t, client.WithVersion(version))
56
+	apiClient := request.NewAPIClient(t, client.WithAPIVersion(version))
57 57
 
58 58
 	expectedErrorMessage := fmt.Sprintf("Error response from daemon: client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", version, minApiVersion)
59 59
 	_, err = apiClient.ServerVersion(ctx, client.ServerVersionOptions{})
... ...
@@ -306,7 +306,7 @@ func TestVolumePruneAnonymous(t *testing.T) {
306 306
 	assert.Check(t, is.Equal(len(report.VolumesDeleted), 2))
307 307
 
308 308
 	// Validate that older API versions still have the old behavior of pruning all local volumes
309
-	clientOld, err := client.New(client.FromEnv, client.WithVersion("1.41"))
309
+	clientOld, err := client.New(client.FromEnv, client.WithAPIVersion("1.41"))
310 310
 	assert.NilError(t, err)
311 311
 	defer clientOld.Close()
312 312
 	assert.Equal(t, clientOld.ClientVersion(), "1.41")
... ...
@@ -104,9 +104,8 @@ const DummyHost = "api.moby.localhost"
104 104
 
105 105
 // MaxAPIVersion is the highest REST API version supported by the client.
106 106
 // If API-version negotiation is enabled (see [WithAPIVersionNegotiation],
107
-// [Client.NegotiateAPIVersion]), the client may downgrade its API version.
108
-// Similarly, the [WithVersion] and [WithVersionFromEnv] allow overriding
109
-// the version.
107
+// the client may downgrade its API version. Similarly, the [WithAPIVersion]
108
+// and [WithAPIVersionFromEnv] options allow overriding the version.
110 109
 //
111 110
 // This version may be lower than the version of the api library module used.
112 111
 const MaxAPIVersion = "1.52"
... ...
@@ -56,7 +56,7 @@ type Opt func(*clientConfig) error
56 56
 
57 57
 // FromEnv configures the client with values from environment variables. It
58 58
 // is the equivalent of using the [WithTLSClientConfigFromEnv], [WithHostFromEnv],
59
-// and [WithVersionFromEnv] options.
59
+// and [WithAPIVersionFromEnv] options.
60 60
 //
61 61
 // FromEnv uses the following environment variables:
62 62
 //
... ...
@@ -71,7 +71,7 @@ func FromEnv(c *clientConfig) error {
71 71
 	ops := []Opt{
72 72
 		WithTLSClientConfigFromEnv(),
73 73
 		WithHostFromEnv(),
74
-		WithVersionFromEnv(),
74
+		WithAPIVersionFromEnv(),
75 75
 	}
76 76
 	for _, op := range ops {
77 77
 		if err := op(c); err != nil {
... ...
@@ -241,14 +241,15 @@ func WithTLSClientConfigFromEnv() Opt {
241 241
 	}
242 242
 }
243 243
 
244
-// WithVersion overrides the client version with the specified one. If an empty
245
-// version is provided, the value is ignored to allow version negotiation
246
-// (see [WithAPIVersionNegotiation]).
244
+// WithAPIVersion overrides the client's API version with the specified one,
245
+// and disables API version negotiation. If an empty version is provided,
246
+// this option is ignored to allow version negotiation. The given version
247
+// should be formatted "<major>.<minor>" (for example, "1.52").
247 248
 //
248
-// WithVersion does not validate if the client supports the given version,
249
+// WithAPIVersion does not validate if the client supports the given version,
249 250
 // and callers should verify if the version is in the correct format and
250 251
 // lower than the maximum supported version as defined by [MaxAPIVersion].
251
-func WithVersion(version string) Opt {
252
+func WithAPIVersion(version string) Opt {
252 253
 	return func(c *clientConfig) error {
253 254
 		if v := strings.TrimPrefix(version, "v"); v != "" {
254 255
 			c.version = v
... ...
@@ -258,17 +259,34 @@ func WithVersion(version string) Opt {
258 258
 	}
259 259
 }
260 260
 
261
-// WithVersionFromEnv overrides the client version with the version specified in
261
+// WithVersion overrides the client version with the specified one.
262
+//
263
+// Deprecated: use [WithAPIVersion] instead.
264
+func WithVersion(version string) Opt {
265
+	return WithAPIVersion(version)
266
+}
267
+
268
+// WithAPIVersionFromEnv overrides the client version with the version specified in
262 269
 // the DOCKER_API_VERSION ([EnvOverrideAPIVersion]) environment variable.
263 270
 // If DOCKER_API_VERSION is not set, or set to an empty value, the version
264 271
 // is not modified.
265 272
 //
266
-// WithVersion does not validate if the client supports the given version,
273
+// WithAPIVersionFromEnv does not validate if the client supports the given version,
267 274
 // and callers should verify if the version is in the correct format and
268 275
 // lower than the maximum supported version as defined by [MaxAPIVersion].
276
+func WithAPIVersionFromEnv() Opt {
277
+	return func(c *clientConfig) error {
278
+		return WithAPIVersion(os.Getenv(EnvOverrideAPIVersion))(c)
279
+	}
280
+}
281
+
282
+// WithVersionFromEnv overrides the client version with the version specified in
283
+// the DOCKER_API_VERSION ([EnvOverrideAPIVersion]) environment variable.
284
+//
285
+// Deprecated: use [WithAPIVersionFromEnv] instead.
269 286
 func WithVersionFromEnv() Opt {
270 287
 	return func(c *clientConfig) error {
271
-		return WithVersion(os.Getenv(EnvOverrideAPIVersion))(c)
288
+		return WithAPIVersion(os.Getenv(EnvOverrideAPIVersion))(c)
272 289
 	}
273 290
 }
274 291
 
... ...
@@ -13,7 +13,7 @@ const (
13 13
 	// be used to override the API version to use. Value must be
14 14
 	// formatted as MAJOR.MINOR, for example, "1.19".
15 15
 	//
16
-	// This env-var is read by [FromEnv] and [WithVersionFromEnv] and when set to a
16
+	// This env-var is read by [FromEnv] and [WithAPIVersionFromEnv] and when set to a
17 17
 	// non-empty value, takes precedence over API version negotiation.
18 18
 	//
19 19
 	// This environment variable should be used for debugging purposes only, as
... ...
@@ -20,7 +20,7 @@ type PingOptions struct {
20 20
 	//
21 21
 	// If a manual override is in place, either through the "DOCKER_API_VERSION"
22 22
 	// ([EnvOverrideAPIVersion]) environment variable, or if the client is initialized
23
-	// with a fixed version ([WithVersion]), no negotiation is performed.
23
+	// with a fixed version ([WithAPIVersion]), no negotiation is performed.
24 24
 	//
25 25
 	// If the API server's ping response does not contain an API version, or if the
26 26
 	// client did not get a successful ping response, it assumes it is connected with
... ...
@@ -31,7 +31,7 @@ type PingOptions struct {
31 31
 	// ForceNegotiate forces the client to re-negotiate the API version, even if
32 32
 	// API-version negotiation already happened. This option cannot be
33 33
 	// used if the client is configured with a fixed version using (using
34
-	// [WithVersion] or [WithVersionFromEnv]).
34
+	// [WithAPIVersion] or [WithAPIVersionFromEnv]).
35 35
 	//
36 36
 	// This option has no effect if NegotiateAPIVersion is not set.
37 37
 	ForceNegotiate bool