Browse code

client/checkpoint_list: Wrap result in a struct

The CheckpointList method previously returned a raw slice of
checkpoint.Summary, which made it difficult to extend the API response
with additional metadata or fields in the future without breaking
backward compatibility.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>

Paweł Gronowski authored on 2025/09/26 22:25:53
Showing 6 changed files
... ...
@@ -2,8 +2,6 @@ package client
2 2
 
3 3
 import (
4 4
 	"context"
5
-
6
-	"github.com/moby/moby/api/types/checkpoint"
7 5
 )
8 6
 
9 7
 // CheckpointAPIClient defines API client methods for the checkpoints.
... ...
@@ -14,5 +12,5 @@ import (
14 14
 type CheckpointAPIClient interface {
15 15
 	CheckpointCreate(ctx context.Context, container string, options CheckpointCreateOptions) error
16 16
 	CheckpointDelete(ctx context.Context, container string, options CheckpointDeleteOptions) error
17
-	CheckpointList(ctx context.Context, container string, options CheckpointListOptions) ([]checkpoint.Summary, error)
17
+	CheckpointList(ctx context.Context, container string, options CheckpointListOptions) (CheckpointListResult, error)
18 18
 }
... ...
@@ -13,9 +13,14 @@ type CheckpointListOptions struct {
13 13
 	CheckpointDir string
14 14
 }
15 15
 
16
+// CheckpointListResult holds the result from the CheckpointList method.
17
+type CheckpointListResult struct {
18
+	Checkpoints []checkpoint.Summary
19
+}
20
+
16 21
 // CheckpointList returns the checkpoints of the given container in the docker host.
17
-func (cli *Client) CheckpointList(ctx context.Context, container string, options CheckpointListOptions) ([]checkpoint.Summary, error) {
18
-	var checkpoints []checkpoint.Summary
22
+func (cli *Client) CheckpointList(ctx context.Context, container string, options CheckpointListOptions) (CheckpointListResult, error) {
23
+	var out CheckpointListResult
19 24
 
20 25
 	query := url.Values{}
21 26
 	if options.CheckpointDir != "" {
... ...
@@ -25,9 +30,9 @@ func (cli *Client) CheckpointList(ctx context.Context, container string, options
25 25
 	resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil)
26 26
 	defer ensureReaderClosed(resp)
27 27
 	if err != nil {
28
-		return checkpoints, err
28
+		return out, err
29 29
 	}
30 30
 
31
-	err = json.NewDecoder(resp.Body).Decode(&checkpoints)
32
-	return checkpoints, err
31
+	err = json.NewDecoder(resp.Body).Decode(&out.Checkpoints)
32
+	return out, err
33 33
 }
... ...
@@ -48,9 +48,9 @@ func TestCheckpointList(t *testing.T) {
48 48
 	)
49 49
 	assert.NilError(t, err)
50 50
 
51
-	checkpoints, err := client.CheckpointList(context.Background(), "container_id", CheckpointListOptions{})
51
+	res, err := client.CheckpointList(context.Background(), "container_id", CheckpointListOptions{})
52 52
 	assert.NilError(t, err)
53
-	assert.Check(t, is.Len(checkpoints, 1))
53
+	assert.Check(t, is.Len(res.Checkpoints, 1))
54 54
 }
55 55
 
56 56
 func TestCheckpointListContainerNotFound(t *testing.T) {
... ...
@@ -77,10 +77,10 @@ func TestCheckpoint(t *testing.T) {
77 77
 	assert.NilError(t, err)
78 78
 	assert.Check(t, is.Equal(true, inspect.State.Running))
79 79
 
80
-	checkpoints, err := apiClient.CheckpointList(ctx, cID, client.CheckpointListOptions{})
80
+	res, err := apiClient.CheckpointList(ctx, cID, client.CheckpointListOptions{})
81 81
 	assert.NilError(t, err)
82
-	assert.Equal(t, len(checkpoints), 1)
83
-	assert.Equal(t, checkpoints[0].Name, "test")
82
+	assert.Equal(t, len(res.Checkpoints), 1)
83
+	assert.Equal(t, res.Checkpoints[0].Name, "test")
84 84
 
85 85
 	// Create a test file on a tmpfs mount.
86 86
 	cmd := []string{"touch", "/tmp/test-file"}
... ...
@@ -103,11 +103,11 @@ func TestCheckpoint(t *testing.T) {
103 103
 	assert.Check(t, is.Equal(false, inspect.State.Running))
104 104
 
105 105
 	// Check that both checkpoints are listed.
106
-	checkpoints, err = apiClient.CheckpointList(ctx, cID, client.CheckpointListOptions{})
106
+	res, err = apiClient.CheckpointList(ctx, cID, client.CheckpointListOptions{})
107 107
 	assert.NilError(t, err)
108
-	assert.Equal(t, len(checkpoints), 2)
108
+	assert.Equal(t, len(res.Checkpoints), 2)
109 109
 	cptNames := make([]string, 2)
110
-	for i, c := range checkpoints {
110
+	for i, c := range res.Checkpoints {
111 111
 		cptNames[i] = c.Name
112 112
 	}
113 113
 	sort.Strings(cptNames)
... ...
@@ -2,8 +2,6 @@ package client
2 2
 
3 3
 import (
4 4
 	"context"
5
-
6
-	"github.com/moby/moby/api/types/checkpoint"
7 5
 )
8 6
 
9 7
 // CheckpointAPIClient defines API client methods for the checkpoints.
... ...
@@ -14,5 +12,5 @@ import (
14 14
 type CheckpointAPIClient interface {
15 15
 	CheckpointCreate(ctx context.Context, container string, options CheckpointCreateOptions) error
16 16
 	CheckpointDelete(ctx context.Context, container string, options CheckpointDeleteOptions) error
17
-	CheckpointList(ctx context.Context, container string, options CheckpointListOptions) ([]checkpoint.Summary, error)
17
+	CheckpointList(ctx context.Context, container string, options CheckpointListOptions) (CheckpointListResult, error)
18 18
 }
... ...
@@ -13,9 +13,14 @@ type CheckpointListOptions struct {
13 13
 	CheckpointDir string
14 14
 }
15 15
 
16
+// CheckpointListResult holds the result from the CheckpointList method.
17
+type CheckpointListResult struct {
18
+	Checkpoints []checkpoint.Summary
19
+}
20
+
16 21
 // CheckpointList returns the checkpoints of the given container in the docker host.
17
-func (cli *Client) CheckpointList(ctx context.Context, container string, options CheckpointListOptions) ([]checkpoint.Summary, error) {
18
-	var checkpoints []checkpoint.Summary
22
+func (cli *Client) CheckpointList(ctx context.Context, container string, options CheckpointListOptions) (CheckpointListResult, error) {
23
+	var out CheckpointListResult
19 24
 
20 25
 	query := url.Values{}
21 26
 	if options.CheckpointDir != "" {
... ...
@@ -25,9 +30,9 @@ func (cli *Client) CheckpointList(ctx context.Context, container string, options
25 25
 	resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil)
26 26
 	defer ensureReaderClosed(resp)
27 27
 	if err != nil {
28
-		return checkpoints, err
28
+		return out, err
29 29
 	}
30 30
 
31
-	err = json.NewDecoder(resp.Body).Decode(&checkpoints)
32
-	return checkpoints, err
31
+	err = json.NewDecoder(resp.Body).Decode(&out.Checkpoints)
32
+	return out, err
33 33
 }