1package cluster // import "github.com/docker/docker/daemon/cluster" 2 3import ( 4 "context" 5 6 apitypes "github.com/docker/docker/api/types" 7 types "github.com/docker/docker/api/types/swarm" 8 "github.com/docker/docker/daemon/cluster/convert" 9 "github.com/docker/docker/errdefs" 10 swarmapi "github.com/docker/swarmkit/api" 11) 12 13// GetNodes returns a list of all nodes known to a cluster. 14func (c *Cluster) GetNodes(options apitypes.NodeListOptions) ([]types.Node, error) { 15 c.mu.RLock() 16 defer c.mu.RUnlock() 17 18 state := c.currentNodeState() 19 if !state.IsActiveManager() { 20 return nil, c.errNoManager(state) 21 } 22 23 filters, err := newListNodesFilters(options.Filters) 24 if err != nil { 25 return nil, err 26 } 27 28 ctx, cancel := c.getRequestContext() 29 defer cancel() 30 31 r, err := state.controlClient.ListNodes( 32 ctx, 33 &swarmapi.ListNodesRequest{Filters: filters}) 34 if err != nil { 35 return nil, err 36 } 37 38 nodes := make([]types.Node, 0, len(r.Nodes)) 39 40 for _, node := range r.Nodes { 41 nodes = append(nodes, convert.NodeFromGRPC(*node)) 42 } 43 return nodes, nil 44} 45 46// GetNode returns a node based on an ID. 47func (c *Cluster) GetNode(input string) (types.Node, error) { 48 var node *swarmapi.Node 49 50 if err := c.lockedManagerAction(func(ctx context.Context, state nodeState) error { 51 n, err := getNode(ctx, state.controlClient, input) 52 if err != nil { 53 return err 54 } 55 node = n 56 return nil 57 }); err != nil { 58 return types.Node{}, err 59 } 60 61 return convert.NodeFromGRPC(*node), nil 62} 63 64// UpdateNode updates existing nodes properties. 65func (c *Cluster) UpdateNode(input string, version uint64, spec types.NodeSpec) error { 66 return c.lockedManagerAction(func(ctx context.Context, state nodeState) error { 67 nodeSpec, err := convert.NodeSpecToGRPC(spec) 68 if err != nil { 69 return errdefs.InvalidParameter(err) 70 } 71 72 ctx, cancel := c.getRequestContext() 73 defer cancel() 74 75 currentNode, err := getNode(ctx, state.controlClient, input) 76 if err != nil { 77 return err 78 } 79 80 _, err = state.controlClient.UpdateNode( 81 ctx, 82 &swarmapi.UpdateNodeRequest{ 83 NodeID: currentNode.ID, 84 Spec: &nodeSpec, 85 NodeVersion: &swarmapi.Version{ 86 Index: version, 87 }, 88 }, 89 ) 90 return err 91 }) 92} 93 94// RemoveNode removes a node from a cluster 95func (c *Cluster) RemoveNode(input string, force bool) error { 96 return c.lockedManagerAction(func(ctx context.Context, state nodeState) error { 97 node, err := getNode(ctx, state.controlClient, input) 98 if err != nil { 99 return err 100 } 101 102 _, err = state.controlClient.RemoveNode(ctx, &swarmapi.RemoveNodeRequest{NodeID: node.ID, Force: force}) 103 return err 104 }) 105} 106