github.com/moby/docker@v26.1.3+incompatible/daemon/cluster/nodes.go (about)

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