update.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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.Int64Var(&opts.cpuRealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds")
  50. flags.StringVar(&opts.cpusetCpus, "cpuset-cpus", "", "CPUs in which to allow execution (0-3, 0,1)")
  51. flags.StringVar(&opts.cpusetMems, "cpuset-mems", "", "MEMs in which to allow execution (0-3, 0,1)")
  52. flags.Int64VarP(&opts.cpuShares, "cpu-shares", "c", 0, "CPU shares (relative weight)")
  53. flags.StringVarP(&opts.memoryString, "memory", "m", "", "Memory limit")
  54. flags.StringVar(&opts.memoryReservation, "memory-reservation", "", "Memory soft limit")
  55. flags.StringVar(&opts.memorySwap, "memory-swap", "", "Swap limit equal to memory plus swap: '-1' to enable unlimited swap")
  56. flags.StringVar(&opts.kernelMemory, "kernel-memory", "", "Kernel memory limit")
  57. flags.StringVar(&opts.restartPolicy, "restart", "", "Restart policy to apply when a container exits")
  58. return cmd
  59. }
  60. func runUpdate(dockerCli *command.DockerCli, opts *updateOptions) error {
  61. var err error
  62. if opts.nFlag == 0 {
  63. return errors.New("You must provide one or more flags when using this command.")
  64. }
  65. var memory int64
  66. if opts.memoryString != "" {
  67. memory, err = units.RAMInBytes(opts.memoryString)
  68. if err != nil {
  69. return err
  70. }
  71. }
  72. var memoryReservation int64
  73. if opts.memoryReservation != "" {
  74. memoryReservation, err = units.RAMInBytes(opts.memoryReservation)
  75. if err != nil {
  76. return err
  77. }
  78. }
  79. var memorySwap int64
  80. if opts.memorySwap != "" {
  81. if opts.memorySwap == "-1" {
  82. memorySwap = -1
  83. } else {
  84. memorySwap, err = units.RAMInBytes(opts.memorySwap)
  85. if err != nil {
  86. return err
  87. }
  88. }
  89. }
  90. var kernelMemory int64
  91. if opts.kernelMemory != "" {
  92. kernelMemory, err = units.RAMInBytes(opts.kernelMemory)
  93. if err != nil {
  94. return err
  95. }
  96. }
  97. var restartPolicy containertypes.RestartPolicy
  98. if opts.restartPolicy != "" {
  99. restartPolicy, err = runconfigopts.ParseRestartPolicy(opts.restartPolicy)
  100. if err != nil {
  101. return err
  102. }
  103. }
  104. resources := containertypes.Resources{
  105. BlkioWeight: opts.blkioWeight,
  106. CpusetCpus: opts.cpusetCpus,
  107. CpusetMems: opts.cpusetMems,
  108. CPUShares: opts.cpuShares,
  109. Memory: memory,
  110. MemoryReservation: memoryReservation,
  111. MemorySwap: memorySwap,
  112. KernelMemory: kernelMemory,
  113. CPUPeriod: opts.cpuPeriod,
  114. CPUQuota: opts.cpuQuota,
  115. CPURealtimePeriod: opts.cpuRealtimePeriod,
  116. CPURealtimeRuntime: opts.cpuRealtimeRuntime,
  117. }
  118. updateConfig := containertypes.UpdateConfig{
  119. Resources: resources,
  120. RestartPolicy: restartPolicy,
  121. }
  122. ctx := context.Background()
  123. var (
  124. warns []string
  125. errs []string
  126. )
  127. for _, container := range opts.containers {
  128. r, err := dockerCli.Client().ContainerUpdate(ctx, container, updateConfig)
  129. if err != nil {
  130. errs = append(errs, err.Error())
  131. } else {
  132. fmt.Fprintln(dockerCli.Out(), container)
  133. }
  134. warns = append(warns, r.Warnings...)
  135. }
  136. if len(warns) > 0 {
  137. fmt.Fprintln(dockerCli.Out(), strings.Join(warns, "\n"))
  138. }
  139. if len(errs) > 0 {
  140. return errors.New(strings.Join(errs, "\n"))
  141. }
  142. return nil
  143. }