client: VolumeInspect: add options struct

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-10-21 23:36:20 +02:00
parent 8f50d38231
commit e3c6dc2a91
11 changed files with 35 additions and 26 deletions

View File

@@ -194,7 +194,7 @@ type SystemAPIClient interface {
// VolumeAPIClient defines API client methods for the volumes
type VolumeAPIClient interface {
VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error)
VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error)
VolumeInspect(ctx context.Context, volumeID string, options VolumeInspectOptions) (VolumeInspectResult, error)
VolumeList(ctx context.Context, options VolumeListOptions) (VolumeListResult, error)
VolumeRemove(ctx context.Context, volumeID string, options VolumeRemoveOptions) error
VolumesPrune(ctx context.Context, opts VolumePruneOptions) (VolumePruneResult, error)

View File

@@ -6,6 +6,11 @@ import (
"github.com/moby/moby/api/types/volume"
)
// VolumeInspectOptions holds options for inspecting a volume.
type VolumeInspectOptions struct {
// Add future optional parameters here
}
// VolumeInspectResult holds the result from the [Client.VolumeInspect] method.
type VolumeInspectResult struct {
Raw []byte
@@ -13,7 +18,7 @@ type VolumeInspectResult struct {
}
// VolumeInspect returns the information about a specific volume in the docker host.
func (cli *Client) VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error) {
func (cli *Client) VolumeInspect(ctx context.Context, volumeID string, options VolumeInspectOptions) (VolumeInspectResult, error) {
volumeID, err := trimID("volume", volumeID)
if err != nil {
return VolumeInspectResult{}, err

View File

@@ -2,7 +2,6 @@ package client
import (
"bytes"
"context"
"encoding/json"
"errors"
"io"
@@ -19,7 +18,7 @@ func TestVolumeInspectError(t *testing.T) {
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err)
_, err = client.VolumeInspect(context.Background(), "nothing")
_, err = client.VolumeInspect(t.Context(), "nothing", VolumeInspectOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
}
@@ -27,7 +26,7 @@ func TestVolumeInspectNotFound(t *testing.T) {
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusNotFound, "Server error")))
assert.NilError(t, err)
_, err = client.VolumeInspect(context.Background(), "unknown")
_, err = client.VolumeInspect(t.Context(), "unknown", VolumeInspectOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
}
@@ -36,11 +35,11 @@ func TestVolumeInspectWithEmptyID(t *testing.T) {
return nil, errors.New("should not make request")
}))
assert.NilError(t, err)
_, err = client.VolumeInspect(context.Background(), "")
_, err = client.VolumeInspect(t.Context(), "", VolumeInspectOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
assert.Check(t, is.ErrorContains(err, "value is empty"))
_, err = client.VolumeInspect(context.Background(), " ")
_, err = client.VolumeInspect(t.Context(), " ", VolumeInspectOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
assert.Check(t, is.ErrorContains(err, "value is empty"))
}
@@ -68,7 +67,7 @@ func TestVolumeInspect(t *testing.T) {
}))
assert.NilError(t, err)
result, err := client.VolumeInspect(context.Background(), "volume_id")
result, err := client.VolumeInspect(t.Context(), "volume_id", VolumeInspectOptions{})
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(expected, result.Volume))
}

View File

@@ -1633,7 +1633,7 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
switch {
// Named volumes still exist after the container is removed
case tc.spec.Type == "volume" && tc.spec.Source != "":
_, err := apiclient.VolumeInspect(ctx, mountPoint.Name)
_, err := apiclient.VolumeInspect(ctx, mountPoint.Name, client.VolumeInspectOptions{})
assert.NilError(c, err)
// Bind mounts are never removed with the container
@@ -1641,7 +1641,7 @@ func (s *DockerAPISuite) TestContainersAPICreateMountsCreate(c *testing.T) {
// anonymous volumes are removed
default:
_, err := apiclient.VolumeInspect(ctx, mountPoint.Name)
_, err := apiclient.VolumeInspect(ctx, mountPoint.Name, client.VolumeInspectOptions{})
assert.Check(c, is.ErrorType(err, cerrdefs.IsNotFound))
}
})

View File

@@ -410,13 +410,13 @@ func TestContainerVolumeAnonymous(t *testing.T) {
assert.Check(t, is.Len(vol.Name, 64), "volume name should be 64 bytes (from stringid.GenerateRandomID())")
assert.Check(t, is.Equal(vol.Driver, volume.DefaultDriverName))
volInspect, err := apiClient.VolumeInspect(ctx, vol.Name)
res, err := apiClient.VolumeInspect(ctx, vol.Name, client.VolumeInspectOptions{})
assert.NilError(t, err)
// see [daemon.AnonymousLabel]; we don't want to import the daemon package here.
const expectedAnonymousLabel = "com.docker.volume.anonymous"
assert.Check(t, is.Contains(volInspect.Volume.Labels, expectedAnonymousLabel))
assert.Check(t, is.Equal(volInspect.Volume.Driver, volume.DefaultDriverName))
assert.Check(t, is.Contains(res.Volume.Labels, expectedAnonymousLabel))
assert.Check(t, is.Equal(res.Volume.Driver, volume.DefaultDriverName))
})
// Verify that specifying a custom driver is still taken into account.

View File

