join.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package swarm
  2. import (
  3. "fmt"
  4. "strings"
  5. "golang.org/x/net/context"
  6. "github.com/docker/docker/api/types/swarm"
  7. "github.com/docker/docker/cli"
  8. "github.com/docker/docker/cli/command"
  9. "github.com/spf13/cobra"
  10. "github.com/spf13/pflag"
  11. )
  12. type joinOptions struct {
  13. remote string
  14. listenAddr NodeAddrOption
  15. // Not a NodeAddrOption because it has no default port.
  16. advertiseAddr string
  17. token string
  18. availability string
  19. }
  20. func newJoinCommand(dockerCli command.Cli) *cobra.Command {
  21. opts := joinOptions{
  22. listenAddr: NewListenAddrOption(),
  23. }
  24. cmd := &cobra.Command{
  25. Use: "join [OPTIONS] HOST:PORT",
  26. Short: "Join a swarm as a node and/or manager",
  27. Args: cli.ExactArgs(1),
  28. RunE: func(cmd *cobra.Command, args []string) error {
  29. opts.remote = args[0]
  30. return runJoin(dockerCli, cmd.Flags(), opts)
  31. },
  32. }
  33. flags := cmd.Flags()
  34. flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: <ip|interface>[:port])")
  35. flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: <ip|interface>[:port])")
  36. flags.StringVar(&opts.token, flagToken, "", "Token for entry into the swarm")
  37. flags.StringVar(&opts.availability, flagAvailability, "active", "Availability of the node (active/pause/drain)")
  38. return cmd
  39. }
  40. func runJoin(dockerCli command.Cli, flags *pflag.FlagSet, opts joinOptions) error {
  41. client := dockerCli.Client()
  42. ctx := context.Background()
  43. req := swarm.JoinRequest{
  44. JoinToken: opts.token,
  45. ListenAddr: opts.listenAddr.String(),
  46. AdvertiseAddr: opts.advertiseAddr,
  47. RemoteAddrs: []string{opts.remote},
  48. }
  49. if flags.Changed(flagAvailability) {
  50. availability := swarm.NodeAvailability(strings.ToLower(opts.availability))
  51. switch availability {
  52. case swarm.NodeAvailabilityActive, swarm.NodeAvailabilityPause, swarm.NodeAvailabilityDrain:
  53. req.Availability = availability
  54. default:
  55. return fmt.Errorf("invalid availability %q, only active, pause and drain are supported", opts.availability)
  56. }
  57. }
  58. err := client.SwarmJoin(ctx, req)
  59. if err != nil {
  60. return err
  61. }
  62. info, err := client.Info(ctx)
  63. if err != nil {
  64. return err
  65. }
  66. if info.Swarm.ControlAvailable {
  67. fmt.Fprintln(dockerCli.Out(), "This node joined a swarm as a manager.")
  68. } else {
  69. fmt.Fprintln(dockerCli.Out(), "This node joined a swarm as a worker.")
  70. }
  71. return nil
  72. }