client: VolumeListResult: define local type

The `VolumeListResult.Items` field was a `volume.ListResponse`, which
in itself also had two slices (for volumes, and warnings). The Volumes
field contained a slice of pointers to Volumes.

This patch:

- Re-defines `ImageRemoveResult` as a distinct type, containing the
  content of the `volume.ListResponse.Volumes` and `.Warnings`.
- The `VolumeListResult` doesn't use a pointer for the volumes to make
  it slightly easier to deal with (possibly the API type could be
  changed as well, which could allow us to simplify the client code.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-10-24 11:55:05 +02:00
parent c246639baa
commit c6a45784f9
6 changed files with 55 additions and 16 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"net/url"
"slices"
"github.com/moby/moby/api/types/volume"
)
@@ -15,7 +16,11 @@ type VolumeListOptions struct {
// VolumeListResult holds the result from the [Client.VolumeList] method.
type VolumeListResult struct {
Items volume.ListResponse
// List of volumes.
Items []volume.Volume
// Warnings that occurred when fetching the list of volumes.
Warnings []string
}
// VolumeList returns the volumes configured in the docker host.
@@ -29,7 +34,22 @@ func (cli *Client) VolumeList(ctx context.Context, options VolumeListOptions) (V
return VolumeListResult{}, err
}
var res VolumeListResult
err = json.NewDecoder(resp.Body).Decode(&res.Items)
return res, err
var apiResp volume.ListResponse
err = json.NewDecoder(resp.Body).Decode(&apiResp)
if err != nil {
return VolumeListResult{}, err
}
res := VolumeListResult{
Items: make([]volume.Volume, 0, len(apiResp.Volumes)),
Warnings: slices.Clone(apiResp.Warnings),
}
for _, vol := range apiResp.Volumes {
if vol != nil {
res.Items = append(res.Items, *vol)
}
}
return res, nil
}

View File

@@ -64,6 +64,6 @@ func TestVolumeList(t *testing.T) {
result, err := client.VolumeList(context.Background(), VolumeListOptions{Filters: listCase.filters})
assert.NilError(t, err)
assert.Check(t, is.Len(result.Items.Volumes, 1))
assert.Check(t, is.Len(result.Items, 1))
}
}

View File

@@ -50,18 +50,17 @@ func TestVolumesCreateAndList(t *testing.T) {
res, err := apiClient.VolumeList(ctx, client.VolumeListOptions{})
assert.NilError(t, err)
assert.Assert(t, len(res.Items.Volumes) > 0)
assert.Assert(t, len(res.Items) > 0)
volumes := res.Items.Volumes[:0]
for _, v := range res.Items.Volumes {
volumes := res.Items[:0]
for _, v := range res.Items {
if v.Name == namedV.Name {
volumes = append(volumes, v)
}
}
assert.Check(t, is.Equal(len(volumes), 1))
assert.Check(t, volumes[0] != nil)
assert.Check(t, is.DeepEqual(*volumes[0], expected, cmpopts.EquateEmpty()))
assert.Check(t, is.DeepEqual(volumes[0], expected, cmpopts.EquateEmpty()))
}
func TestVolumesRemove(t *testing.T) {

View File

@@ -130,7 +130,7 @@ func deleteAllVolumes(ctx context.Context, t testing.TB, c client.VolumeAPIClien
res, err := c.VolumeList(ctx, client.VolumeListOptions{})
assert.Check(t, err, "failed to list volumes")
for _, v := range res.Items.Volumes {
for _, v := range res.Items {
if _, ok := protectedVolumes[v.Name]; ok {
continue
}

View File

@@ -231,7 +231,7 @@ func getExistingVolumes(ctx context.Context, t testing.TB, testEnv *Execution) [
assert.NilError(t, err, "failed to list volumes")
var volumes []string
for _, vol := range res.Items.Volumes {
for _, vol := range res.Items {
volumes = append(volumes, vol.Name)
}
return volumes

View File

@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"net/url"
"slices"
"github.com/moby/moby/api/types/volume"
)
@@ -15,7 +16,11 @@ type VolumeListOptions struct {
// VolumeListResult holds the result from the [Client.VolumeList] method.
type VolumeListResult struct {
Items volume.ListResponse
// List of volumes.
Items []volume.Volume
// Warnings that occurred when fetching the list of volumes.
Warnings []string
}
// VolumeList returns the volumes configured in the docker host.
@@ -29,7 +34,22 @@ func (cli *Client) VolumeList(ctx context.Context, options VolumeListOptions) (V
return VolumeListResult{}, err
}
var res VolumeListResult
err = json.NewDecoder(resp.Body).Decode(&res.Items)
return res, err
var apiResp volume.ListResponse
err = json.NewDecoder(resp.Body).Decode(&apiResp)
if err != nil {
return VolumeListResult{}, err
}
res := VolumeListResult{
Items: make([]volume.Volume, 0, len(apiResp.Volumes)),
Warnings: slices.Clone(apiResp.Warnings),
}
for _, vol := range apiResp.Volumes {
if vol != nil {
res.Items = append(res.Items, *vol)
}
}
return res, nil
}