@@ -63,7 +63,7 @@ func TestRemoveContainerWithVolume(t *testing.T) {
assert.Check(t, is.Equal(1, len(ctrInspect.Mounts)))
volName := ctrInspect.Mounts[0].Name
_, err = apiClient.VolumeInspect(ctx, volName)
_, err = apiClient.VolumeInspect(ctx, volName, client.VolumeInspectOptions{})
assert.NilError(t, err)
err = apiClient.ContainerRemove(ctx, cID, client.ContainerRemoveOptions{
@@ -72,7 +72,7 @@ func TestRemoveContainerWithVolume(t *testing.T) {
})
assert.NilError(t, err)
_, err = apiClient.VolumeInspect(ctx, volName)
_, err = apiClient.VolumeInspect(ctx, volName, client.VolumeInspectOptions{})
assert.ErrorType(t, err, cerrdefs.IsNotFound, "Expected anonymous volume to be removed")
}

View File

@@ -569,7 +569,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
err = c.VolumeRemove(ctx, volName, client.VolumeRemoveOptions{})
assert.ErrorContains(t, err, "volume is in use")
_, err = c.VolumeInspect(ctx, volName)
_, err = c.VolumeInspect(ctx, volName, client.VolumeInspectOptions{})
assert.NilError(t, err)
})
}

View File

@@ -105,7 +105,7 @@ func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) {
assert.Assert(t, err != nil)
assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
_, err = c.VolumeInspect(ctx, "test")
_, err = c.VolumeInspect(ctx, "test", client.VolumeInspectOptions{})
assert.Assert(t, err != nil)
assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))

View File

@@ -164,25 +164,25 @@ func TestVolumesInspect(t *testing.T) {
assert.NilError(t, err)
v := created.Volume
inspected, err := apiClient.VolumeInspect(ctx, v.Name)
res, err := apiClient.VolumeInspect(ctx, v.Name, client.VolumeInspectOptions{})
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(inspected.Volume, v, cmpopts.EquateEmpty()))
assert.Check(t, is.DeepEqual(res.Volume, v, cmpopts.EquateEmpty()))
// comparing CreatedAt field time for the new volume to now. Truncate to 1 minute precision to avoid false positive
createdAt, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.Volume.CreatedAt))
createdAt, err := time.Parse(time.RFC3339, strings.TrimSpace(res.Volume.CreatedAt))
assert.NilError(t, err)
assert.Check(t, createdAt.Unix()-now.Unix() < 60, "CreatedAt (%s) exceeds creation time (%s) 60s", createdAt, now)
// update atime and mtime for the "_data" directory (which would happen during volume initialization)
modifiedAt := time.Now().Local().Add(5 * time.Hour)
err = os.Chtimes(inspected.Volume.Mountpoint, modifiedAt, modifiedAt)
err = os.Chtimes(res.Volume.Mountpoint, modifiedAt, modifiedAt)
assert.NilError(t, err)
inspected, err = apiClient.VolumeInspect(ctx, v.Name)
res, err = apiClient.VolumeInspect(ctx, v.Name, client.VolumeInspectOptions{})
assert.NilError(t, err)
createdAt2, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.Volume.CreatedAt))
createdAt2, err := time.Parse(time.RFC3339, strings.TrimSpace(res.Volume.CreatedAt))
assert.NilError(t, err)
// Check that CreatedAt didn't change after updating atime and mtime of the "_data" directory
@@ -280,7 +280,7 @@ func TestVolumePruneAnonymous(t *testing.T) {
assert.Check(t, is.Equal(len(report.VolumesDeleted), 1))
assert.Check(t, is.Equal(report.VolumesDeleted[0], anonV.Name))
_, err = apiClient.VolumeInspect(ctx, namedV.Name)
_, err = apiClient.VolumeInspect(ctx, namedV.Name, client.VolumeInspectOptions{})
assert.NilError(t, err)
// Prune all volumes

View File

@@ -194,7 +194,7 @@ type SystemAPIClient interface {
// VolumeAPIClient defines API client methods for the volumes
type VolumeAPIClient interface {
VolumeCreate(ctx context.Context, options VolumeCreateOptions) (VolumeCreateResult, error)
VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error)
VolumeInspect(ctx context.Context, volumeID string, options VolumeInspectOptions) (VolumeInspectResult, error)
VolumeList(ctx context.Context, options VolumeListOptions) (VolumeListResult, error)
VolumeRemove(ctx context.Context, volumeID string, options VolumeRemoveOptions) error
VolumesPrune(ctx context.Context, opts VolumePruneOptions) (VolumePruneResult, error)

View File

@@ -6,6 +6,11 @@ import (
"github.com/moby/moby/api/types/volume"
)
// VolumeInspectOptions holds options for inspecting a volume.
type VolumeInspectOptions struct {
// Add future optional parameters here
}
// VolumeInspectResult holds the result from the [Client.VolumeInspect] method.
type VolumeInspectResult struct {
Raw []byte
@@ -13,7 +18,7 @@ type VolumeInspectResult struct {
}
// VolumeInspect returns the information about a specific volume in the docker host.
func (cli *Client) VolumeInspect(ctx context.Context, volumeID string) (VolumeInspectResult, error) {
func (cli *Client) VolumeInspect(ctx context.Context, volumeID string, options VolumeInspectOptions) (VolumeInspectResult, error) {
volumeID, err := trimID("volume", volumeID)
if err != nil {
return VolumeInspectResult{}, err