Browse code

client: VolumeInspect: add options struct

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

Sebastiaan van Stijn authored on 2025/10/22 06:36:20
Showing 11 changed files
... ...
@@ -194,7 +194,7 @@ type SystemAPIClient interface {
194 194
 // VolumeAPIClient defines API client methods for the volumes
195 195
 type VolumeAPIClient interface {
196 196
 	VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error)
197
-	VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error)
197
+	VolumeInspect(ctx context.Context, volumeID string, options VolumeInspectOptions) (VolumeInspectResult, error)
198 198
 	VolumeList(ctx context.Context, options VolumeListOptions) (VolumeListResult, error)
199 199
 	VolumeRemove(ctx context.Context, volumeID string, options VolumeRemoveOptions) error
200 200
 	VolumesPrune(ctx context.Context, opts VolumePruneOptions) (VolumePruneResult, error)
... ...
@@ -6,6 +6,11 @@ import (
6 6
 	"github.com/moby/moby/api/types/volume"
7 7
 )
8 8
 
9
+// VolumeInspectOptions holds options for inspecting a volume.
10
+type VolumeInspectOptions struct {
11
+	// Add future optional parameters here
12
+}
13
+
9 14
 // VolumeInspectResult holds the result from the [Client.VolumeInspect] method.
10 15
 type VolumeInspectResult struct {
11 16
 	Raw    []byte
... ...
@@ -13,7 +18,7 @@ type VolumeInspectResult struct {
13 13
 }
14 14
 
15 15
 // VolumeInspect returns the information about a specific volume in the docker host.
16
-func (cli *Client) VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error) {
16
+func (cli *Client) VolumeInspect(ctx context.Context, volumeID string, options VolumeInspectOptions) (VolumeInspectResult, error) {
17 17
 	volumeID, err := trimID("volume", volumeID)
18 18
 	if err != nil {
19 19
 		return VolumeInspectResult{}, err
... ...
@@ -2,7 +2,6 @@ package client
2 2
 
3 3
 import (
4 4
 	"bytes"
5
-	"context"
6 5
 	"encoding/json"
7 6
 	"errors"
8 7
 	"io"
... ...
@@ -19,7 +18,7 @@ func TestVolumeInspectError(t *testing.T) {
19 19
 	client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
20 20
 	assert.NilError(t, err)
21 21
 
22
-	_, err = client.VolumeInspect(context.Background(), "nothing")
22
+	_, err = client.VolumeInspect(t.Context(), "nothing", VolumeInspectOptions{})
23 23
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
24 24
 }
25 25
 
... ...
@@ -27,7 +26,7 @@ func TestVolumeInspectNotFound(t *testing.T) {
27 27
 	client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusNotFound, "Server error")))
28 28
 	assert.NilError(t, err)
29 29
 
30
-	_, err = client.VolumeInspect(context.Background(), "unknown")
30
+	_, err = client.VolumeInspect(t.Context(), "unknown", VolumeInspectOptions{})
31 31
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
32 32
 }
33 33
 
... ...
@@ -36,11 +35,11 @@ func TestVolumeInspectWithEmptyID(t *testing.T) {
36 36
 		return nil, errors.New("should not make request")
37 37
 	}))
38 38
 	assert.NilError(t, err)
39
-	_, err = client.VolumeInspect(context.Background(), "")
39
+	_, err = client.VolumeInspect(t.Context(), "", VolumeInspectOptions{})
40 40
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
41 41
 	assert.Check(t, is.ErrorContains(err, "value is empty"))
42 42
 
43
-	_, err = client.VolumeInspect(context.Background(), "    ")
43
+	_, err = client.VolumeInspect(t.Context(), "    ", VolumeInspectOptions{})
44 44
 	assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
45 45
 	assert.Check(t, is.ErrorContains(err, "value is empty"))
46 46
 }
... ...
@@ -68,7 +67,7 @@ func TestVolumeInspect(t *testing.T) {
68 68
 	}))
69 69
 	assert.NilError(t, err)
70 70
 
71
-	result, err := client.VolumeInspect(context.Background(), "volume_id")
71
+	result, err := client.VolumeInspect(t.Context(), "volume_id", VolumeInspectOptions{})
72 72
 	assert.NilError(t, err)
73 73
 	assert.Check(t, is.DeepEqual(expected, result.Volume))
74 74
 }
