github.com/kobeld/docker@v1.12.0-rc1/api/client/service/scale.go (about)

     1  package service
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"golang.org/x/net/context"
     9  
    10  	"github.com/docker/docker/api/client"
    11  	"github.com/docker/docker/cli"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  func newScaleCommand(dockerCli *client.DockerCli) *cobra.Command {
    16  	return &cobra.Command{
    17  		Use:   "scale SERVICE=SCALE [SERVICE=SCALE...]",
    18  		Short: "Scale one or multiple services",
    19  		Args:  scaleArgs,
    20  		RunE: func(cmd *cobra.Command, args []string) error {
    21  			return runScale(dockerCli, args)
    22  		},
    23  	}
    24  }
    25  
    26  func scaleArgs(cmd *cobra.Command, args []string) error {
    27  	if err := cli.RequiresMinArgs(1)(cmd, args); err != nil {
    28  		return err
    29  	}
    30  	for _, arg := range args {
    31  		if parts := strings.SplitN(arg, "=", 2); len(parts) != 2 {
    32  			return fmt.Errorf(
    33  				"Invalid scale specifier '%s'.\nSee '%s --help'.\n\nUsage:  %s\n\n%s",
    34  				arg,
    35  				cmd.CommandPath(),
    36  				cmd.UseLine(),
    37  				cmd.Short,
    38  			)
    39  		}
    40  	}
    41  	return nil
    42  }
    43  
    44  func runScale(dockerCli *client.DockerCli, args []string) error {
    45  	var errors []string
    46  	for _, arg := range args {
    47  		parts := strings.SplitN(arg, "=", 2)
    48  		serviceID, scale := parts[0], parts[1]
    49  		if err := runServiceScale(dockerCli, serviceID, scale); err != nil {
    50  			errors = append(errors, fmt.Sprintf("%s: %s", serviceID, err.Error()))
    51  		}
    52  	}
    53  
    54  	if len(errors) == 0 {
    55  		return nil
    56  	}
    57  	return fmt.Errorf(strings.Join(errors, "\n"))
    58  }
    59  
    60  func runServiceScale(dockerCli *client.DockerCli, serviceID string, scale string) error {
    61  	client := dockerCli.Client()
    62  	ctx := context.Background()
    63  
    64  	service, err := client.ServiceInspect(ctx, serviceID)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	serviceMode := &service.Spec.Mode
    70  	if serviceMode.Replicated == nil {
    71  		return fmt.Errorf("scale can only be used with replicated mode")
    72  	}
    73  	uintScale, err := strconv.ParseUint(scale, 10, 64)
    74  	if err != nil {
    75  		return fmt.Errorf("invalid replicas value %s: %s", scale, err.Error())
    76  	}
    77  	serviceMode.Replicated.Replicas = &uintScale
    78  
    79  	err = client.ServiceUpdate(ctx, service.ID, service.Version, service.Spec)
    80  	if err != nil {
    81  		return err
    82  	}
    83  
    84  	fmt.Fprintf(dockerCli.Out(), "%s scaled to %s\n", serviceID, scale)
    85  	return nil
    86  }