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

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package command
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  	"os"
    10  	"strings"
    11  
    12  	"github.com/hernad/nomad/helper/raftutil"
    13  	"github.com/posener/complete"
    14  )
    15  
    16  type OperatorRaftStateCommand struct {
    17  	Meta
    18  }
    19  
    20  func (c *OperatorRaftStateCommand) Help() string {
    21  	helpText := `
    22  Usage: nomad operator raft state <path to nomad data dir>
    23  
    24    Display the server state obtained by replaying raft log entries persisted in
    25    the Nomad data directory in JSON format.
    26  
    27    This command requires file system permissions to access the data directory on
    28    disk. The Nomad server locks access to the data directory, so this command
    29    cannot be run on a data directory that is being used by a running Nomad server.
    30  
    31    This is a low-level debugging tool and not subject to Nomad's usual backward
    32    compatibility guarantees.
    33  
    34  Options:
    35  
    36    -last-index=<last_index>
    37      Set the last log index to be applied, to drop spurious log entries not
    38      properly committed. If passed last_index is zero or negative, it's perceived
    39      as an offset from the last index seen in raft.
    40  `
    41  	return strings.TrimSpace(helpText)
    42  }
    43  
    44  func (c *OperatorRaftStateCommand) AutocompleteFlags() complete.Flags {
    45  	return complete.Flags{}
    46  }
    47  
    48  func (c *OperatorRaftStateCommand) AutocompleteArgs() complete.Predictor {
    49  	return complete.PredictNothing
    50  }
    51  
    52  func (c *OperatorRaftStateCommand) Synopsis() string {
    53  	return "Display raft server state"
    54  }
    55  
    56  func (c *OperatorRaftStateCommand) Name() string { return "operator raft state" }
    57  
    58  func (c *OperatorRaftStateCommand) Run(args []string) int {
    59  	var fLastIdx int64
    60  
    61  	flags := c.Meta.FlagSet(c.Name(), 0)
    62  	flags.Usage = func() { fmt.Println(c.Help()) }
    63  	flags.Int64Var(&fLastIdx, "last-index", 0, "")
    64  
    65  	if err := flags.Parse(args); err != nil {
    66  		c.Ui.Error(fmt.Sprintf("Failed to parse args: %v", err))
    67  		return 1
    68  	}
    69  	args = flags.Args()
    70  
    71  	if len(args) != 1 {
    72  		c.Ui.Error("This command takes one argument: <path>")
    73  		c.Ui.Error(commandErrorText(c))
    74  
    75  		return 1
    76  	}
    77  
    78  	// Find raft.db folder
    79  	raftPath, err := raftutil.FindRaftDir(args[0])
    80  	if err != nil {
    81  		c.Ui.Error(err.Error())
    82  		return 1
    83  	}
    84  
    85  	fsm, err := raftutil.NewFSM(raftPath)
    86  	if err != nil {
    87  		c.Ui.Error(err.Error())
    88  		return 1
    89  	}
    90  	defer fsm.Close()
    91  
    92  	_, _, err = fsm.ApplyAll()
    93  	if err != nil {
    94  		c.Ui.Error(err.Error())
    95  		return 1
    96  	}
    97  
    98  	state := fsm.StateAsMap()
    99  	enc := json.NewEncoder(os.Stdout)
   100  	enc.SetIndent("", "  ")
   101  	if err := enc.Encode(state); err != nil {
   102  		c.Ui.Error(fmt.Sprintf("failed to encode output: %v", err))
   103  		return 1
   104  	}
   105  
   106  	return 0
   107  }