code: func (c *Cluster) Info() types.Info {
  	info := types.Info{
  		NodeAddr: c.GetAdvertiseAddress(),
  	}
  	c.mu.RLock()
  	defer c.mu.RUnlock()
  
  	state := c.currentNodeState()
  	info.LocalNodeState = state.status
  	if state.err != nil {
  		info.Error = state.err.Error()
  	}
  
  	ctx, cancel := c.getRequestContext()
  	defer cancel()
  
  	if state.IsActiveManager() {
  		info.ControlAvailable = true
  		swarm, err := c.inspect(ctx, state)
  		if err != nil {
  			info.Error = err.Error()
  		}
  
  		info.Cluster = &swarm.ClusterInfo
  
  		if r, err := state.controlClient.ListNodes(ctx, &swarmapi.ListNodesRequest{}); err != nil {
  			info.Error = err.Error()
  		} else {
  			info.Nodes = len(r.Nodes)
  			for _, n := range r.Nodes {
  				if n.ManagerStatus != nil {
  					info.Managers = info.Managers + 1
  				}
  			}
  		}
  
  		switch info.LocalNodeState {
  		case types.LocalNodeStateInactive, types.LocalNodeStateLocked, types.LocalNodeStateError:
  			// nothing to do
  		default:
  			if info.Managers == 2 {
  				const warn string = `WARNING: Running Swarm in a two-manager configuration. This configuration provides
           no fault tolerance, and poses a high risk to lose control over the cluster.
           Refer to https://docs.docker.com/engine/swarm/admin_guide/ to configure the
           Swarm for fault-tolerance.`
  
  				info.Warnings = append(info.Warnings, warn)
  			}
  		}
  	}
  
  	if state.swarmNode != nil {
  		for _, r := range state.swarmNode.Remotes() {
  			info.RemoteManagers = append(info.RemoteManagers, types.Peer{NodeID: r.NodeID, Addr: r.Addr})
  		}
  		info.NodeID = state.swarmNode.NodeID()
  	}
  
  	return info
  }
docs: // Info returns information about the current cluster state.