Skip to content

Commit 81da375

Browse files
committed
cli/command/service: runScale: use errors.Join, and cleanup
- Use stdlib multi-errors instead of creating our own - use apiClient instead of client for the API client to prevent shadowing imports. - use dockerCLI with Go's standard camelCase casing. - rewrite runServiceScale to return warnings, instead of printing them Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent 09b513e commit 81da375

1 file changed

Lines changed: 32 additions & 38 deletions

File tree

cli/command/service/scale.go

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package service
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"strconv"
78
"strings"
@@ -10,7 +11,7 @@ import (
1011
"github.com/docker/cli/cli/command"
1112
"github.com/docker/docker/api/types"
1213
"github.com/docker/docker/api/types/versions"
13-
"github.com/pkg/errors"
14+
"github.com/docker/docker/client"
1415
"github.com/spf13/cobra"
1516
)
1617

@@ -44,8 +45,8 @@ func scaleArgs(cmd *cobra.Command, args []string) error {
4445
}
4546
for _, arg := range args {
4647
if k, v, ok := strings.Cut(arg, "="); !ok || k == "" || v == "" {
47-
return errors.Errorf(
48-
"Invalid scale specifier '%s'.\nSee '%s --help'.\n\nUsage: %s\n\n%s",
48+
return fmt.Errorf(
49+
"invalid scale specifier '%s'.\nSee '%s --help'.\n\nUsage: %s\n\n%s",
4950
arg,
5051
cmd.CommandPath(),
5152
cmd.UseLine(),
@@ -56,49 +57,48 @@ func scaleArgs(cmd *cobra.Command, args []string) error {
5657
return nil
5758
}
5859

59-
func runScale(ctx context.Context, dockerCli command.Cli, options *scaleOptions, args []string) error {
60-
var errs []string
61-
var serviceIDs []string
62-
60+
func runScale(ctx context.Context, dockerCLI command.Cli, options *scaleOptions, args []string) error {
61+
apiClient := dockerCLI.Client()
62+
var (
63+
errs []error
64+
serviceIDs = make([]string, 0, len(args))
65+
)
6366
for _, arg := range args {
6467
serviceID, scaleStr, _ := strings.Cut(arg, "=")
6568

6669
// validate input arg scale number
6770
scale, err := strconv.ParseUint(scaleStr, 10, 64)
6871
if err != nil {
69-
errs = append(errs, fmt.Sprintf("%s: invalid replicas value %s: %v", serviceID, scaleStr, err))
72+
errs = append(errs, fmt.Errorf("%s: invalid replicas value %s: %v", serviceID, scaleStr, err))
7073
continue
7174
}
7275

73-
if err := runServiceScale(ctx, dockerCli, serviceID, scale); err != nil {
74-
errs = append(errs, fmt.Sprintf("%s: %v", serviceID, err))
75-
} else {
76-
serviceIDs = append(serviceIDs, serviceID)
76+
warnings, err := runServiceScale(ctx, apiClient, serviceID, scale)
77+
if err != nil {
78+
errs = append(errs, fmt.Errorf("%s: %v", serviceID, err))
79+
continue
80+
}
81+
for _, warning := range warnings {
82+
_, _ = fmt.Fprintln(dockerCLI.Err(), warning)
7783
}
84+
_, _ = fmt.Fprintf(dockerCLI.Out(), "%s scaled to %d\n", serviceID, scale)
85+
serviceIDs = append(serviceIDs, serviceID)
7886
}
7987

80-
if len(serviceIDs) > 0 {
81-
if !options.detach && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.29") {
82-
for _, serviceID := range serviceIDs {
83-
if err := WaitOnService(ctx, dockerCli, serviceID, false); err != nil {
84-
errs = append(errs, fmt.Sprintf("%s: %v", serviceID, err))
85-
}
88+
if len(serviceIDs) > 0 && !options.detach && versions.GreaterThanOrEqualTo(dockerCLI.Client().ClientVersion(), "1.29") {
89+
for _, serviceID := range serviceIDs {
90+
if err := WaitOnService(ctx, dockerCLI, serviceID, false); err != nil {
91+
errs = append(errs, fmt.Errorf("%s: %v", serviceID, err))
8692
}
8793
}
8894
}
89-
90-
if len(errs) == 0 {
91-
return nil
92-
}
93-
return errors.New(strings.Join(errs, "\n"))
95+
return errors.Join(errs...)
9496
}
9597

96-
func runServiceScale(ctx context.Context, dockerCli command.Cli, serviceID string, scale uint64) error {
97-
client := dockerCli.Client()
98-
99-
service, _, err := client.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
98+
func runServiceScale(ctx context.Context, apiClient client.ServiceAPIClient, serviceID string, scale uint64) (warnings []string, _ error) {
99+
service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
100100
if err != nil {
101-
return err
101+
return nil, err
102102
}
103103

104104
serviceMode := &service.Spec.Mode
@@ -108,18 +108,12 @@ func runServiceScale(ctx context.Context, dockerCli command.Cli, serviceID strin
108108
case serviceMode.ReplicatedJob != nil:
109109
serviceMode.ReplicatedJob.TotalCompletions = &scale
110110
default:
111-
return errors.Errorf("scale can only be used with replicated or replicated-job mode")
111+
return nil, errors.New("scale can only be used with replicated or replicated-job mode")
112112
}
113113

114-
response, err := client.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
114+
response, err := apiClient.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
115115
if err != nil {
116-
return err
117-
}
118-
119-
for _, warning := range response.Warnings {
120-
_, _ = fmt.Fprintln(dockerCli.Err(), warning)
116+
return nil, err
121117
}
122-
123-
_, _ = fmt.Fprintf(dockerCli.Out(), "%s scaled to %d\n", serviceID, scale)
124-
return nil
118+
return response.Warnings, nil
125119
}

0 commit comments

Comments
 (0)