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 }