join.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package swarm
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/docker/docker/api/client"
  6. "github.com/docker/docker/cli"
  7. "github.com/docker/engine-api/types/swarm"
  8. "github.com/spf13/cobra"
  9. "golang.org/x/net/context"
  10. )
  11. type joinOptions struct {
  12. remote string
  13. listenAddr NodeAddrOption
  14. // Not a NodeAddrOption because it has no default port.
  15. advertiseAddr string
  16. token string
  17. }
  18. func newJoinCommand(dockerCli *client.DockerCli) *cobra.Command {
  19. opts := joinOptions{
  20. listenAddr: NewListenAddrOption(),
  21. }
  22. cmd := &cobra.Command{
  23. Use: "join [OPTIONS] HOST:PORT",
  24. Short: "Join a swarm as a node and/or manager",
  25. Args: cli.ExactArgs(1),
  26. RunE: func(cmd *cobra.Command, args []string) error {
  27. opts.remote = args[0]
  28. return runJoin(dockerCli, opts)
  29. },
  30. }
  31. flags := cmd.Flags()
  32. flags.Var(&opts.listenAddr, flagListenAddr, "Listen address (format: <ip|interface>[:port])")
  33. flags.StringVar(&opts.advertiseAddr, flagAdvertiseAddr, "", "Advertised address (format: <ip|interface>[:port])")
  34. flags.StringVar(&opts.token, flagToken, "", "Token for entry into the swarm")
  35. return cmd
  36. }
  37. func runJoin(dockerCli *client.DockerCli, opts joinOptions) error {
  38. client := dockerCli.Client()
  39. ctx := context.Background()
  40. req := swarm.JoinRequest{
  41. JoinToken: opts.token,
  42. ListenAddr: opts.listenAddr.String(),
  43. AdvertiseAddr: opts.advertiseAddr,
  44. RemoteAddrs: []string{opts.remote},
  45. }
  46. err := client.SwarmJoin(ctx, req)
  47. if err != nil {
  48. return err
  49. }
  50. info, err := client.Info(ctx)
  51. if err != nil {
  52. return err
  53. }
  54. _, _, err = client.NodeInspectWithRaw(ctx, info.Swarm.NodeID)
  55. if err != nil {
  56. // TODO(aaronl): is there a better way to do this?
  57. if strings.Contains(err.Error(), "This node is not a swarm manager.") {
  58. fmt.Fprintln(dockerCli.Out(), "This node joined a swarm as a worker.")
  59. }
  60. } else {
  61. fmt.Fprintln(dockerCli.Out(), "This node joined a swarm as a manager.")
  62. }
  63. return nil
  64. }