update local code for updated modules

Some tests had to be skipped as there's some issues to address, and
some of the result-types cannot be mocked / stubbed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-10-22 17:05:31 +02:00
parent aeb78091a0
commit 4f7c07cfc2
190 changed files with 3020 additions and 2585 deletions

View File

@ -3,26 +3,25 @@ package task
import (
"context"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
)
type fakeClient struct {
client.APIClient
nodeInspectWithRaw func(ref string) (swarm.Node, []byte, error)
serviceInspectWithRaw func(ref string, options client.ServiceInspectOptions) (swarm.Service, []byte, error)
nodeInspectFunc func(ref string) (client.NodeInspectResult, error)
serviceInspectFunc func(ref string, options client.ServiceInspectOptions) (client.ServiceInspectResult, error)
}
func (cli *fakeClient) NodeInspectWithRaw(_ context.Context, ref string) (swarm.Node, []byte, error) {
if cli.nodeInspectWithRaw != nil {
return cli.nodeInspectWithRaw(ref)
func (cli *fakeClient) NodeInspect(_ context.Context, ref string, _ client.NodeInspectOptions) (client.NodeInspectResult, error) {
if cli.nodeInspectFunc != nil {
return cli.nodeInspectFunc(ref)
}
return swarm.Node{}, nil, nil
return client.NodeInspectResult{}, nil
}
func (cli *fakeClient) ServiceInspectWithRaw(_ context.Context, ref string, options client.ServiceInspectOptions) (swarm.Service, []byte, error) {
if cli.serviceInspectWithRaw != nil {
return cli.serviceInspectWithRaw(ref, options)
func (cli *fakeClient) ServiceInspect(_ context.Context, ref string, options client.ServiceInspectOptions) (client.ServiceInspectResult, error) {
if cli.serviceInspectFunc != nil {
return cli.serviceInspectFunc(ref, options)
}
return swarm.Service{}, nil, nil
return client.ServiceInspectResult{}, nil
}

View File

@ -9,6 +9,7 @@ import (
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/go-units"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
)
const (
@ -40,7 +41,7 @@ func newTaskFormat(source string, quiet bool) formatter.Format {
}
// formatWrite writes the context.
func formatWrite(fmtCtx formatter.Context, tasks []swarm.Task, names map[string]string, nodes map[string]string) error {
func formatWrite(fmtCtx formatter.Context, tasks client.TaskListResult, names map[string]string, nodes map[string]string) error {
taskCtx := &taskContext{
HeaderContext: formatter.HeaderContext{
Header: formatter.SubHeaderContext{
@ -56,7 +57,7 @@ func formatWrite(fmtCtx formatter.Context, tasks []swarm.Task, names map[string]
},
}
return fmtCtx.Write(taskCtx, func(format func(subContext formatter.SubContext) error) error {
for _, task := range tasks {
for _, task := range tasks.Items {
if err := format(&taskContext{
trunc: fmtCtx.Trunc,
task: task,
@ -140,7 +141,7 @@ func (c *taskContext) Ports() string {
if len(c.task.Status.PortStatus.Ports) == 0 {
return ""
}
ports := []string{}
ports := make([]string, 0, len(c.task.Status.PortStatus.Ports))
for _, pConfig := range c.task.Status.PortStatus.Ports {
ports = append(ports, fmt.Sprintf("*:%d->%d/%s",
pConfig.PublishedPort,

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/cli/cli/command/formatter"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/golden"
@ -57,9 +58,11 @@ foobar_bar foo2
},
}
tasks := []swarm.Task{
{ID: "taskID1"},
{ID: "taskID2"},
tasks := client.TaskListResult{
Items: []swarm.Task{
{ID: "taskID1"},
{ID: "taskID2"},
},
}
names := map[string]string{
"taskID1": "foobar_baz",
@ -85,9 +88,11 @@ foobar_bar foo2
}
func TestTaskContextWriteJSONField(t *testing.T) {
tasks := []swarm.Task{
{ID: "taskID1"},
{ID: "taskID2"},
tasks := client.TaskListResult{
Items: []swarm.Task{
{ID: "taskID1"},
{ID: "taskID2"},
},
}
names := map[string]string{
"taskID1": "foobar_baz",
@ -103,6 +108,6 @@ func TestTaskContextWriteJSONField(t *testing.T) {
if err := json.Unmarshal([]byte(line), &s); err != nil {
t.Fatal(err)
}
assert.Check(t, is.Equal(tasks[i].ID, s))
assert.Check(t, is.Equal(tasks.Items[i].ID, s))
}
}

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/fvbommel/sortorder"
"github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client"
)
type tasksSortable []swarm.Task
@ -34,7 +35,7 @@ func (t tasksSortable) Less(i, j int) bool {
// Print task information in a format.
// Besides this, command `docker node ps <node>`
// and `docker stack ps` will call this, too.
func Print(ctx context.Context, dockerCli command.Cli, tasks []swarm.Task, resolver *idresolver.IDResolver, trunc, quiet bool, format string) error {
func Print(ctx context.Context, dockerCli command.Cli, tasks client.TaskListResult, resolver *idresolver.IDResolver, trunc, quiet bool, format string) error {
tasks, err := generateTaskNames(ctx, tasks, resolver)
if err != nil {
return err
@ -43,7 +44,7 @@ func Print(ctx context.Context, dockerCli command.Cli, tasks []swarm.Task, resol
// First sort tasks, so that all tasks (including previous ones) of the same
// service and slot are together. This must be done first, to print "previous"
// tasks indented
sort.Stable(tasksSortable(tasks))
sort.Stable(tasksSortable(tasks.Items))
names := map[string]string{}
nodes := map[string]string{}
@ -59,7 +60,7 @@ func Print(ctx context.Context, dockerCli command.Cli, tasks []swarm.Task, resol
indent = ` \_ `
}
prevName := ""
for _, task := range tasks {
for _, task := range tasks.Items {
if task.Name == prevName {
// Indent previous tasks of the same slot
names[task.ID] = indent + task.Name
@ -87,15 +88,15 @@ func Print(ctx context.Context, dockerCli command.Cli, tasks []swarm.Task, resol
// - ServiceName.NodeName or ServiceID.NodeID for tasks that are part of a global service
//
// Task-names are not unique in cases where "tasks" contains previous/rotated tasks.
func generateTaskNames(ctx context.Context, tasks []swarm.Task, resolver *idresolver.IDResolver) ([]swarm.Task, error) {
func generateTaskNames(ctx context.Context, tasks client.TaskListResult, resolver *idresolver.IDResolver) (client.TaskListResult, error) {
// Use a copy of the tasks list, to not modify the original slice
// see https://github.com/go101/go101/wiki/How-to-efficiently-clone-a-slice%3F
t := append(tasks[:0:0], tasks...) //nolint:gocritic // ignore appendAssign: append result not assigned to the same slice
t := append(tasks.Items[:0:0], tasks.Items...) //nolint:gocritic // ignore appendAssign: append result not assigned to the same slice
for i, task := range t {
serviceName, err := resolver.Resolve(ctx, swarm.Service{}, task.ServiceID)
if err != nil {
return nil, err
return client.TaskListResult{}, err
}
if task.Slot != 0 {
t[i].Name = fmt.Sprintf("%v.%v", serviceName, task.Slot)
@ -103,7 +104,7 @@ func generateTaskNames(ctx context.Context, tasks []swarm.Task, resolver *idreso
t[i].Name = fmt.Sprintf("%v.%v", serviceName, task.NodeID)
}
}
return t, nil
return client.TaskListResult{Items: t}, nil
}
// DefaultFormat returns the default format from the config file, or table

View File

@ -17,35 +17,41 @@ import (
func TestTaskPrintSorted(t *testing.T) {
apiClient := &fakeClient{
serviceInspectWithRaw: func(ref string, options client.ServiceInspectOptions) (swarm.Service, []byte, error) {
serviceInspectFunc: func(ref string, options client.ServiceInspectOptions) (client.ServiceInspectResult, error) {
if ref == "service-id-one" {
return *builders.Service(builders.ServiceName("service-name-1")), nil, nil
return client.ServiceInspectResult{
Service: *builders.Service(builders.ServiceName("service-name-1")),
}, nil
}
return *builders.Service(builders.ServiceName("service-name-10")), nil, nil
return client.ServiceInspectResult{
Service: *builders.Service(builders.ServiceName("service-name-10")),
}, nil
},
}
cli := test.NewFakeCli(apiClient)
tasks := []swarm.Task{
*builders.Task(
builders.TaskID("id-foo"),
builders.TaskServiceID("service-id-ten"),
builders.TaskNodeID("id-node"),
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
builders.TaskDesiredState(swarm.TaskStateReady),
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
),
*builders.Task(
builders.TaskID("id-bar"),
builders.TaskServiceID("service-id-one"),
builders.TaskNodeID("id-node"),
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
builders.TaskDesiredState(swarm.TaskStateReady),
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
),
res := client.TaskListResult{
Items: []swarm.Task{
*builders.Task(
builders.TaskID("id-foo"),
builders.TaskServiceID("service-id-ten"),
builders.TaskNodeID("id-node"),
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
builders.TaskDesiredState(swarm.TaskStateReady),
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
),
*builders.Task(
builders.TaskID("id-bar"),
builders.TaskServiceID("service-id-one"),
builders.TaskNodeID("id-node"),
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
builders.TaskDesiredState(swarm.TaskStateReady),
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
),
},
}
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, false), false, false, formatter.TableFormatKey)
err := Print(context.Background(), cli, res, idresolver.New(apiClient, false), false, false, formatter.TableFormatKey)
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), "task-print-sorted.golden")
}
@ -56,7 +62,11 @@ func TestTaskPrintWithQuietOption(t *testing.T) {
const noResolve = true
apiClient := &fakeClient{}
cli := test.NewFakeCli(apiClient)
tasks := []swarm.Task{*builders.Task(builders.TaskID("id-foo"))}
tasks := client.TaskListResult{
Items: []swarm.Task{
*builders.Task(builders.TaskID("id-foo")),
},
}
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, formatter.TableFormatKey)
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), "task-print-with-quiet-option.golden")
@ -68,8 +78,10 @@ func TestTaskPrintWithNoTruncOption(t *testing.T) {
const noResolve = true
apiClient := &fakeClient{}
cli := test.NewFakeCli(apiClient)
tasks := []swarm.Task{
*builders.Task(builders.TaskID("id-foo-yov6omdek8fg3k5stosyp2m50")),
tasks := client.TaskListResult{
Items: []swarm.Task{
*builders.Task(builders.TaskID("id-foo-yov6omdek8fg3k5stosyp2m50")),
},
}
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .ID }}")
assert.NilError(t, err)
@ -82,8 +94,10 @@ func TestTaskPrintWithGlobalService(t *testing.T) {
const noResolve = true
apiClient := &fakeClient{}
cli := test.NewFakeCli(apiClient)
tasks := []swarm.Task{
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskNodeID("node-id-bar"), builders.TaskSlot(0)),
tasks := client.TaskListResult{
Items: []swarm.Task{
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskNodeID("node-id-bar"), builders.TaskSlot(0)),
},
}
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }}")
assert.NilError(t, err)
@ -96,8 +110,10 @@ func TestTaskPrintWithReplicatedService(t *testing.T) {
const noResolve = true
apiClient := &fakeClient{}
cli := test.NewFakeCli(apiClient)
tasks := []swarm.Task{
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskSlot(1)),
tasks := client.TaskListResult{
Items: []swarm.Task{
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskSlot(1)),
},
}
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }}")
assert.NilError(t, err)
@ -109,31 +125,37 @@ func TestTaskPrintWithIndentation(t *testing.T) {
const trunc = false
const noResolve = false
apiClient := &fakeClient{
serviceInspectWithRaw: func(ref string, options client.ServiceInspectOptions) (swarm.Service, []byte, error) {
return *builders.Service(builders.ServiceName("service-name-foo")), nil, nil
serviceInspectFunc: func(ref string, options client.ServiceInspectOptions) (client.ServiceInspectResult, error) {
return client.ServiceInspectResult{
Service: *builders.Service(builders.ServiceName("service-name-foo")),
}, nil
},
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
return *builders.Node(builders.NodeName("node-name-bar")), nil, nil
nodeInspectFunc: func(ref string) (client.NodeInspectResult, error) {
return client.NodeInspectResult{
Node: *builders.Node(builders.NodeName("node-name-bar")),
}, nil
},
}
cli := test.NewFakeCli(apiClient)
tasks := []swarm.Task{
*builders.Task(
builders.TaskID("id-foo"),
builders.TaskServiceID("service-id-foo"),
builders.TaskNodeID("id-node"),
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
builders.TaskDesiredState(swarm.TaskStateReady),
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
),
*builders.Task(
builders.TaskID("id-bar"),
builders.TaskServiceID("service-id-foo"),
builders.TaskNodeID("id-node"),
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
builders.TaskDesiredState(swarm.TaskStateReady),
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
),
tasks := client.TaskListResult{
Items: []swarm.Task{
*builders.Task(
builders.TaskID("id-foo"),
builders.TaskServiceID("service-id-foo"),
builders.TaskNodeID("id-node"),
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
builders.TaskDesiredState(swarm.TaskStateReady),
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
),
*builders.Task(
builders.TaskID("id-bar"),
builders.TaskServiceID("service-id-foo"),
builders.TaskNodeID("id-node"),
builders.WithTaskSpec(builders.TaskImage("myimage:mytag")),
builders.TaskDesiredState(swarm.TaskStateReady),
builders.WithStatus(builders.TaskState(swarm.TaskStateFailed), builders.Timestamp(time.Now().Add(-2*time.Hour))),
),
},
}
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, formatter.TableFormatKey)
assert.NilError(t, err)
@ -145,16 +167,22 @@ func TestTaskPrintWithResolution(t *testing.T) {
const trunc = false
const noResolve = false
apiClient := &fakeClient{
serviceInspectWithRaw: func(ref string, options client.ServiceInspectOptions) (swarm.Service, []byte, error) {
return *builders.Service(builders.ServiceName("service-name-foo")), nil, nil
serviceInspectFunc: func(ref string, options client.ServiceInspectOptions) (client.ServiceInspectResult, error) {
return client.ServiceInspectResult{
Service: *builders.Service(builders.ServiceName("service-name-foo")),
}, nil
},
nodeInspectWithRaw: func(ref string) (swarm.Node, []byte, error) {
return *builders.Node(builders.NodeName("node-name-bar")), nil, nil
nodeInspectFunc: func(ref string) (client.NodeInspectResult, error) {
return client.NodeInspectResult{
Node: *builders.Node(builders.NodeName("node-name-bar")),
}, nil
},
}
cli := test.NewFakeCli(apiClient)
tasks := []swarm.Task{
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskSlot(1)),
tasks := client.TaskListResult{
Items: []swarm.Task{
*builders.Task(builders.TaskServiceID("service-id-foo"), builders.TaskSlot(1)),
},
}
err := Print(context.Background(), cli, tasks, idresolver.New(apiClient, noResolve), trunc, quiet, "{{ .Name }} {{ .Node }}")
assert.NilError(t, err)