update.go 4.8 KB

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