Merge pull request #51210 from austinvazquez/refactor-client-volume

client/volume: refactor volume options and responses
This commit is contained in:
Sebastiaan van Stijn
2025-10-20 18:59:42 +02:00
committed by GitHub
20 changed files with 110 additions and 75 deletions

View File

@@ -415,8 +415,8 @@ func TestContainerVolumeAnonymous(t *testing.T) {
// 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.Labels, expectedAnonymousLabel))
assert.Check(t, is.Equal(volInspect.Driver, volume.DefaultDriverName))
assert.Check(t, is.Contains(volInspect.Volume.Labels, expectedAnonymousLabel))
assert.Check(t, is.Equal(volInspect.Volume.Driver, volume.DefaultDriverName))
})
// Verify that specifying a custom driver is still taken into account.

View File

@@ -567,7 +567,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
d.Restart(t, "--live-restore", "--iptables=false", "--ip6tables=false")
// Try to remove the volume
err = c.VolumeRemove(ctx, volName, false)
err = c.VolumeRemove(ctx, volName, client.VolumeRemoveOptions{})
assert.ErrorContains(t, err, "volume is in use")
_, err = c.VolumeInspect(ctx, volName)
@@ -626,7 +626,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
// Try to remove the volume
// This should fail since its used by a container
err = c.VolumeRemove(ctx, v.Name, false)
err = c.VolumeRemove(ctx, v.Name, client.VolumeRemoveOptions{})
assert.ErrorContains(t, err, "volume is in use")
t.Run("volume still mounted", func(t *testing.T) {
@@ -660,7 +660,7 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
assert.NilError(t, err)
// Now we should be able to remove the volume
err = c.VolumeRemove(ctx, v.Name, false)
err = c.VolumeRemove(ctx, v.Name, client.VolumeRemoveOptions{})
assert.NilError(t, err)
})

View File

@@ -102,7 +102,7 @@ func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) {
assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
// The plugin will block the command before it can determine the volume does not exist
err = c.VolumeRemove(ctx, "test", false)
err = c.VolumeRemove(ctx, "test", client.VolumeRemoveOptions{})
assert.Assert(t, err != nil)
assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))

View File

@@ -238,7 +238,7 @@ func setupTestVolume(t *testing.T, apiClient client.APIClient) string {
volumeName := t.Name() + "-volume"
err := apiClient.VolumeRemove(ctx, volumeName, true)
err := apiClient.VolumeRemove(ctx, volumeName, client.VolumeRemoveOptions{Force: true})
assert.NilError(t, err, "failed to clean volume")
_, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{

View File

@@ -47,8 +47,9 @@ func TestVolumesCreateAndList(t *testing.T) {
}
assert.Check(t, is.DeepEqual(vol, expected, cmpopts.EquateEmpty()))
volList, err := apiClient.VolumeList(ctx, client.VolumeListOptions{})
res, err := apiClient.VolumeList(ctx, client.VolumeListOptions{})
assert.NilError(t, err)
volList := res.List
assert.Assert(t, len(volList.Volumes) > 0)
volumes := volList.Volumes[:0]
@@ -76,7 +77,7 @@ func TestVolumesRemove(t *testing.T) {
vname := c.Mounts[0].Name
t.Run("volume in use", func(t *testing.T) {
err = apiClient.VolumeRemove(ctx, vname, false)
err = apiClient.VolumeRemove(ctx, vname, client.VolumeRemoveOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsConflict))
assert.Check(t, is.ErrorContains(err, "volume is in use"))
})
@@ -87,17 +88,17 @@ func TestVolumesRemove(t *testing.T) {
})
assert.NilError(t, err)
err = apiClient.VolumeRemove(ctx, vname, false)
err = apiClient.VolumeRemove(ctx, vname, client.VolumeRemoveOptions{})
assert.NilError(t, err)
})
t.Run("non-existing volume", func(t *testing.T) {
err = apiClient.VolumeRemove(ctx, "no_such_volume", false)
err = apiClient.VolumeRemove(ctx, "no_such_volume", client.VolumeRemoveOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
})
t.Run("non-existing volume force", func(t *testing.T) {
err = apiClient.VolumeRemove(ctx, "no_such_volume", true)
err = apiClient.VolumeRemove(ctx, "no_such_volume", client.VolumeRemoveOptions{Force: true})
assert.NilError(t, err)
})
}
@@ -128,7 +129,7 @@ func TestVolumesRemoveSwarmEnabled(t *testing.T) {
vname := c.Mounts[0].Name
t.Run("volume in use", func(t *testing.T) {
err = apiClient.VolumeRemove(ctx, vname, false)
err = apiClient.VolumeRemove(ctx, vname, client.VolumeRemoveOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsConflict))
assert.Check(t, is.ErrorContains(err, "volume is in use"))
})
@@ -139,17 +140,17 @@ func TestVolumesRemoveSwarmEnabled(t *testing.T) {
})
assert.NilError(t, err)
err = apiClient.VolumeRemove(ctx, vname, false)
err = apiClient.VolumeRemove(ctx, vname, client.VolumeRemoveOptions{})
assert.NilError(t, err)
})
t.Run("non-existing volume", func(t *testing.T) {
err = apiClient.VolumeRemove(ctx, "no_such_volume", false)
err = apiClient.VolumeRemove(ctx, "no_such_volume", client.VolumeRemoveOptions{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsNotFound))
})
t.Run("non-existing volume force", func(t *testing.T) {
err = apiClient.VolumeRemove(ctx, "no_such_volume", true)
err = apiClient.VolumeRemove(ctx, "no_such_volume", client.VolumeRemoveOptions{Force: true})
assert.NilError(t, err)
})
}
@@ -165,22 +166,22 @@ func TestVolumesInspect(t *testing.T) {
inspected, err := apiClient.VolumeInspect(ctx, vol.Name)
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(inspected, vol, cmpopts.EquateEmpty()))
assert.Check(t, is.DeepEqual(inspected.Volume, vol, 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.CreatedAt))
createdAt, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.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.Mountpoint, modifiedAt, modifiedAt)
err = os.Chtimes(inspected.Volume.Mountpoint, modifiedAt, modifiedAt)
assert.NilError(t, err)
inspected, err = apiClient.VolumeInspect(ctx, vol.Name)
assert.NilError(t, err)
createdAt2, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.CreatedAt))
createdAt2, err := time.Parse(time.RFC3339, strings.TrimSpace(inspected.Volume.CreatedAt))
assert.NilError(t, err)
// Check that CreatedAt didn't change after updating atime and mtime of the "_data" directory