... ...
@@ -1633,7 +1633,7 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
1633 1633
 			switch {
1634 1634
 			// Named volumes still exist after the container is removed
1635 1635
 			case tc.spec.Type == "volume" && tc.spec.Source != "":
1636
-				_, err := apiclient.VolumeInspect(ctx, mountPoint.Name)
1636
+				_, err := apiclient.VolumeInspect(ctx, mountPoint.Name, client.VolumeInspectOptions{})
1637 1637
 				assert.NilError(c, err)
1638 1638
 
1639 1639
 			// Bind mounts are never removed with the container
... ...
@@ -1641,7 +1641,7 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
1641 1641
 
1642 1642
 			// anonymous volumes are removed
1643 1643
 			default:
1644
-				_, err := apiclient.VolumeInspect(ctx, mountPoint.Name)
1644
+				_, err := apiclient.VolumeInspect(ctx, mountPoint.Name, client.VolumeInspectOptions{})
1645 1645
 				assert.Check(c, is.ErrorType(err, cerrdefs.IsNotFound))
1646 1646
 			}
1647 1647
 		})
... ...
@@ -410,13 +410,13 @@ func TestContainerVolumeAnonymous(t *testing.T) {
410 410
 		assert.Check(t, is.Len(vol.Name, 64), "volume name should be 64 bytes (from stringid.GenerateRandomID())")
411 411
 		assert.Check(t, is.Equal(vol.Driver, volume.DefaultDriverName))
412 412
 
413
-		volInspect, err := apiClient.VolumeInspect(ctx, vol.Name)
413
+		res, err := apiClient.VolumeInspect(ctx, vol.Name, client.VolumeInspectOptions{})
414 414
 		assert.NilError(t, err)
415 415
 
416 416
 		// see [daemon.AnonymousLabel]; we don't want to import the daemon package here.
417 417
 		const expectedAnonymousLabel = "com.docker.volume.anonymous"
418
-		assert.Check(t, is.Contains(volInspect.Volume.Labels, expectedAnonymousLabel))
419
-		assert.Check(t, is.Equal(volInspect.Volume.Driver, volume.DefaultDriverName))
418
+		assert.Check(t, is.Contains(res.Volume.Labels, expectedAnonymousLabel))
419
+		assert.Check(t, is.Equal(res.Volume.Driver, volume.DefaultDriverName))
420 420
 	})
421 421
 
422 422
 	// Verify that specifying a custom driver is still taken into account.
... ...
@@ -63,7 +63,7 @@ func TestRemoveContainerWithVolume(t *testing.T) {
63 63
 	assert.Check(t, is.Equal(1, len(ctrInspect.Mounts)))
64 64
 	volName := ctrInspect.Mounts[0].Name
65 65
 
66
-	_, err = apiClient.VolumeInspect(ctx, volName)
66
+	_, err = apiClient.VolumeInspect(ctx, volName, client.VolumeInspectOptions{})
67 67
 	assert.NilError(t, err)
68 68
 
69 69
 	err = apiClient.ContainerRemove(ctx, cID, client.ContainerRemoveOptions{
... ...
@@ -72,7 +72,7 @@ func TestRemoveContainerWithVolume(t *testing.T) {
72 72
 	})
73 73
 	assert.NilError(t, err)
74 74
 
75
-	_, err = apiClient.VolumeInspect(ctx, volName)
75
+	_, err = apiClient.VolumeInspect(ctx, volName, client.VolumeInspectOptions{})
76 76
 	assert.ErrorType(t, err, cerrdefs.IsNotFound, "Expected anonymous volume to be removed")
77 77
 }
78 78
 
... ...
@@ -569,7 +569,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
569 569
 			err = c.VolumeRemove(ctx, volName, client.VolumeRemoveOptions{})
570 570
 			assert.ErrorContains(t, err, "volume is in use")
571 571
 
572
-			_, err = c.VolumeInspect(ctx, volName)
572
+			_, err = c.VolumeInspect(ctx, volName, client.VolumeInspectOptions{})
573 573
 			assert.NilError(t, err)
574 574
 		})
575 575
 	}
