mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Merge pull request #51285 from thaJeztah/client_fixes
client: assorted fixes and refactor
This commit is contained in:
@@ -26,7 +26,7 @@ type ExecCreateOptions struct {
|
||||
|
||||
// ExecCreateResult holds the result of creating a container exec.
|
||||
type ExecCreateResult struct {
|
||||
container.ExecCreateResponse
|
||||
ID string
|
||||
}
|
||||
|
||||
// ExecCreate creates a new exec configuration to run an exec process.
|
||||
@@ -58,7 +58,7 @@ func (cli *Client) ExecCreate(ctx context.Context, containerID string, options E
|
||||
|
||||
var response container.ExecCreateResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||
return ExecCreateResult{ExecCreateResponse: response}, err
|
||||
return ExecCreateResult{ID: response.ID}, err
|
||||
}
|
||||
|
||||
type execStartAttachOptions struct {
|
||||
@@ -127,26 +127,21 @@ func (cli *Client) ExecAttach(ctx context.Context, execID string, options ExecAt
|
||||
return ExecAttachResult{HijackedResponse: response}, err
|
||||
}
|
||||
|
||||
// ExecInspect holds information returned by exec inspect.
|
||||
//
|
||||
// It provides a subset of the information included in [container.ExecInspectResponse].
|
||||
//
|
||||
// TODO(thaJeztah): include all fields of [container.ExecInspectResponse] ?
|
||||
type ExecInspect struct {
|
||||
ExecID string `json:"ID"`
|
||||
ContainerID string `json:"ContainerID"`
|
||||
Running bool `json:"Running"`
|
||||
ExitCode int `json:"ExitCode"`
|
||||
Pid int `json:"Pid"`
|
||||
}
|
||||
|
||||
// ExecInspectOptions holds options for inspecting a container exec.
|
||||
type ExecInspectOptions struct {
|
||||
}
|
||||
|
||||
// ExecInspectResult holds the result of inspecting a container exec.
|
||||
//
|
||||
// It provides a subset of the information included in [container.ExecInspectResponse].
|
||||
//
|
||||
// TODO(thaJeztah): include all fields of [container.ExecInspectResponse] ?
|
||||
type ExecInspectResult struct {
|
||||
ExecInspect
|
||||
ID string
|
||||
ContainerID string
|
||||
Running bool
|
||||
ExitCode int
|
||||
PID int
|
||||
}
|
||||
|
||||
// ExecInspect returns information about a specific exec process on the docker host.
|
||||
@@ -168,11 +163,11 @@ func (cli *Client) ExecInspect(ctx context.Context, execID string, options ExecI
|
||||
ec = *response.ExitCode
|
||||
}
|
||||
|
||||
return ExecInspectResult{ExecInspect: ExecInspect{
|
||||
ExecID: response.ID,
|
||||
return ExecInspectResult{
|
||||
ID: response.ID,
|
||||
ContainerID: response.ContainerID,
|
||||
Running: response.Running,
|
||||
ExitCode: ec,
|
||||
Pid: response.Pid,
|
||||
}}, nil
|
||||
PID: response.Pid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -68,11 +68,11 @@ func TestExecCreate(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
r, err := client.ExecCreate(context.Background(), "container_id", ExecCreateOptions{
|
||||
res, err := client.ExecCreate(context.Background(), "container_id", ExecCreateOptions{
|
||||
User: "user",
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(r.ID, "exec_id"))
|
||||
assert.Check(t, is.Equal(res.ID, "exec_id"))
|
||||
}
|
||||
|
||||
func TestExecStartError(t *testing.T) {
|
||||
@@ -141,6 +141,6 @@ func TestExecInspect(t *testing.T) {
|
||||
|
||||
inspect, err := client.ExecInspect(context.Background(), "exec_id", ExecInspectOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(inspect.ExecID, "exec_id"))
|
||||
assert.Check(t, is.Equal(inspect.ID, "exec_id"))
|
||||
assert.Check(t, is.Equal(inspect.ContainerID, "container_id"))
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@ func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, re
|
||||
if err != nil {
|
||||
return ImageImportResult{}, err
|
||||
}
|
||||
return ImageImportResult{body: resp.Body}, nil
|
||||
return ImageImportResult{rc: resp.Body}, nil
|
||||
}
|
||||
|
||||
@@ -20,16 +20,19 @@ type ImageImportOptions struct {
|
||||
|
||||
// ImageImportResult holds the response body returned by the daemon for image import.
|
||||
type ImageImportResult struct {
|
||||
body io.ReadCloser
|
||||
rc io.ReadCloser
|
||||
}
|
||||
|
||||
func (r ImageImportResult) Read(p []byte) (n int, err error) {
|
||||
return r.body.Read(p)
|
||||
if r.rc == nil {
|
||||
return 0, io.EOF
|
||||
}
|
||||
return r.rc.Read(p)
|
||||
}
|
||||
|
||||
func (r ImageImportResult) Close() error {
|
||||
if r.body == nil {
|
||||
if r.rc == nil {
|
||||
return nil
|
||||
}
|
||||
return r.body.Close()
|
||||
return r.rc.Close()
|
||||
}
|
||||
|
||||
@@ -35,5 +35,5 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options Imag
|
||||
|
||||
var dels []image.DeleteResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&dels)
|
||||
return ImageRemoveResult{Deleted: dels}, err
|
||||
return ImageRemoveResult{Items: dels}, err
|
||||
}
|
||||
|
||||
@@ -14,5 +14,5 @@ type ImageRemoveOptions struct {
|
||||
|
||||
// ImageRemoveResult holds the delete responses returned by the daemon.
|
||||
type ImageRemoveResult struct {
|
||||
Deleted []image.DeleteResponse
|
||||
Items []image.DeleteResponse
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ func TestImageRemove(t *testing.T) {
|
||||
opts.Platforms = []ocispec.Platform{*removeCase.platform}
|
||||
}
|
||||
|
||||
imageDeletes, err := client.ImageRemove(context.Background(), "image_id", opts)
|
||||
res, err := client.ImageRemove(context.Background(), "image_id", opts)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Len(imageDeletes.Deleted, 2))
|
||||
assert.Check(t, is.Len(res.Items, 2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ import (
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// NodeInspectOptions holds parameters to inspect nodes with.
|
||||
type NodeInspectOptions struct{}
|
||||
|
||||
type NodeInspectResult struct {
|
||||
Node swarm.Node
|
||||
Raw []byte
|
||||
|
||||
@@ -8,6 +8,11 @@ import (
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// NodeListOptions holds parameters to list nodes with.
|
||||
type NodeListOptions struct {
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
type NodeListResult struct {
|
||||
Items []swarm.Node
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// NodeRemoveOptions holds parameters to remove nodes with.
|
||||
type NodeRemoveOptions struct {
|
||||
Force bool
|
||||
}
|
||||
type NodeRemoveResult struct{}
|
||||
|
||||
// NodeRemove removes a Node.
|
||||
|
||||
@@ -3,8 +3,16 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// NodeUpdateOptions holds parameters to update nodes with.
|
||||
type NodeUpdateOptions struct {
|
||||
Version swarm.Version
|
||||
Spec swarm.NodeSpec
|
||||
}
|
||||
|
||||
type NodeUpdateResult struct{}
|
||||
|
||||
// NodeUpdate updates a Node.
|
||||
@@ -16,7 +24,7 @@ func (cli *Client) NodeUpdate(ctx context.Context, nodeID string, options NodeUp
|
||||
|
||||
query := url.Values{}
|
||||
query.Set("version", options.Version.String())
|
||||
resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, options.Node, nil)
|
||||
resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, options.Spec, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
return NodeUpdateResult{}, err
|
||||
}
|
||||
|
||||
@@ -17,20 +17,20 @@ func TestNodeUpdateError(t *testing.T) {
|
||||
|
||||
_, err = client.NodeUpdate(context.Background(), "node_id", NodeUpdateOptions{
|
||||
Version: swarm.Version{},
|
||||
Node: swarm.NodeSpec{},
|
||||
Spec: swarm.NodeSpec{},
|
||||
})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
|
||||
|
||||
_, err = client.NodeUpdate(context.Background(), "", NodeUpdateOptions{
|
||||
Version: swarm.Version{},
|
||||
Node: swarm.NodeSpec{},
|
||||
Spec: swarm.NodeSpec{},
|
||||
})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
assert.Check(t, is.ErrorContains(err, "value is empty"))
|
||||
|
||||
_, err = client.NodeUpdate(context.Background(), " ", NodeUpdateOptions{
|
||||
Version: swarm.Version{},
|
||||
Node: swarm.NodeSpec{},
|
||||
Spec: swarm.NodeSpec{},
|
||||
})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
assert.Check(t, is.ErrorContains(err, "value is empty"))
|
||||
@@ -49,7 +49,7 @@ func TestNodeUpdate(t *testing.T) {
|
||||
|
||||
_, err = client.NodeUpdate(context.Background(), "node_id", NodeUpdateOptions{
|
||||
Version: swarm.Version{},
|
||||
Node: swarm.NodeSpec{},
|
||||
Spec: swarm.NodeSpec{},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package client
|
||||
|
||||
// NodeInspectOptions holds parameters to inspect nodes with.
|
||||
type NodeInspectOptions struct{}
|
||||
@@ -1,6 +0,0 @@
|
||||
package client
|
||||
|
||||
// NodeListOptions holds parameters to list nodes with.
|
||||
type NodeListOptions struct {
|
||||
Filters Filters
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package client
|
||||
|
||||
// NodeRemoveOptions holds parameters to remove nodes with.
|
||||
type NodeRemoveOptions struct {
|
||||
Force bool
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/swarm"
|
||||
|
||||
// NodeUpdateOptions holds parameters to update nodes with.
|
||||
type NodeUpdateOptions struct {
|
||||
Version swarm.Version
|
||||
Node swarm.NodeSpec
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,13 +128,13 @@ func (s *DockerAPISuite) TestExecAPIStartWithDetach(c *testing.T) {
|
||||
assert.NilError(c, err)
|
||||
defer apiClient.Close()
|
||||
|
||||
createResp, err := apiClient.ExecCreate(ctx, name, client.ExecCreateOptions{
|
||||
res, err := apiClient.ExecCreate(ctx, name, client.ExecCreateOptions{
|
||||
Cmd: []string{"true"},
|
||||
AttachStderr: true,
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
||||
_, body, err := request.Post(ctx, fmt.Sprintf("/exec/%s/start", createResp.ID), request.RawString(`{"Detach": true}`), request.JSON)
|
||||
_, body, err := request.Post(ctx, fmt.Sprintf("/exec/%s/start", res.ID), request.RawString(`{"Detach": true}`), request.JSON)
|
||||
assert.NilError(c, err)
|
||||
|
||||
b, err := request.ReadBody(body)
|
||||
|
||||
@@ -802,7 +802,7 @@ func TestBuildHistoryDoesNotPreventRemoval(t *testing.T) {
|
||||
|
||||
res, err := apiClient.ImageRemove(ctx, "history-a", client.ImageRemoveOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, slices.ContainsFunc(res.Deleted, func(r image.DeleteResponse) bool {
|
||||
assert.Check(t, slices.ContainsFunc(res.Items, func(r image.DeleteResponse) bool {
|
||||
return r.Deleted != ""
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -33,14 +33,14 @@ func TestExecWithCloseStdin(t *testing.T) {
|
||||
cID := container.Run(ctx, t, apiClient)
|
||||
|
||||
const expected = "closeIO"
|
||||
execResp, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{
|
||||
res, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{
|
||||
AttachStdin: true,
|
||||
AttachStdout: true,
|
||||
Cmd: []string{"sh", "-c", "cat && echo " + expected},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
|
||||
resp, err := apiClient.ExecAttach(ctx, execResp.ID, client.ExecAttachOptions{})
|
||||
resp, err := apiClient.ExecAttach(ctx, res.ID, client.ExecAttachOptions{})
|
||||
assert.NilError(t, err)
|
||||
defer resp.Close()
|
||||
|
||||
@@ -88,7 +88,7 @@ func TestExec(t *testing.T) {
|
||||
|
||||
cID := container.Run(ctx, t, apiClient, container.WithTty(true), container.WithWorkingDir("/root"))
|
||||
|
||||
id, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{
|
||||
res, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{
|
||||
WorkingDir: "/tmp",
|
||||
Env: []string{"FOO=BAR"},
|
||||
AttachStdout: true,
|
||||
@@ -96,11 +96,11 @@ func TestExec(t *testing.T) {
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
|
||||
inspect, err := apiClient.ExecInspect(ctx, id.ID, client.ExecInspectOptions{})
|
||||
inspect, err := apiClient.ExecInspect(ctx, res.ID, client.ExecInspectOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(inspect.ExecID, id.ID))
|
||||
assert.Check(t, is.Equal(inspect.ID, res.ID))
|
||||
|
||||
resp, err := apiClient.ExecAttach(ctx, id.ID, client.ExecAttachOptions{})
|
||||
resp, err := apiClient.ExecAttach(ctx, res.ID, client.ExecAttachOptions{})
|
||||
assert.NilError(t, err)
|
||||
defer resp.Close()
|
||||
r, err := io.ReadAll(resp.Reader)
|
||||
@@ -126,12 +126,12 @@ func TestExecResize(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = []string{"sleep", "240"}
|
||||
}
|
||||
resp, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{
|
||||
res, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{
|
||||
Tty: true, // Windows requires a TTY for the resize to work, otherwise fails with "is not a tty: failed precondition", see https://github.com/moby/moby/pull/48665#issuecomment-2412530345
|
||||
Cmd: cmd,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
execID := resp.ID
|
||||
execID := res.ID
|
||||
assert.NilError(t, err)
|
||||
_, err = apiClient.ExecStart(ctx, execID, client.ExecStartOptions{
|
||||
Detach: true,
|
||||
|
||||
@@ -78,7 +78,7 @@ func TestAPIImageHistoryCrossPlatform(t *testing.T) {
|
||||
|
||||
imgID := build.GetImageIDFromBody(t, resp.Body)
|
||||
t.Cleanup(func() {
|
||||
apiClient.ImageRemove(ctx, imgID, client.ImageRemoveOptions{Force: true})
|
||||
_, _ = apiClient.ImageRemove(ctx, imgID, client.ImageRemoveOptions{Force: true})
|
||||
})
|
||||
|
||||
testCases := []struct {
|
||||
|
||||
@@ -147,20 +147,20 @@ func TestRemoveWithPlatform(t *testing.T) {
|
||||
Force: true,
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Len(res.Deleted, 1))
|
||||
for _, r := range res.Deleted {
|
||||
assert.Check(t, is.Len(res.Items, 1))
|
||||
for _, r := range res.Items {
|
||||
assert.Check(t, is.Equal(r.Untagged, ""), "No image should be untagged")
|
||||
}
|
||||
checkPlatformDeleted(t, imageIdx, res.Deleted, tc.deleted)
|
||||
checkPlatformDeleted(t, imageIdx, res.Items, tc.deleted)
|
||||
}
|
||||
|
||||
// Delete the rest
|
||||
resp, err := apiClient.ImageRemove(ctx, imgName, client.ImageRemoveOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.Check(t, is.Len(resp.Deleted, 2))
|
||||
assert.Check(t, is.Equal(resp.Deleted[0].Untagged, imgName))
|
||||
assert.Check(t, is.Equal(resp.Deleted[1].Deleted, imageIdx.Manifests[0].Digest.String()))
|
||||
assert.Check(t, is.Len(resp.Items, 2))
|
||||
assert.Check(t, is.Equal(resp.Items[0].Untagged, imgName))
|
||||
assert.Check(t, is.Equal(resp.Items[1].Deleted, imageIdx.Manifests[0].Digest.String()))
|
||||
// TODO(vvoland): Should it also include platform-specific manifests? https://github.com/moby/moby/pull/49982
|
||||
}
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@ import (
|
||||
// Do builds an image from the given context and returns the image ID.
|
||||
func Do(ctx context.Context, t *testing.T, apiClient client.APIClient, buildCtx *fakecontext.Fake) string {
|
||||
resp, err := apiClient.ImageBuild(ctx, buildCtx.AsTarReader(t), client.ImageBuildOptions{})
|
||||
assert.NilError(t, err)
|
||||
if resp.Body != nil {
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
assert.NilError(t, err)
|
||||
img := GetImageIDFromBody(t, resp.Body)
|
||||
t.Cleanup(func() {
|
||||
apiClient.ImageRemove(ctx, img, client.ImageRemoveOptions{Force: true})
|
||||
_, _ = apiClient.ImageRemove(ctx, img, client.ImageRemoveOptions{Force: true})
|
||||
})
|
||||
return img
|
||||
}
|
||||
|
||||
@@ -58,11 +58,11 @@ func Exec(ctx context.Context, apiClient client.APIClient, id string, cmd []stri
|
||||
op(&execOptions)
|
||||
}
|
||||
|
||||
cresp, err := apiClient.ExecCreate(ctx, id, execOptions)
|
||||
res, err := apiClient.ExecCreate(ctx, id, execOptions)
|
||||
if err != nil {
|
||||
return ExecResult{}, err
|
||||
}
|
||||
execID := cresp.ID
|
||||
execID := res.ID
|
||||
|
||||
// run it, with stdout/stderr attached
|
||||
aresp, err := apiClient.ExecAttach(ctx, execID, client.ExecAttachOptions{})
|
||||
@@ -77,12 +77,12 @@ func Exec(ctx context.Context, apiClient client.APIClient, id string, cmd []stri
|
||||
}
|
||||
|
||||
// get the exit code
|
||||
iresp, err := apiClient.ExecInspect(ctx, execID, client.ExecInspectOptions{})
|
||||
inspect, err := apiClient.ExecInspect(ctx, execID, client.ExecInspectOptions{})
|
||||
if err != nil {
|
||||
return ExecResult{}, err
|
||||
}
|
||||
|
||||
return ExecResult{ExitCode: iresp.ExitCode, outBuffer: &s.stdout, errBuffer: &s.stderr}, nil
|
||||
return ExecResult{ExitCode: inspect.ExitCode, outBuffer: &s.stdout, errBuffer: &s.stderr}, nil
|
||||
}
|
||||
|
||||
// ExecT calls Exec() and aborts the test if an error occurs.
|
||||
|
||||
@@ -237,10 +237,10 @@ func ExecTask(ctx context.Context, t *testing.T, d *daemon.Daemon, task swarmtyp
|
||||
apiClient := d.NewClientT(t)
|
||||
defer apiClient.Close()
|
||||
|
||||
resp, err := apiClient.ExecCreate(ctx, task.Status.ContainerStatus.ContainerID, options)
|
||||
res, err := apiClient.ExecCreate(ctx, task.Status.ContainerStatus.ContainerID, options)
|
||||
assert.NilError(t, err, "error creating exec")
|
||||
|
||||
attach, err := apiClient.ExecAttach(ctx, resp.ID, client.ExecAttachOptions{})
|
||||
attach, err := apiClient.ExecAttach(ctx, res.ID, client.ExecAttachOptions{})
|
||||
assert.NilError(t, err, "error attaching to exec")
|
||||
return attach.HijackedResponse
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestEventsExecDie(t *testing.T) {
|
||||
|
||||
cID := container.Run(ctx, t, apiClient)
|
||||
|
||||
id, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{
|
||||
res, err := apiClient.ExecCreate(ctx, cID, client.ExecCreateOptions{
|
||||
Cmd: []string{"echo", "hello"},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
@@ -34,7 +34,7 @@ func TestEventsExecDie(t *testing.T) {
|
||||
Filters: make(client.Filters).Add("container", cID).Add("event", string(events.ActionExecDie)),
|
||||
})
|
||||
|
||||
_, err = apiClient.ExecStart(ctx, id.ID, client.ExecStartOptions{
|
||||
_, err = apiClient.ExecStart(ctx, res.ID, client.ExecStartOptions{
|
||||
Detach: true,
|
||||
Tty: false,
|
||||
})
|
||||
@@ -45,7 +45,7 @@ func TestEventsExecDie(t *testing.T) {
|
||||
assert.Equal(t, m.Type, events.ContainerEventType)
|
||||
assert.Equal(t, m.Actor.ID, cID)
|
||||
assert.Equal(t, m.Action, events.ActionExecDie)
|
||||
assert.Equal(t, m.Actor.Attributes["execID"], id.ID)
|
||||
assert.Equal(t, m.Actor.Attributes["execID"], res.ID)
|
||||
assert.Equal(t, m.Actor.Attributes["exitCode"], "0")
|
||||
case err = <-errs:
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -151,7 +151,9 @@ func TestRunMountImage(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
testImage := setupTestImage(t, ctx, apiClient, tc.name)
|
||||
if testImage != "" {
|
||||
defer apiClient.ImageRemove(ctx, testImage, client.ImageRemoveOptions{Force: true})
|
||||
defer func() {
|
||||
_, _ = apiClient.ImageRemove(ctx, testImage, client.ImageRemoveOptions{Force: true})
|
||||
}()
|
||||
}
|
||||
|
||||
cfg := containertypes.Config{
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -60,7 +60,7 @@ func (d *Daemon) UpdateNode(ctx context.Context, t testing.TB, id string, f ...N
|
||||
|
||||
_, err := cli.NodeUpdate(ctx, node.ID, client.NodeUpdateOptions{
|
||||
Version: node.Version,
|
||||
Node: node.Spec,
|
||||
Spec: node.Spec,
|
||||
})
|
||||
if i < 10 && err != nil && strings.Contains(err.Error(), "update out of sequence") {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
35
vendor/github.com/moby/moby/client/container_exec.go
generated
vendored
35
vendor/github.com/moby/moby/client/container_exec.go
generated
vendored
@@ -26,7 +26,7 @@ type ExecCreateOptions struct {
|
||||
|
||||
// ExecCreateResult holds the result of creating a container exec.
|
||||
type ExecCreateResult struct {
|
||||
container.ExecCreateResponse
|
||||
ID string
|
||||
}
|
||||
|
||||
// ExecCreate creates a new exec configuration to run an exec process.
|
||||
@@ -58,7 +58,7 @@ func (cli *Client) ExecCreate(ctx context.Context, containerID string, options E
|
||||
|
||||
var response container.ExecCreateResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&response)
|
||||
return ExecCreateResult{ExecCreateResponse: response}, err
|
||||
return ExecCreateResult{ID: response.ID}, err
|
||||
}
|
||||
|
||||
type execStartAttachOptions struct {
|
||||
@@ -127,26 +127,21 @@ func (cli *Client) ExecAttach(ctx context.Context, execID string, options ExecAt
|
||||
return ExecAttachResult{HijackedResponse: response}, err
|
||||
}
|
||||
|
||||
// ExecInspect holds information returned by exec inspect.
|
||||
//
|
||||
// It provides a subset of the information included in [container.ExecInspectResponse].
|
||||
//
|
||||
// TODO(thaJeztah): include all fields of [container.ExecInspectResponse] ?
|
||||
type ExecInspect struct {
|
||||
ExecID string `json:"ID"`
|
||||
ContainerID string `json:"ContainerID"`
|
||||
Running bool `json:"Running"`
|
||||
ExitCode int `json:"ExitCode"`
|
||||
Pid int `json:"Pid"`
|
||||
}
|
||||
|
||||
// ExecInspectOptions holds options for inspecting a container exec.
|
||||
type ExecInspectOptions struct {
|
||||
}
|
||||
|
||||
// ExecInspectResult holds the result of inspecting a container exec.
|
||||
//
|
||||
// It provides a subset of the information included in [container.ExecInspectResponse].
|
||||
//
|
||||
// TODO(thaJeztah): include all fields of [container.ExecInspectResponse] ?
|
||||
type ExecInspectResult struct {
|
||||
ExecInspect
|
||||
ID string
|
||||
ContainerID string
|
||||
Running bool
|
||||
ExitCode int
|
||||
PID int
|
||||
}
|
||||
|
||||
// ExecInspect returns information about a specific exec process on the docker host.
|
||||
@@ -168,11 +163,11 @@ func (cli *Client) ExecInspect(ctx context.Context, execID string, options ExecI
|
||||
ec = *response.ExitCode
|
||||
}
|
||||
|
||||
return ExecInspectResult{ExecInspect: ExecInspect{
|
||||
ExecID: response.ID,
|
||||
return ExecInspectResult{
|
||||
ID: response.ID,
|
||||
ContainerID: response.ContainerID,
|
||||
Running: response.Running,
|
||||
ExitCode: ec,
|
||||
Pid: response.Pid,
|
||||
}}, nil
|
||||
PID: response.Pid,
|
||||
}, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/moby/moby/client/image_import.go
generated
vendored
2
vendor/github.com/moby/moby/client/image_import.go
generated
vendored
@@ -42,5 +42,5 @@ func (cli *Client) ImageImport(ctx context.Context, source ImageImportSource, re
|
||||
if err != nil {
|
||||
return ImageImportResult{}, err
|
||||
}
|
||||
return ImageImportResult{body: resp.Body}, nil
|
||||
return ImageImportResult{rc: resp.Body}, nil
|
||||
}
|
||||
|
||||
11
vendor/github.com/moby/moby/client/image_import_opts.go
generated
vendored
11
vendor/github.com/moby/moby/client/image_import_opts.go
generated
vendored
@@ -20,16 +20,19 @@ type ImageImportOptions struct {
|
||||
|
||||
// ImageImportResult holds the response body returned by the daemon for image import.
|
||||
type ImageImportResult struct {
|
||||
body io.ReadCloser
|
||||
rc io.ReadCloser
|
||||
}
|
||||
|
||||
func (r ImageImportResult) Read(p []byte) (n int, err error) {
|
||||
return r.body.Read(p)
|
||||
if r.rc == nil {
|
||||
return 0, io.EOF
|
||||
}
|
||||
return r.rc.Read(p)
|
||||
}
|
||||
|
||||
func (r ImageImportResult) Close() error {
|
||||
if r.body == nil {
|
||||
if r.rc == nil {
|
||||
return nil
|
||||
}
|
||||
return r.body.Close()
|
||||
return r.rc.Close()
|
||||
}
|
||||
|
||||
2
vendor/github.com/moby/moby/client/image_remove.go
generated
vendored
2
vendor/github.com/moby/moby/client/image_remove.go
generated
vendored
@@ -35,5 +35,5 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options Imag
|
||||
|
||||
var dels []image.DeleteResponse
|
||||
err = json.NewDecoder(resp.Body).Decode(&dels)
|
||||
return ImageRemoveResult{Deleted: dels}, err
|
||||
return ImageRemoveResult{Items: dels}, err
|
||||
}
|
||||
|
||||
2
vendor/github.com/moby/moby/client/image_remove_opts.go
generated
vendored
2
vendor/github.com/moby/moby/client/image_remove_opts.go
generated
vendored
@@ -14,5 +14,5 @@ type ImageRemoveOptions struct {
|
||||
|
||||
// ImageRemoveResult holds the delete responses returned by the daemon.
|
||||
type ImageRemoveResult struct {
|
||||
Deleted []image.DeleteResponse
|
||||
Items []image.DeleteResponse
|
||||
}
|
||||
|
||||
3
vendor/github.com/moby/moby/client/node_inspect.go
generated
vendored
3
vendor/github.com/moby/moby/client/node_inspect.go
generated
vendored
@@ -9,6 +9,9 @@ import (
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// NodeInspectOptions holds parameters to inspect nodes with.
|
||||
type NodeInspectOptions struct{}
|
||||
|
||||
type NodeInspectResult struct {
|
||||
Node swarm.Node
|
||||
Raw []byte
|
||||
|
||||
5
vendor/github.com/moby/moby/client/node_list.go
generated
vendored
5
vendor/github.com/moby/moby/client/node_list.go
generated
vendored
@@ -8,6 +8,11 @@ import (
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// NodeListOptions holds parameters to list nodes with.
|
||||
type NodeListOptions struct {
|
||||
Filters Filters
|
||||
}
|
||||
|
||||
type NodeListResult struct {
|
||||
Items []swarm.Node
|
||||
}
|
||||
|
||||
4
vendor/github.com/moby/moby/client/node_remove.go
generated
vendored
4
vendor/github.com/moby/moby/client/node_remove.go
generated
vendored
@@ -5,6 +5,10 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// NodeRemoveOptions holds parameters to remove nodes with.
|
||||
type NodeRemoveOptions struct {
|
||||
Force bool
|
||||
}
|
||||
type NodeRemoveResult struct{}
|
||||
|
||||
// NodeRemove removes a Node.
|
||||
|
||||
10
vendor/github.com/moby/moby/client/node_update.go
generated
vendored
10
vendor/github.com/moby/moby/client/node_update.go
generated
vendored
@@ -3,8 +3,16 @@ package client
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// NodeUpdateOptions holds parameters to update nodes with.
|
||||
type NodeUpdateOptions struct {
|
||||
Version swarm.Version
|
||||
Spec swarm.NodeSpec
|
||||
}
|
||||
|
||||
type NodeUpdateResult struct{}
|
||||
|
||||
// NodeUpdate updates a Node.
|
||||
@@ -16,7 +24,7 @@ func (cli *Client) NodeUpdate(ctx context.Context, nodeID string, options NodeUp
|
||||
|
||||
query := url.Values{}
|
||||
query.Set("version", options.Version.String())
|
||||
resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, options.Node, nil)
|
||||
resp, err := cli.post(ctx, "/nodes/"+nodeID+"/update", query, options.Spec, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
return NodeUpdateResult{}, err
|
||||
}
|
||||
|
||||
4
vendor/github.com/moby/moby/client/swarm_node_inspect_opts.go
generated
vendored
4
vendor/github.com/moby/moby/client/swarm_node_inspect_opts.go
generated
vendored
@@ -1,4 +0,0 @@
|
||||
package client
|
||||
|
||||
// NodeInspectOptions holds parameters to inspect nodes with.
|
||||
type NodeInspectOptions struct{}
|
||||
6
vendor/github.com/moby/moby/client/swarm_node_list_opts.go
generated
vendored
6
vendor/github.com/moby/moby/client/swarm_node_list_opts.go
generated
vendored
@@ -1,6 +0,0 @@
|
||||
package client
|
||||
|
||||
// NodeListOptions holds parameters to list nodes with.
|
||||
type NodeListOptions struct {
|
||||
Filters Filters
|
||||
}
|
||||
6
vendor/github.com/moby/moby/client/swarm_node_remove_opts.go
generated
vendored
6
vendor/github.com/moby/moby/client/swarm_node_remove_opts.go
generated
vendored
@@ -1,6 +0,0 @@
|
||||
package client
|
||||
|
||||
// NodeRemoveOptions holds parameters to remove nodes with.
|
||||
type NodeRemoveOptions struct {
|
||||
Force bool
|
||||
}
|
||||
9
vendor/github.com/moby/moby/client/swarm_node_update_opts.go
generated
vendored
9
vendor/github.com/moby/moby/client/swarm_node_update_opts.go
generated
vendored
@@ -1,9 +0,0 @@
|
||||
package client
|
||||
|
||||
import "github.com/moby/moby/api/types/swarm"
|
||||
|
||||
// NodeUpdateOptions holds parameters to update nodes with.
|
||||
type NodeUpdateOptions struct {
|
||||
Version swarm.Version
|
||||
Node swarm.NodeSpec
|
||||
}
|
||||
28
vendor/github.com/moby/moby/client/volume_list.go
generated
vendored
28
vendor/github.com/moby/moby/client/volume_list.go
generated
vendored
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user