github.com/justincormack/cli@v0.0.0-20201215022714-831ebeae9675/cli/command/container/update.go (about)

     1  package container
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/docker/cli/cli"
     9  	"github.com/docker/cli/cli/command"
    10  	"github.com/docker/cli/opts"
    11  	containertypes "github.com/docker/docker/api/types/container"
    12  	"github.com/pkg/errors"
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  type updateOptions struct {
    17  	blkioWeight        uint16
    18  	cpuPeriod          int64
    19  	cpuQuota           int64
    20  	cpuRealtimePeriod  int64
    21  	cpuRealtimeRuntime int64
    22  	cpusetCpus         string
    23  	cpusetMems         string
    24  	cpuShares          int64
    25  	memory             opts.MemBytes
    26  	memoryReservation  opts.MemBytes
    27  	memorySwap         opts.MemSwapBytes
    28  	kernelMemory       opts.MemBytes
    29  	restartPolicy      string
    30  	pidsLimit          int64
    31  	cpus               opts.NanoCPUs
    32  
    33  	nFlag int
    34  
    35  	containers []string
    36  }
    37  
    38  // NewUpdateCommand creates a new cobra.Command for `docker update`
    39  func NewUpdateCommand(dockerCli command.Cli) *cobra.Command {
    40  	var options updateOptions
    41  
    42  	cmd := &cobra.Command{
    43  		Use:   "update [OPTIONS] CONTAINER [CONTAINER...]",
    44  		Short: "Update configuration of one or more containers",
    45  		Args:  cli.RequiresMinArgs(1),
    46  		RunE: func(cmd *cobra.Command, args []string) error {
    47  			options.containers = args
    48  			options.nFlag = cmd.Flags().NFlag()
    49  			return runUpdate(dockerCli, &options)
    50  		},
    51  	}
    52  
    53  	flags := cmd.Flags()
    54  	flags.Uint16Var(&options.blkioWeight, "blkio-weight", 0, "Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)")
    55  	flags.Int64Var(&options.cpuPeriod, "cpu-period", 0, "Limit CPU CFS (Completely Fair Scheduler) period")
    56  	flags.Int64Var(&options.cpuQuota, "cpu-quota", 0, "Limit CPU CFS (Completely Fair Scheduler) quota")
    57  	flags.Int64Var(&options.cpuRealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds")
    58  	flags.SetAnnotation("cpu-rt-period", "version", []string{"1.25"})
    59  	flags.Int64Var(&options.cpuRealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds")
    60  	flags.SetAnnotation("cpu-rt-runtime", "version", []string{"1.25"})
    61  	flags.StringVar(&options.cpusetCpus, "cpuset-cpus", "", "CPUs in which to allow execution (0-3, 0,1)")
    62  	flags.StringVar(&options.cpusetMems, "cpuset-mems", "", "MEMs in which to allow execution (0-3, 0,1)")
    63  	flags.Int64VarP(&options.cpuShares, "cpu-shares", "c", 0, "CPU shares (relative weight)")
    64  	flags.VarP(&options.memory, "memory", "m", "Memory limit")
    65  	flags.Var(&options.memoryReservation, "memory-reservation", "Memory soft limit")
    66  	flags.Var(&options.memorySwap, "memory-swap", "Swap limit equal to memory plus swap: '-1' to enable unlimited swap")
    67  	flags.Var(&options.kernelMemory, "kernel-memory", "Kernel memory limit")
    68  	flags.StringVar(&options.restartPolicy, "restart", "", "Restart policy to apply when a container exits")
    69  	flags.Int64Var(&options.pidsLimit, "pids-limit", 0, "Tune container pids limit (set -1 for unlimited)")
    70  	flags.SetAnnotation("pids-limit", "version", []string{"1.40"})
    71  
    72  	flags.Var(&options.cpus, "cpus", "Number of CPUs")
    73  	flags.SetAnnotation("cpus", "version", []string{"1.29"})
    74  
    75  	return cmd
    76  }
    77  
    78  func runUpdate(dockerCli command.Cli, options *updateOptions) error {
    79  	var err error
    80  
    81  	if options.nFlag == 0 {
    82  		return errors.New("you must provide one or more flags when using this command")
    83  	}
    84  
    85  	var restartPolicy containertypes.RestartPolicy
    86  	if options.restartPolicy != "" {
    87  		restartPolicy, err = opts.ParseRestartPolicy(options.restartPolicy)
    88  		if err != nil {
    89  			return err
    90  		}
    91  	}
    92  
    93  	resources := containertypes.Resources{
    94  		BlkioWeight:        options.blkioWeight,
    95  		CpusetCpus:         options.cpusetCpus,
    96  		CpusetMems:         options.cpusetMems,
    97  		CPUShares:          options.cpuShares,
    98  		Memory:             options.memory.Value(),
    99  		MemoryReservation:  options.memoryReservation.Value(),
   100  		MemorySwap:         options.memorySwap.Value(),
   101  		KernelMemory:       options.kernelMemory.Value(),
   102  		CPUPeriod:          options.cpuPeriod,
   103  		CPUQuota:           options.cpuQuota,
   104  		CPURealtimePeriod:  options.cpuRealtimePeriod,
   105  		CPURealtimeRuntime: options.cpuRealtimeRuntime,
   106  		NanoCPUs:           options.cpus.Value(),
   107  	}
   108  
   109  	if options.pidsLimit != 0 {
   110  		resources.PidsLimit = &options.pidsLimit
   111  	}
   112  
   113  	updateConfig := containertypes.UpdateConfig{
   114  		Resources:     resources,
   115  		RestartPolicy: restartPolicy,
   116  	}
   117  
   118  	ctx := context.Background()
   119  
   120  	var (
   121  		warns []string
   122  		errs  []string
   123  	)
   124  	for _, container := range options.containers {
   125  		r, err := dockerCli.Client().ContainerUpdate(ctx, container, updateConfig)
   126  		if err != nil {
   127  			errs = append(errs, err.Error())
   128  		} else {
   129  			fmt.Fprintln(dockerCli.Out(), container)
   130  		}
   131  		warns = append(warns, r.Warnings...)
   132  	}
   133  	if len(warns) > 0 {
   134  		fmt.Fprintln(dockerCli.Out(), strings.Join(warns, "\n"))
   135  	}
   136  	if len(errs) > 0 {
   137  		return errors.New(strings.Join(errs, "\n"))
   138  	}
   139  	return nil
   140  }