github.com/hernad/nomad@v1.6.112/command/node.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package command
     5  
     6  import (
     7  	"fmt"
     8  	"sort"
     9  	"strings"
    10  
    11  	"github.com/hernad/nomad/api"
    12  	"github.com/mitchellh/cli"
    13  )
    14  
    15  type NodeCommand struct {
    16  	Meta
    17  }
    18  
    19  func (f *NodeCommand) Help() string {
    20  	helpText := `
    21  Usage: nomad node <subcommand> [options] [args]
    22  
    23    This command groups subcommands for interacting with nodes. Nodes in Nomad are
    24    agent's that can run submitted workloads. This command can be used to examine
    25    nodes and operate on nodes, such as draining workloads off of them.
    26  
    27    Examine the status of a node:
    28  
    29        $ nomad node status <node-id>
    30  
    31    Mark a node as ineligible for running workloads. This is useful when the node
    32    is expected to be removed or upgraded so new allocations aren't placed on it:
    33  
    34        $ nomad node eligibility -disable <node-id>
    35  
    36    Mark a node to be drained, allowing batch jobs four hours to finish before
    37    forcing them off the node:
    38  
    39        $ nomad node drain -enable -deadline 4h <node-id>
    40  
    41    Please see the individual subcommand help for detailed usage information.
    42  `
    43  
    44  	return strings.TrimSpace(helpText)
    45  }
    46  
    47  func (f *NodeCommand) Synopsis() string {
    48  	return "Interact with nodes"
    49  }
    50  
    51  func (f *NodeCommand) Name() string { return "node" }
    52  
    53  func (f *NodeCommand) Run(args []string) int {
    54  	return cli.RunResultHelp
    55  }
    56  
    57  // formatNodeMeta is used to format node metadata in columns.
    58  func formatNodeMeta(meta map[string]string) string {
    59  	// Print the meta
    60  	keys := make([]string, 0, len(meta))
    61  	for k := range meta {
    62  		keys = append(keys, k)
    63  	}
    64  	sort.Strings(keys)
    65  
    66  	var rows []string
    67  	for _, k := range keys {
    68  		if k != "" {
    69  			rows = append(rows, fmt.Sprintf("%s|%s", k, meta[k]))
    70  		}
    71  	}
    72  
    73  	return formatKV(rows)
    74  }
    75  
    76  // lookupNodeID looks up a nodeID prefix and returns the full ID or an error.
    77  // The error will always be suitable for displaying to users.
    78  func lookupNodeID(client *api.Nodes, nodeID string) (string, error) {
    79  	if len(nodeID) == 1 {
    80  		return "", fmt.Errorf("Node ID must contain at least two characters.")
    81  	}
    82  
    83  	nodeID = sanitizeUUIDPrefix(nodeID)
    84  	nodes, _, err := client.PrefixList(nodeID)
    85  	if err != nil {
    86  		return "", fmt.Errorf("Error querying node: %w", err)
    87  	}
    88  
    89  	if len(nodes) == 0 {
    90  		return "", fmt.Errorf("No node(s) with prefix or id %q found", nodeID)
    91  	}
    92  
    93  	if len(nodes) > 1 {
    94  		return "", fmt.Errorf("Prefix matched multiple nodes\n\n%s",
    95  			formatNodeStubList(nodes, true))
    96  	}
    97  
    98  	return nodes[0].ID, nil
    99  }