update.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package node
  2. import (
  3. "fmt"
  4. "github.com/docker/docker/api/client"
  5. "github.com/docker/docker/cli"
  6. "github.com/docker/docker/opts"
  7. runconfigopts "github.com/docker/docker/runconfig/opts"
  8. "github.com/docker/engine-api/types/swarm"
  9. "github.com/spf13/cobra"
  10. "github.com/spf13/pflag"
  11. "golang.org/x/net/context"
  12. )
  13. func newUpdateCommand(dockerCli *client.DockerCli) *cobra.Command {
  14. nodeOpts := newNodeOptions()
  15. cmd := &cobra.Command{
  16. Use: "update [OPTIONS] NODE",
  17. Short: "Update a node",
  18. Args: cli.ExactArgs(1),
  19. RunE: func(cmd *cobra.Command, args []string) error {
  20. return runUpdate(dockerCli, cmd.Flags(), args[0])
  21. },
  22. }
  23. flags := cmd.Flags()
  24. flags.StringVar(&nodeOpts.role, flagRole, "", "Role of the node (worker/manager)")
  25. flags.StringVar(&nodeOpts.membership, flagMembership, "", "Membership of the node (accepted/rejected)")
  26. flags.StringVar(&nodeOpts.availability, flagAvailability, "", "Availability of the node (active/pause/drain)")
  27. flags.Var(&nodeOpts.annotations.labels, flagLabelAdd, "Add or update a node label (key=value)")
  28. labelKeys := opts.NewListOpts(nil)
  29. flags.Var(&labelKeys, flagLabelRemove, "Remove a node label if exists")
  30. return cmd
  31. }
  32. func runUpdate(dockerCli *client.DockerCli, flags *pflag.FlagSet, nodeID string) error {
  33. success := func(_ string) {
  34. fmt.Fprintln(dockerCli.Out(), nodeID)
  35. }
  36. return updateNodes(dockerCli, []string{nodeID}, mergeNodeUpdate(flags), success)
  37. }
  38. func updateNodes(dockerCli *client.DockerCli, nodes []string, mergeNode func(node *swarm.Node) error, success func(nodeID string)) error {
  39. client := dockerCli.Client()
  40. ctx := context.Background()
  41. for _, nodeID := range nodes {
  42. node, _, err := client.NodeInspectWithRaw(ctx, nodeID)
  43. if err != nil {
  44. return err
  45. }
  46. err = mergeNode(&node)
  47. if err != nil {
  48. return err
  49. }
  50. err = client.NodeUpdate(ctx, node.ID, node.Version, node.Spec)
  51. if err != nil {
  52. return err
  53. }
  54. success(nodeID)
  55. }
  56. return nil
  57. }
  58. func mergeNodeUpdate(flags *pflag.FlagSet) func(*swarm.Node) error {
  59. return func(node *swarm.Node) error {
  60. spec := &node.Spec
  61. if flags.Changed(flagRole) {
  62. str, err := flags.GetString(flagRole)
  63. if err != nil {
  64. return err
  65. }
  66. spec.Role = swarm.NodeRole(str)
  67. }
  68. if flags.Changed(flagMembership) {
  69. str, err := flags.GetString(flagMembership)
  70. if err != nil {
  71. return err
  72. }
  73. spec.Membership = swarm.NodeMembership(str)
  74. }
  75. if flags.Changed(flagAvailability) {
  76. str, err := flags.GetString(flagAvailability)
  77. if err != nil {
  78. return err
  79. }
  80. spec.Availability = swarm.NodeAvailability(str)
  81. }
  82. if spec.Annotations.Labels == nil {
  83. spec.Annotations.Labels = make(map[string]string)
  84. }
  85. if flags.Changed(flagLabelAdd) {
  86. labels := flags.Lookup(flagLabelAdd).Value.(*opts.ListOpts).GetAll()
  87. for k, v := range runconfigopts.ConvertKVStringsToMap(labels) {
  88. spec.Annotations.Labels[k] = v
  89. }
  90. }
  91. if flags.Changed(flagLabelRemove) {
  92. keys := flags.Lookup(flagLabelRemove).Value.(*opts.ListOpts).GetAll()
  93. for _, k := range keys {
  94. // if a key doesn't exist, fail the command explicitly
  95. if _, exists := spec.Annotations.Labels[k]; !exists {
  96. return fmt.Errorf("key %s doesn't exist in node's labels", k)
  97. }
  98. delete(spec.Annotations.Labels, k)
  99. }
  100. }
  101. return nil
  102. }
  103. }
  104. const (
  105. flagRole = "role"
  106. flagMembership = "membership"
  107. flagAvailability = "availability"
  108. flagLabelAdd = "label-add"
  109. flagLabelRemove = "label-rm"
  110. )