func (c *Cluster) startNewNode(forceNewCluster bool, listenAddr, joinAddr, secret, cahash string, ismanager bool) (*swarmagent.Node, context.Context, error) { if err := c.checkCompatibility(); err != nil { return nil, nil, err } c.node = nil c.cancelDelay = nil node, err := swarmagent.NewNode(&swarmagent.NodeConfig{ Hostname: c.config.Name, ForceNewCluster: forceNewCluster, ListenControlAPI: filepath.Join(c.root, controlSocket), ListenRemoteAPI: listenAddr, JoinAddr: joinAddr, StateDir: c.root, CAHash: cahash, Secret: secret, Executor: container.NewExecutor(c.config.Backend), HeartbeatTick: 1, ElectionTick: 3, IsManager: ismanager, }) if err != nil { return nil, nil, err } ctx, cancel := context.WithCancel(context.Background()) if err := node.Start(ctx); err != nil { return nil, nil, err } c.node = node c.listenAddr = listenAddr c.saveState() c.config.Backend.SetClusterProvider(c) go func() { err := node.Err(ctx) if err != nil { logrus.Errorf("cluster exited with error: %v", err) } c.Lock() c.conn = nil c.client = nil c.node = nil c.ready = false c.err = err c.Unlock() cancel() }() go func() { select { case <-node.Ready(context.Background()): c.Lock() c.reconnectDelay = initialReconnectDelay c.Unlock() case <-ctx.Done(): } if ctx.Err() == nil { c.Lock() c.ready = true c.err = nil c.Unlock() } c.configEvent <- struct{}{} }() go func() { for conn := range node.ListenControlSocket(ctx) { c.Lock() if c.conn != conn { c.client = swarmapi.NewControlClient(conn) } if c.conn != nil { c.client = nil } c.conn = conn c.Unlock() c.configEvent <- struct{}{} } }() return node, ctx, nil }
func (c *Cluster) startNewNode(forceNewCluster bool, localAddr, remoteAddr, listenAddr, advertiseAddr, joinAddr, joinToken string) (*node, error) { if err := c.config.Backend.IsSwarmCompatible(); err != nil { return nil, err } actualLocalAddr := localAddr if actualLocalAddr == "" { // If localAddr was not specified, resolve it automatically // based on the route to joinAddr. localAddr can only be left // empty on "join". listenHost, _, err := net.SplitHostPort(listenAddr) if err != nil { return nil, fmt.Errorf("could not parse listen address: %v", err) } listenAddrIP := net.ParseIP(listenHost) if listenAddrIP == nil || !listenAddrIP.IsUnspecified() { actualLocalAddr = listenHost } else { if remoteAddr == "" { // Should never happen except using swarms created by // old versions that didn't save remoteAddr. remoteAddr = "8.8.8.8:53" } conn, err := net.Dial("udp", remoteAddr) if err != nil { return nil, fmt.Errorf("could not find local IP address: %v", err) } localHostPort := conn.LocalAddr().String() actualLocalAddr, _, _ = net.SplitHostPort(localHostPort) conn.Close() } } c.node = nil c.cancelDelay = nil c.stop = false n, err := swarmagent.NewNode(&swarmagent.NodeConfig{ Hostname: c.config.Name, ForceNewCluster: forceNewCluster, ListenControlAPI: filepath.Join(c.root, controlSocket), ListenRemoteAPI: listenAddr, AdvertiseRemoteAPI: advertiseAddr, JoinAddr: joinAddr, StateDir: c.root, JoinToken: joinToken, Executor: container.NewExecutor(c.config.Backend), HeartbeatTick: 1, ElectionTick: 3, }) if err != nil { return nil, err } ctx := context.Background() if err := n.Start(ctx); err != nil { return nil, err } node := &node{ Node: n, done: make(chan struct{}), reconnectDelay: initialReconnectDelay, } c.node = node c.localAddr = localAddr c.actualLocalAddr = actualLocalAddr // not saved c.remoteAddr = remoteAddr c.listenAddr = listenAddr c.advertiseAddr = advertiseAddr c.saveState() c.config.Backend.SetClusterProvider(c) go func() { err := n.Err(ctx) if err != nil { logrus.Errorf("cluster exited with error: %v", err) } c.Lock() c.node = nil c.err = err c.Unlock() close(node.done) }() go func() { select { case <-n.Ready(): c.Lock() node.ready = true c.err = nil c.Unlock() case <-ctx.Done(): } c.configEvent <- struct{}{} }() go func() { for conn := range n.ListenControlSocket(ctx) { c.Lock() if node.conn != conn { if conn == nil { node.client = nil } else { node.client = swarmapi.NewControlClient(conn) } } node.conn = conn c.Unlock() c.configEvent <- struct{}{} } }() return node, nil }
func (c *Cluster) startNewNode(forceNewCluster bool, listenAddr, joinAddr, secret, cahash string, ismanager bool) (*node, error) { if err := c.config.Backend.IsSwarmCompatible(); err != nil { return nil, err } c.node = nil c.cancelDelay = nil c.stop = false n, err := swarmagent.NewNode(&swarmagent.NodeConfig{ Hostname: c.config.Name, ForceNewCluster: forceNewCluster, ListenControlAPI: filepath.Join(c.root, controlSocket), ListenRemoteAPI: listenAddr, JoinAddr: joinAddr, StateDir: c.root, CAHash: cahash, Secret: secret, Executor: container.NewExecutor(c.config.Backend), HeartbeatTick: 1, ElectionTick: 3, IsManager: ismanager, }) if err != nil { return nil, err } ctx := context.Background() if err := n.Start(ctx); err != nil { return nil, err } node := &node{ Node: n, done: make(chan struct{}), reconnectDelay: initialReconnectDelay, } c.node = node c.listenAddr = listenAddr c.saveState() c.config.Backend.SetClusterProvider(c) go func() { err := n.Err(ctx) if err != nil { logrus.Errorf("cluster exited with error: %v", err) } c.Lock() c.node = nil c.err = err c.Unlock() close(node.done) }() go func() { select { case <-n.Ready(): c.Lock() node.ready = true c.err = nil c.Unlock() case <-ctx.Done(): } c.configEvent <- struct{}{} }() go func() { for conn := range n.ListenControlSocket(ctx) { c.Lock() if node.conn != conn { if conn == nil { node.client = nil } else { node.client = swarmapi.NewControlClient(conn) } } node.conn = conn c.Unlock() c.configEvent <- struct{}{} } }() return node, nil }
if debugAddr != "" { go func() { // setup listening to give access to pprof, expvar, etc. if err := http.ListenAndServe(debugAddr, nil); err != nil { panic(err) } }() } n, err := agent.NewNode(&agent.NodeConfig{ Hostname: hostname, ForceNewCluster: forceNewCluster, ListenControlAPI: unix, ListenRemoteAPI: addr, JoinAddr: managerAddr, StateDir: stateDir, CAHash: caHash, Secret: secret, Executor: executor, HeartbeatTick: hb, ElectionTick: election, IsManager: ismanager, }) if err != nil { return err } if err := n.Start(ctx); err != nil { return err } c := make(chan os.Signal, 1)
if debugAddr != "" { go func() { // setup listening to give access to pprof, expvar, etc. if err := http.ListenAndServe(debugAddr, nil); err != nil { panic(err) } }() } n, err := agent.NewNode(&agent.NodeConfig{ Hostname: hostname, ForceNewCluster: forceNewCluster, ListenControlAPI: unix, ListenRemoteAPI: addr, JoinAddr: managerAddr, StateDir: stateDir, JoinToken: joinToken, ExternalCAs: externalCAOpt.Value(), Executor: executor, HeartbeatTick: hb, ElectionTick: election, }) if err != nil { return err } if err := n.Start(ctx); err != nil { return err } c := make(chan os.Signal, 1)