... ...
@@ -105,7 +105,7 @@ func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) {
105 105
 	assert.Assert(t, err != nil)
106 106
 	assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
107 107
 
108
-	_, err = c.VolumeInspect(ctx, "test")
108
+	_, err = c.VolumeInspect(ctx, "test", client.VolumeInspectOptions{})
109 109
 	assert.Assert(t, err != nil)
110 110
 	assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
111 111
 
... ...
@@ -164,25 +164,25 @@ func TestVolumesInspect(t *testing.T) {
164 164
 	assert.NilError(t, err)
165 165
 	v := created.Volume
166 166
 
167
-	inspected, err := apiClient.VolumeInspect(ctx, v.Name)
167
+	res, err := apiClient.VolumeInspect(ctx, v.Name, client.VolumeInspectOptions{})
168 168
 	assert.NilError(t, err)
169 169
 
170
-	assert.Check(t, is.DeepEqual(inspected.Volume, v, cmpopts.EquateEmpty()))
170
+	assert.Check(t, is.DeepEqual(res.Volume, v, cmpopts.EquateEmpty()))
171 171
 
172 172
 	// comparing CreatedAt field time for the new volume to now. Truncate to 1 minute precision to avoid false positive
173
-	createdAt, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.Volume.CreatedAt))
173
+	createdAt, err := time.Parse(time.RFC3339, strings.TrimSpace(res.Volume.CreatedAt))
174 174
 	assert.NilError(t, err)
175 175
 	assert.Check(t, createdAt.Unix()-now.Unix() < 60, "CreatedAt (%s) exceeds creation time (%s) 60s", createdAt, now)
176 176
 
177 177
 	// update atime and mtime for the "_data" directory (which would happen during volume initialization)
178 178
 	modifiedAt := time.Now().Local().Add(5 * time.Hour)
179
-	err = os.Chtimes(inspected.Volume.Mountpoint, modifiedAt, modifiedAt)
179
+	err = os.Chtimes(res.Volume.Mountpoint, modifiedAt, modifiedAt)
180 180
 	assert.NilError(t, err)
181 181
 
182
-	inspected, err = apiClient.VolumeInspect(ctx, v.Name)
182
+	res, err = apiClient.VolumeInspect(ctx, v.Name, client.VolumeInspectOptions{})
183 183
 	assert.NilError(t, err)
184 184
 
185
-	createdAt2, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.Volume.CreatedAt))
185
+	createdAt2, err := time.Parse(time.RFC3339, strings.TrimSpace(res.Volume.CreatedAt))
186 186
 	assert.NilError(t, err)
187 187
 
188 188
 	// Check that CreatedAt didn't change after updating atime and mtime of the "_data" directory
... ...
@@ -280,7 +280,7 @@ func TestVolumePruneAnonymous(t *testing.T) {
280 280
 	assert.Check(t, is.Equal(len(report.VolumesDeleted), 1))
281 281
 	assert.Check(t, is.Equal(report.VolumesDeleted[0], anonV.Name))
282 282
 
283
-	_, err = apiClient.VolumeInspect(ctx, namedV.Name)
283
+	_, err = apiClient.VolumeInspect(ctx, namedV.Name, client.VolumeInspectOptions{})
284 284
 	assert.NilError(t, err)
285 285
 
286 286
 	// Prune all volumes
... ...
@@ -194,7 +194,7 @@ type SystemAPIClient interface {
194 194
 // VolumeAPIClient defines API client methods for the volumes
195 195
 type VolumeAPIClient interface {
196 196
 	VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error)
197
-	VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error)
197
+	VolumeInspect(ctx context.Context, volumeID string, options VolumeInspectOptions) (VolumeInspectResult, error)
198 198
 	VolumeList(ctx context.Context, options VolumeListOptions) (VolumeListResult, error)
199 199
 	VolumeRemove(ctx context.Context, volumeID string, options VolumeRemoveOptions) error
200 200
 	VolumesPrune(ctx context.Context, opts VolumePruneOptions) (VolumePruneResult, error)
... ...
@@ -6,6 +6,11 @@ import (
6 6
 	"github.com/moby/moby/api/types/volume"
7 7
 )
8 8
 
9
+// VolumeInspectOptions holds options for inspecting a volume.
10
+type VolumeInspectOptions struct {
11
+	// Add future optional parameters here
12
+}
13
+
9 14
 // VolumeInspectResult holds the result from the [Client.VolumeInspect] method.
10 15
 type VolumeInspectResult struct {
11 16
 	Raw    []byte
... ...
@@ -13,7 +18,7 @@ type VolumeInspectResult struct {
13 13
 }
14 14
 
15 15
 // VolumeInspect returns the information about a specific volume in the docker host.
16
-func (cli *Client) VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error) {
16
+func (cli *Client) VolumeInspect(ctx context.Context, volumeID string, options VolumeInspectOptions) (VolumeInspectResult, error) {
17 17
 	volumeID, err := trimID("volume", volumeID)
18 18
 	if err != nil {
19 19
 		return VolumeInspectResult{}, err