github.com/hernad/nomad@v1.6.112/main.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package main 5 6 import ( 7 "bytes" 8 "fmt" 9 "io" 10 "os" 11 "sort" 12 "strings" 13 "text/tabwriter" 14 15 // These packages have init() funcs which check os.Args and drop directly 16 // into their command logic. This is because they are run as separate 17 // processes along side of a task. By early importing them we can avoid 18 // additional code being imported and thus reserving memory. 19 _ "github.com/hernad/nomad/client/allocrunner/taskrunner/getter" 20 _ "github.com/hernad/nomad/client/logmon" 21 _ "github.com/hernad/nomad/drivers/docker/docklog" 22 _ "github.com/hernad/nomad/drivers/shared/executor" 23 24 // Don't move any other code imports above the import block above! 25 "github.com/hernad/nomad/command" 26 "github.com/hernad/nomad/version" 27 "github.com/mitchellh/cli" 28 ) 29 30 var ( 31 // Hidden hides the commands from both help and autocomplete. Commands that 32 // users should not be running should be placed here, versus hiding 33 // subcommands from the main help, which should be filtered out of the 34 // commands above. 35 hidden = []string{ 36 "alloc-status", 37 "check", 38 "client-config", 39 "debug", 40 "eval-status", 41 "executor", 42 "logmon", 43 "node-drain", 44 "node-status", 45 "server-force-leave", 46 "server-join", 47 "server-members", 48 "syslog", 49 "docker_logger", 50 "operator raft _info", 51 "operator raft _logs", 52 "operator raft _state", 53 "operator snapshot _state", 54 } 55 56 // aliases is the list of aliases we want users to be aware of. We hide 57 // these form the help output but autocomplete them. 58 aliases = []string{ 59 "fs", 60 "init", 61 "inspect", 62 "logs", 63 "plan", 64 "validate", 65 } 66 67 // Common commands are grouped separately to call them out to operators. 68 commonCommands = []string{ 69 "run", 70 "stop", 71 "status", 72 "alloc", 73 "job", 74 "node", 75 "agent", 76 } 77 ) 78 79 func main() { 80 os.Exit(Run(os.Args[1:])) 81 } 82 83 func Run(args []string) int { 84 // Create the meta object 85 metaPtr := new(command.Meta) 86 metaPtr.SetupUi(args) 87 88 // The Nomad agent never outputs color 89 agentUi := &cli.BasicUi{ 90 Reader: os.Stdin, 91 Writer: os.Stdout, 92 ErrorWriter: os.Stderr, 93 } 94 95 commands := command.Commands(metaPtr, agentUi) 96 cli := &cli.CLI{ 97 Name: "nomad", 98 Version: version.GetVersion().FullVersionNumber(true), 99 Args: args, 100 Commands: commands, 101 HiddenCommands: hidden, 102 Autocomplete: true, 103 AutocompleteNoDefaultFlags: true, 104 HelpFunc: groupedHelpFunc( 105 cli.BasicHelpFunc("nomad"), 106 ), 107 HelpWriter: os.Stdout, 108 } 109 110 exitCode, err := cli.Run() 111 if err != nil { 112 fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error()) 113 return 1 114 } 115 116 return exitCode 117 } 118 119 func groupedHelpFunc(f cli.HelpFunc) cli.HelpFunc { 120 return func(commands map[string]cli.CommandFactory) string { 121 var b bytes.Buffer 122 tw := tabwriter.NewWriter(&b, 0, 2, 6, ' ', 0) 123 124 fmt.Fprintf(tw, "Usage: nomad [-version] [-help] [-autocomplete-(un)install] <command> [args]\n\n") 125 fmt.Fprintf(tw, "Common commands:\n") 126 for _, v := range commonCommands { 127 printCommand(tw, v, commands[v]) 128 } 129 130 // Filter out common commands and aliased commands from the other 131 // commands output 132 otherCommands := make([]string, 0, len(commands)) 133 for k := range commands { 134 found := false 135 for _, v := range commonCommands { 136 if k == v { 137 found = true 138 break 139 } 140 } 141 142 for _, v := range aliases { 143 if k == v { 144 found = true 145 break 146 } 147 } 148 149 if !found { 150 otherCommands = append(otherCommands, k) 151 } 152 } 153 sort.Strings(otherCommands) 154 155 fmt.Fprintf(tw, "\n") 156 fmt.Fprintf(tw, "Other commands:\n") 157 for _, v := range otherCommands { 158 printCommand(tw, v, commands[v]) 159 } 160 161 tw.Flush() 162 163 return strings.TrimSpace(b.String()) 164 } 165 } 166 167 func printCommand(w io.Writer, name string, cmdFn cli.CommandFactory) { 168 cmd, err := cmdFn() 169 if err != nil { 170 panic(fmt.Sprintf("failed to load %q command: %s", name, err)) 171 } 172 fmt.Fprintf(w, " %s\t%s\n", name, cmd.Synopsis()) 173 }