2016-09-08 13:11:39 -04:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
2018-05-03 21:02:44 -04:00
|
|
|
"context"
|
2016-09-08 13:11:39 -04:00
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
2017-04-17 18:07:56 -04:00
|
|
|
"github.com/docker/cli/cli"
|
|
|
|
"github.com/docker/cli/cli/command"
|
2016-09-08 13:11:39 -04:00
|
|
|
"github.com/docker/docker/api/types"
|
Use non-detached mode as default for service commands
Commit 330a0035334871d92207b583c1c36d52a244753f added a `--detach=false` option
to various service-related commands, with the intent to make this the default in
a future version (17.09).
This patch changes the default to use "interactive" (non-detached), allowing
users to override this by setting the `--detach` option.
To prevent problems when connecting to older daemon versions (17.05 and below,
see commit db60f255617fd90cb093813dcdfe7eec840eeff8), the detach option is
ignored for those versions, and detach is always true.
Before this change, a warning was printed to announce the upcoming default:
$ docker service create nginx:alpine
saxiyn3pe559d753730zr0xer
Since --detach=false was not specified, tasks will be created in the background.
In a future release, --detach=false will become the default.
After this change, no warning is printed, but `--detach` is disabled;
$ docker service create nginx:alpine
y9jujwzozi0hwgj5yaadzliq6
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
Setting the `--detach` flag makes the cli use the pre-17.06 behavior:
$ docker service create --detach nginx:alpine
280hjnzy0wzje5o56gr22a46n
Running against a 17.03 daemon, without specifying the `--detach` flag;
$ docker service create nginx:alpine
kqheg7ogj0kszoa34g4p73i8q
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-09-12 08:35:19 -04:00
|
|
|
"github.com/docker/docker/api/types/versions"
|
2017-03-09 13:23:45 -05:00
|
|
|
"github.com/pkg/errors"
|
2016-09-08 13:11:39 -04:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
)
|
|
|
|
|
2017-06-27 12:55:10 -04:00
|
|
|
type scaleOptions struct {
|
|
|
|
detach bool
|
|
|
|
}
|
|
|
|
|
2017-07-20 04:32:51 -04:00
|
|
|
func newScaleCommand(dockerCli command.Cli) *cobra.Command {
|
2017-06-27 12:55:10 -04:00
|
|
|
options := &scaleOptions{}
|
|
|
|
|
|
|
|
cmd := &cobra.Command{
|
2016-09-08 13:11:39 -04:00
|
|
|
Use: "scale SERVICE=REPLICAS [SERVICE=REPLICAS...]",
|
2016-11-02 03:53:18 -04:00
|
|
|
Short: "Scale one or multiple replicated services",
|
2016-09-08 13:11:39 -04:00
|
|
|
Args: scaleArgs,
|
|
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
2023-09-09 18:27:44 -04:00
|
|
|
return runScale(cmd.Context(), dockerCli, options, args)
|
2016-09-08 13:11:39 -04:00
|
|
|
},
|
2022-03-30 09:27:25 -04:00
|
|
|
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
|
|
|
return CompletionFn(dockerCli)(cmd, args, toComplete)
|
|
|
|
},
|
2016-09-08 13:11:39 -04:00
|
|
|
}
|
2017-06-27 12:55:10 -04:00
|
|
|
|
|
|
|
flags := cmd.Flags()
|
|
|
|
addDetachFlag(flags, &options.detach)
|
|
|
|
return cmd
|
2016-09-08 13:11:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func scaleArgs(cmd *cobra.Command, args []string) error {
|
|
|
|
if err := cli.RequiresMinArgs(1)(cmd, args); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, arg := range args {
|
2022-12-27 10:27:13 -05:00
|
|
|
if k, v, ok := strings.Cut(arg, "="); !ok || k == "" || v == "" {
|
2017-03-09 13:23:45 -05:00
|
|
|
return errors.Errorf(
|
2016-09-08 13:11:39 -04:00
|
|
|
"Invalid scale specifier '%s'.\nSee '%s --help'.\n\nUsage: %s\n\n%s",
|
|
|
|
arg,
|
|
|
|
cmd.CommandPath(),
|
|
|
|
cmd.UseLine(),
|
|
|
|
cmd.Short,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-09 18:27:44 -04:00
|
|
|
func runScale(ctx context.Context, dockerCli command.Cli, options *scaleOptions, args []string) error {
|
2017-03-09 13:23:45 -05:00
|
|
|
var errs []string
|
2017-06-30 06:04:49 -04:00
|
|
|
var serviceIDs []string
|
2017-06-27 12:55:10 -04:00
|
|
|
|
2016-09-08 13:11:39 -04:00
|
|
|
for _, arg := range args {
|
2022-12-27 10:27:13 -05:00
|
|
|
serviceID, scaleStr, _ := strings.Cut(arg, "=")
|
2016-09-19 04:40:44 -04:00
|
|
|
|
|
|
|
// validate input arg scale number
|
|
|
|
scale, err := strconv.ParseUint(scaleStr, 10, 64)
|
|
|
|
if err != nil {
|
2017-03-09 13:23:45 -05:00
|
|
|
errs = append(errs, fmt.Sprintf("%s: invalid replicas value %s: %v", serviceID, scaleStr, err))
|
2016-09-19 04:40:44 -04:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-06-27 12:55:10 -04:00
|
|
|
if err := runServiceScale(ctx, dockerCli, serviceID, scale); err != nil {
|
|
|
|
errs = append(errs, fmt.Sprintf("%s: %v", serviceID, err))
|
2017-06-30 06:04:49 -04:00
|
|
|
} else {
|
|
|
|
serviceIDs = append(serviceIDs, serviceID)
|
2017-06-27 12:55:10 -04:00
|
|
|
}
|
2016-09-08 13:11:39 -04:00
|
|
|
}
|
|
|
|
|
2017-06-30 06:04:49 -04:00
|
|
|
if len(serviceIDs) > 0 {
|
Use non-detached mode as default for service commands
Commit 330a0035334871d92207b583c1c36d52a244753f added a `--detach=false` option
to various service-related commands, with the intent to make this the default in
a future version (17.09).
This patch changes the default to use "interactive" (non-detached), allowing
users to override this by setting the `--detach` option.
To prevent problems when connecting to older daemon versions (17.05 and below,
see commit db60f255617fd90cb093813dcdfe7eec840eeff8), the detach option is
ignored for those versions, and detach is always true.
Before this change, a warning was printed to announce the upcoming default:
$ docker service create nginx:alpine
saxiyn3pe559d753730zr0xer
Since --detach=false was not specified, tasks will be created in the background.
In a future release, --detach=false will become the default.
After this change, no warning is printed, but `--detach` is disabled;
$ docker service create nginx:alpine
y9jujwzozi0hwgj5yaadzliq6
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
Setting the `--detach` flag makes the cli use the pre-17.06 behavior:
$ docker service create --detach nginx:alpine
280hjnzy0wzje5o56gr22a46n
Running against a 17.03 daemon, without specifying the `--detach` flag;
$ docker service create nginx:alpine
kqheg7ogj0kszoa34g4p73i8q
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-09-12 08:35:19 -04:00
|
|
|
if !options.detach && versions.GreaterThanOrEqualTo(dockerCli.Client().ClientVersion(), "1.29") {
|
2017-06-30 06:04:49 -04:00
|
|
|
for _, serviceID := range serviceIDs {
|
2023-05-05 10:00:30 -04:00
|
|
|
if err := WaitOnService(ctx, dockerCli, serviceID, false); err != nil {
|
2017-06-30 06:04:49 -04:00
|
|
|
errs = append(errs, fmt.Sprintf("%s: %v", serviceID, err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-06-27 12:55:10 -04:00
|
|
|
}
|
|
|
|
|
2017-03-09 13:23:45 -05:00
|
|
|
if len(errs) == 0 {
|
2016-09-08 13:11:39 -04:00
|
|
|
return nil
|
|
|
|
}
|
2024-08-26 07:52:49 -04:00
|
|
|
return errors.New(strings.Join(errs, "\n"))
|
2016-09-08 13:11:39 -04:00
|
|
|
}
|
|
|
|
|
2017-07-20 04:32:51 -04:00
|
|
|
func runServiceScale(ctx context.Context, dockerCli command.Cli, serviceID string, scale uint64) error {
|
2016-09-08 13:11:39 -04:00
|
|
|
client := dockerCli.Client()
|
|
|
|
|
2017-03-30 20:15:54 -04:00
|
|
|
service, _, err := client.ServiceInspectWithRaw(ctx, serviceID, types.ServiceInspectOptions{})
|
2016-09-08 13:11:39 -04:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
serviceMode := &service.Spec.Mode
|
2023-11-20 07:54:53 -05:00
|
|
|
switch {
|
|
|
|
case serviceMode.Replicated != nil:
|
2020-01-09 13:17:43 -05:00
|
|
|
serviceMode.Replicated.Replicas = &scale
|
2023-11-20 07:54:53 -05:00
|
|
|
case serviceMode.ReplicatedJob != nil:
|
2020-01-09 13:17:43 -05:00
|
|
|
serviceMode.ReplicatedJob.TotalCompletions = &scale
|
2023-11-20 07:54:53 -05:00
|
|
|
default:
|
2020-01-09 13:17:43 -05:00
|
|
|
return errors.Errorf("scale can only be used with replicated or replicated-job mode")
|
2016-09-08 13:11:39 -04:00
|
|
|
}
|
2016-09-19 04:40:44 -04:00
|
|
|
|
2016-11-14 21:08:24 -05:00
|
|
|
response, err := client.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{})
|
2016-09-08 13:11:39 -04:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-11-14 21:08:24 -05:00
|
|
|
for _, warning := range response.Warnings {
|
|
|
|
fmt.Fprintln(dockerCli.Err(), warning)
|
|
|
|
}
|
|
|
|
|
2016-09-19 04:40:44 -04:00
|
|
|
fmt.Fprintf(dockerCli.Out(), "%s scaled to %d\n", serviceID, scale)
|
2016-09-08 13:11:39 -04:00
|
|
|
return nil
|
|
|
|
}
|