diff --git a/api/nodes_test.go b/api/nodes_test.go index 4945b3f99c7..6f6d9449929 100644 --- a/api/nodes_test.go +++ b/api/nodes_test.go @@ -270,6 +270,9 @@ func TestNodes_ToggleEligibility(t *testing.T) { if out.SchedulingEligibility != structs.NodeSchedulingEligible { t.Fatalf("bad eligibility: %v vs %v", out.SchedulingEligibility, structs.NodeSchedulingEligible) } + if out.DrainStrategy != nil { + t.Fatalf("drain strategy should be unset") + } } func TestNodes_Allocations(t *testing.T) { diff --git a/command/acl.go b/command/acl.go index 3a6461a22a2..4cc45a18c3e 100644 --- a/command/acl.go +++ b/command/acl.go @@ -12,11 +12,17 @@ type ACLCommand struct { func (f *ACLCommand) Help() string { helpText := ` -Usage: nomad acl [options] +Usage: nomad acl [options] [args] - Interact with ACL policies and tokens. + This command groups subcommands for interacting with ACL policies and tokens. + Users can bootstrap Nomad's ACL system, create policies that restrict access, + and generate tokens from those policies. - Run nomad acl with no arguments for help on that subcommand. + Bootstrap ACLs: + + $ nomad acl bootstrap + + Please see the individual subcommand help for detailed usage information. ` return strings.TrimSpace(helpText) } diff --git a/command/acl_policy.go b/command/acl_policy.go index 43eaf26dc37..28e9e1be054 100644 --- a/command/acl_policy.go +++ b/command/acl_policy.go @@ -1,13 +1,39 @@ package command -import "github.com/mitchellh/cli" +import ( + "strings" + + "github.com/mitchellh/cli" +) type ACLPolicyCommand struct { Meta } func (f *ACLPolicyCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad acl policy [options] [args] + + This command groups subcommands for interacting with ACL policies. Nomad's ACL + system can be used to control access to data and APIs. ACL policies allow a + set of capabilities or actions to be granted or whitelisted. For a full guide + see: https://www.nomadproject.io/guides/acl.html + + Create an ACL policy: + + $ nomad acl policy apply + + List ACL policies: + + $ nomad acl policy list + + Inspect an ACL policy: + + $ nomad acl policy info + + Please see the individual subcommand help for detailed usage information. +` + return strings.TrimSpace(helpText) } func (f *ACLPolicyCommand) Synopsis() string { diff --git a/command/acl_token.go b/command/acl_token.go index d11f06b6af4..8f1faa50327 100644 --- a/command/acl_token.go +++ b/command/acl_token.go @@ -1,13 +1,39 @@ package command -import "github.com/mitchellh/cli" +import ( + "strings" + + "github.com/mitchellh/cli" +) type ACLTokenCommand struct { Meta } func (f *ACLTokenCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad acl token [options] [args] + + This command groups subcommands for interacting with ACL tokens. Nomad's ACL + system can be used to control access to data and APIs. ACL tokens are + associated with one or more ACL policies which grant specific capabilities. + For a full guide see: https://www.nomadproject.io/guides/acl.html + + Create an ACL token: + + $ nomad acl token create -name "my-token" -policy foo -policy bar + + Lookup a token and display its associated policies: + + $ nomad acl policy info + + Revoke an ACL token: + + $ nomad acl policy delete + + Please see the individual subcommand help for detailed usage information. +` + return strings.TrimSpace(helpText) } func (f *ACLTokenCommand) Synopsis() string { diff --git a/command/alloc.go b/command/alloc.go new file mode 100644 index 00000000000..04f232b3f28 --- /dev/null +++ b/command/alloc.go @@ -0,0 +1,40 @@ +package command + +import ( + "strings" + + "github.com/mitchellh/cli" +) + +type AllocCommand struct { + Meta +} + +func (f *AllocCommand) Help() string { + helpText := ` +Usage: nomad alloc [options] [args] + + This command groups subcommands for interacting with allocations. Users can + inspect the status, examine the filesystem or logs of an allocation. + + Examine an allocations status: + + $ nomad alloc status + + Stream a task's logs: + + $ nomad alloc logs -f + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) +} + +func (f *AllocCommand) Synopsis() string { + return "Interact with allocations" +} + +func (f *AllocCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/fs.go b/command/alloc_fs.go similarity index 95% rename from command/fs.go rename to command/alloc_fs.go index e875c648347..1a59df7743b 100644 --- a/command/fs.go +++ b/command/alloc_fs.go @@ -27,13 +27,14 @@ const ( defaultTailLines int64 = 10 ) -type FSCommand struct { +type AllocFSCommand struct { Meta } -func (f *FSCommand) Help() string { +func (f *AllocFSCommand) Help() string { helpText := ` -Usage: nomad fs [options] +Usage: nomad alloc fs [options] +Alias: nomad fs fs displays either the contents of an allocation directory for the passed allocation, or displays the file at the given path. The path is relative to the root of the alloc @@ -75,11 +76,11 @@ FS Specific Options: return strings.TrimSpace(helpText) } -func (f *FSCommand) Synopsis() string { +func (f *AllocFSCommand) Synopsis() string { return "Inspect the contents of an allocation directory" } -func (c *FSCommand) AutocompleteFlags() complete.Flags { +func (c *AllocFSCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ "-H": complete.PredictNothing, @@ -93,7 +94,7 @@ func (c *FSCommand) AutocompleteFlags() complete.Flags { }) } -func (f *FSCommand) AutocompleteArgs() complete.Predictor { +func (f *AllocFSCommand) AutocompleteArgs() complete.Predictor { return complete.PredictFunc(func(a complete.Args) []string { client, err := f.Meta.Client() if err != nil { @@ -108,11 +109,11 @@ func (f *FSCommand) AutocompleteArgs() complete.Predictor { }) } -func (f *FSCommand) Run(args []string) int { +func (f *AllocFSCommand) Run(args []string) int { var verbose, machine, job, stat, tail, follow bool var numLines, numBytes int64 - flags := f.Meta.FlagSet("fs", FlagSetClient) + flags := f.Meta.FlagSet("alloc fs", FlagSetClient) flags.Usage = func() { f.Ui.Output(f.Help()) } flags.BoolVar(&verbose, "verbose", false, "") flags.BoolVar(&machine, "H", false, "") @@ -333,7 +334,7 @@ func (f *FSCommand) Run(args []string) int { // followFile outputs the contents of the file to stdout relative to the end of // the file. If numLines does not equal -1, then tail -n behavior is used. -func (f *FSCommand) followFile(client *api.Client, alloc *api.Allocation, +func (f *AllocFSCommand) followFile(client *api.Client, alloc *api.Allocation, path, origin string, offset, numLines int64) (io.ReadCloser, error) { cancel := make(chan struct{}) diff --git a/command/fs_test.go b/command/alloc_fs_test.go similarity index 95% rename from command/fs_test.go rename to command/alloc_fs_test.go index 342eeb2a348..0e15b503471 100644 --- a/command/fs_test.go +++ b/command/alloc_fs_test.go @@ -13,7 +13,7 @@ import ( func TestFSCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &FSCommand{} + var _ cli.Command = &AllocFSCommand{} } func TestFSCommand_Fails(t *testing.T) { @@ -22,7 +22,7 @@ func TestFSCommand_Fails(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &FSCommand{Meta: Meta{Ui: ui}} + cmd := &AllocFSCommand{Meta: Meta{Ui: ui}} // Fails on lack of job ID if code := cmd.Run([]string{"-job"}); code != 1 { @@ -95,7 +95,7 @@ func TestFSCommand_AutocompleteArgs(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &FSCommand{Meta: Meta{Ui: ui, flagAddress: url}} + cmd := &AllocFSCommand{Meta: Meta{Ui: ui, flagAddress: url}} // Create a fake alloc state := srv.Agent.Server().State() diff --git a/command/logs.go b/command/alloc_logs.go similarity index 92% rename from command/logs.go rename to command/alloc_logs.go index e0d53c65c18..20ad8356121 100644 --- a/command/logs.go +++ b/command/alloc_logs.go @@ -14,13 +14,14 @@ import ( "github.com/posener/complete" ) -type LogsCommand struct { +type AllocLogsCommand struct { Meta } -func (l *LogsCommand) Help() string { +func (l *AllocLogsCommand) Help() string { helpText := ` -Usage: nomad logs [options] +Usage: nomad alloc logs [options] +Alias: nomad logs Streams the stdout/stderr of the given allocation and task. @@ -57,11 +58,11 @@ Logs Specific Options: return strings.TrimSpace(helpText) } -func (l *LogsCommand) Synopsis() string { +func (l *AllocLogsCommand) Synopsis() string { return "Streams the logs of a task." } -func (c *LogsCommand) AutocompleteFlags() complete.Flags { +func (c *AllocLogsCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ "-stderr": complete.PredictNothing, @@ -74,7 +75,7 @@ func (c *LogsCommand) AutocompleteFlags() complete.Flags { }) } -func (l *LogsCommand) AutocompleteArgs() complete.Predictor { +func (l *AllocLogsCommand) AutocompleteArgs() complete.Predictor { return complete.PredictFunc(func(a complete.Args) []string { client, err := l.Meta.Client() if err != nil { @@ -89,11 +90,11 @@ func (l *LogsCommand) AutocompleteArgs() complete.Predictor { }) } -func (l *LogsCommand) Run(args []string) int { +func (l *AllocLogsCommand) Run(args []string) int { var verbose, job, tail, stderr, follow bool var numLines, numBytes int64 - flags := l.Meta.FlagSet("logs", FlagSetClient) + flags := l.Meta.FlagSet("alloc logs", FlagSetClient) flags.Usage = func() { l.Ui.Output(l.Help()) } flags.BoolVar(&verbose, "verbose", false, "") flags.BoolVar(&job, "job", false, "") @@ -262,7 +263,7 @@ func (l *LogsCommand) Run(args []string) int { // followFile outputs the contents of the file to stdout relative to the end of // the file. -func (l *LogsCommand) followFile(client *api.Client, alloc *api.Allocation, +func (l *AllocLogsCommand) followFile(client *api.Client, alloc *api.Allocation, follow bool, task, logType, origin string, offset int64) (io.ReadCloser, error) { cancel := make(chan struct{}) diff --git a/command/logs_test.go b/command/alloc_logs_test.go similarity index 94% rename from command/logs_test.go rename to command/alloc_logs_test.go index c5662832078..868a9cb9163 100644 --- a/command/logs_test.go +++ b/command/alloc_logs_test.go @@ -13,7 +13,7 @@ import ( func TestLogsCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &LogsCommand{} + var _ cli.Command = &AllocLogsCommand{} } func TestLogsCommand_Fails(t *testing.T) { @@ -22,7 +22,7 @@ func TestLogsCommand_Fails(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &LogsCommand{Meta: Meta{Ui: ui}} + cmd := &AllocLogsCommand{Meta: Meta{Ui: ui}} // Fails on misuse if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { @@ -77,7 +77,7 @@ func TestLogsCommand_AutocompleteArgs(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &LogsCommand{Meta: Meta{Ui: ui, flagAddress: url}} + cmd := &AllocLogsCommand{Meta: Meta{Ui: ui, flagAddress: url}} // Create a fake alloc state := srv.Agent.Server().State() diff --git a/command/alloc_status.go b/command/alloc_status.go index 7abaffcbc0f..7ce4c9e4129 100644 --- a/command/alloc_status.go +++ b/command/alloc_status.go @@ -22,7 +22,7 @@ type AllocStatusCommand struct { func (c *AllocStatusCommand) Help() string { helpText := ` -Usage: nomad alloc-status [options] +Usage: nomad alloc status [options] Display information about existing allocations and its tasks. This command can be used to inspect the current status of an allocation, including its running @@ -87,7 +87,7 @@ func (c *AllocStatusCommand) Run(args []string) int { var short, displayStats, verbose, json bool var tmpl string - flags := c.Meta.FlagSet("alloc-status", FlagSetClient) + flags := c.Meta.FlagSet("alloc status", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&short, "short", false, "") flags.BoolVar(&verbose, "verbose", false, "") diff --git a/command/commands.go b/command/commands.go new file mode 100644 index 00000000000..63a050ad379 --- /dev/null +++ b/command/commands.go @@ -0,0 +1,652 @@ +package command + +import ( + "fmt" + "os" + + "github.com/hashicorp/nomad/command/agent" + "github.com/hashicorp/nomad/version" + "github.com/mitchellh/cli" +) + +const ( + // EnvNomadCLINoColor is an env var that toggles colored UI output. + EnvNomadCLINoColor = `NOMAD_CLI_NO_COLOR` +) + +// DeprecatedCommand is a command that wraps an existing command and prints a +// deprecation notice and points the user to the new command. Deprecated +// commands are always hidden from help output. +type DeprecatedCommand struct { + cli.Command + Meta + + // Old is the old command name, New is the new command name. + Old, New string +} + +// Help wraps the embedded Help command and prints a warning about deprecations. +func (c *DeprecatedCommand) Help() string { + c.warn() + return c.Command.Help() +} + +// Run wraps the embedded Run command and prints a warning about deprecation. +func (c *DeprecatedCommand) Run(args []string) int { + c.warn() + return c.Command.Run(args) +} + +func (c *DeprecatedCommand) warn() { + c.Ui.Warn(wrapAtLength(fmt.Sprintf( + "WARNING! The \"nomad %s\" command is deprecated. Please use \"nomad %s\" "+ + "instead. This command will be removed in Nomad 0.10 (or later).", + c.Old, + c.New))) + c.Ui.Warn("") +} + +// Commands returns the mapping of CLI commands for Nomad. The meta +// parameter lets you set meta options for all commands. +func Commands(metaPtr *Meta) map[string]cli.CommandFactory { + if metaPtr == nil { + metaPtr = new(Meta) + } + + meta := *metaPtr + if meta.Ui == nil { + meta.Ui = &cli.BasicUi{ + Reader: os.Stdin, + Writer: os.Stdout, + ErrorWriter: os.Stderr, + } + } + + all := map[string]cli.CommandFactory{ + "acl": func() (cli.Command, error) { + return &ACLCommand{ + Meta: meta, + }, nil + }, + "acl bootstrap": func() (cli.Command, error) { + return &ACLBootstrapCommand{ + Meta: meta, + }, nil + }, + "acl policy": func() (cli.Command, error) { + return &ACLPolicyCommand{ + Meta: meta, + }, nil + }, + "acl policy apply": func() (cli.Command, error) { + return &ACLPolicyApplyCommand{ + Meta: meta, + }, nil + }, + "acl policy delete": func() (cli.Command, error) { + return &ACLPolicyDeleteCommand{ + Meta: meta, + }, nil + }, + "acl policy info": func() (cli.Command, error) { + return &ACLPolicyInfoCommand{ + Meta: meta, + }, nil + }, + "acl policy list": func() (cli.Command, error) { + return &ACLPolicyListCommand{ + Meta: meta, + }, nil + }, + "acl token": func() (cli.Command, error) { + return &ACLTokenCommand{ + Meta: meta, + }, nil + }, + "acl token create": func() (cli.Command, error) { + return &ACLTokenCreateCommand{ + Meta: meta, + }, nil + }, + "acl token update": func() (cli.Command, error) { + return &ACLTokenUpdateCommand{ + Meta: meta, + }, nil + }, + "acl token delete": func() (cli.Command, error) { + return &ACLTokenDeleteCommand{ + Meta: meta, + }, nil + }, + "acl token info": func() (cli.Command, error) { + return &ACLTokenInfoCommand{ + Meta: meta, + }, nil + }, + "acl token self": func() (cli.Command, error) { + return &ACLTokenSelfCommand{ + Meta: meta, + }, nil + }, + "alloc": func() (cli.Command, error) { + return &AllocCommand{ + Meta: meta, + }, nil + }, + "alloc fs": func() (cli.Command, error) { + return &AllocFSCommand{ + Meta: meta, + }, nil + }, + "alloc logs": func() (cli.Command, error) { + return &AllocLogsCommand{ + Meta: meta, + }, nil + }, + "alloc status": func() (cli.Command, error) { + return &AllocStatusCommand{ + Meta: meta, + }, nil + }, + "alloc-status": func() (cli.Command, error) { + return &AllocStatusCommand{ + Meta: meta, + }, nil + }, + "agent": func() (cli.Command, error) { + return &agent.Command{ + Version: version.GetVersion(), + Ui: meta.Ui, + ShutdownCh: make(chan struct{}), + }, nil + }, + "agent-info": func() (cli.Command, error) { + return &AgentInfoCommand{ + Meta: meta, + }, nil + }, + "check": func() (cli.Command, error) { + return &AgentCheckCommand{ + Meta: meta, + }, nil + }, + "deployment": func() (cli.Command, error) { + return &DeploymentCommand{ + Meta: meta, + }, nil + }, + "deployment fail": func() (cli.Command, error) { + return &DeploymentFailCommand{ + Meta: meta, + }, nil + }, + "deployment list": func() (cli.Command, error) { + return &DeploymentListCommand{ + Meta: meta, + }, nil + }, + "deployment pause": func() (cli.Command, error) { + return &DeploymentPauseCommand{ + Meta: meta, + }, nil + }, + "deployment promote": func() (cli.Command, error) { + return &DeploymentPromoteCommand{ + Meta: meta, + }, nil + }, + "deployment resume": func() (cli.Command, error) { + return &DeploymentResumeCommand{ + Meta: meta, + }, nil + }, + "deployment status": func() (cli.Command, error) { + return &DeploymentStatusCommand{ + Meta: meta, + }, nil + }, + "eval": func() (cli.Command, error) { + return &EvalCommand{ + Meta: meta, + }, nil + }, + "eval status": func() (cli.Command, error) { + return &EvalStatusCommand{ + Meta: meta, + }, nil + }, + "eval-status": func() (cli.Command, error) { + return &EvalStatusCommand{ + Meta: meta, + }, nil + }, + "executor": func() (cli.Command, error) { + return &ExecutorPluginCommand{ + Meta: meta, + }, nil + }, + "fs": func() (cli.Command, error) { + return &AllocFSCommand{ + Meta: meta, + }, nil + }, + "init": func() (cli.Command, error) { + return &JobInitCommand{ + Meta: meta, + }, nil + }, + "inspect": func() (cli.Command, error) { + return &JobInspectCommand{ + Meta: meta, + }, nil + }, + "keygen": func() (cli.Command, error) { + return &OperatorKeygenCommand{ + Meta: meta, + }, nil + }, + "keyring": func() (cli.Command, error) { + return &OperatorKeyringCommand{ + Meta: meta, + }, nil + }, + "job": func() (cli.Command, error) { + return &JobCommand{ + Meta: meta, + }, nil + }, + "job deployments": func() (cli.Command, error) { + return &JobDeploymentsCommand{ + Meta: meta, + }, nil + }, + "job dispatch": func() (cli.Command, error) { + return &JobDispatchCommand{ + Meta: meta, + }, nil + }, + "job history": func() (cli.Command, error) { + return &JobHistoryCommand{ + Meta: meta, + }, nil + }, + "job init": func() (cli.Command, error) { + return &JobInitCommand{ + Meta: meta, + }, nil + }, + "job inspect": func() (cli.Command, error) { + return &JobInspectCommand{ + Meta: meta, + }, nil + }, + "job plan": func() (cli.Command, error) { + return &JobPlanCommand{ + Meta: meta, + }, nil + }, + "job promote": func() (cli.Command, error) { + return &JobPromoteCommand{ + Meta: meta, + }, nil + }, + "job revert": func() (cli.Command, error) { + return &JobRevertCommand{ + Meta: meta, + }, nil + }, + "job run": func() (cli.Command, error) { + return &JobRunCommand{ + Meta: meta, + }, nil + }, + "job status": func() (cli.Command, error) { + return &JobStatusCommand{ + Meta: meta, + }, nil + }, + "job stop": func() (cli.Command, error) { + return &JobStopCommand{ + Meta: meta, + }, nil + }, + "job validate": func() (cli.Command, error) { + return &JobValidateCommand{ + Meta: meta, + }, nil + }, + "logs": func() (cli.Command, error) { + return &AllocLogsCommand{ + Meta: meta, + }, nil + }, + "namespace": func() (cli.Command, error) { + return &NamespaceCommand{ + Meta: meta, + }, nil + }, + "namespace apply": func() (cli.Command, error) { + return &NamespaceApplyCommand{ + Meta: meta, + }, nil + }, + "namespace delete": func() (cli.Command, error) { + return &NamespaceDeleteCommand{ + Meta: meta, + }, nil + }, + "namespace inspect": func() (cli.Command, error) { + return &NamespaceInspectCommand{ + Meta: meta, + }, nil + }, + "namespace list": func() (cli.Command, error) { + return &NamespaceListCommand{ + Meta: meta, + }, nil + }, + "namespace status": func() (cli.Command, error) { + return &NamespaceStatusCommand{ + Meta: meta, + }, nil + }, + "node": func() (cli.Command, error) { + return &NodeCommand{ + Meta: meta, + }, nil + }, + "node config": func() (cli.Command, error) { + return &NodeConfigCommand{ + Meta: meta, + }, nil + }, + "node-drain": func() (cli.Command, error) { + return &NodeDrainCommand{ + Meta: meta, + }, nil + }, + "node drain": func() (cli.Command, error) { + return &NodeDrainCommand{ + Meta: meta, + }, nil + }, + "node eligibility": func() (cli.Command, error) { + return &NodeEligibilityCommand{ + Meta: meta, + }, nil + }, + "node-status": func() (cli.Command, error) { + return &NodeStatusCommand{ + Meta: meta, + }, nil + }, + "node status": func() (cli.Command, error) { + return &NodeStatusCommand{ + Meta: meta, + }, nil + }, + "operator": func() (cli.Command, error) { + return &OperatorCommand{ + Meta: meta, + }, nil + }, + + "operator autopilot": func() (cli.Command, error) { + return &OperatorAutopilotCommand{ + Meta: meta, + }, nil + }, + + "operator autopilot get-config": func() (cli.Command, error) { + return &OperatorAutopilotGetCommand{ + Meta: meta, + }, nil + }, + + "operator autopilot set-config": func() (cli.Command, error) { + return &OperatorAutopilotSetCommand{ + Meta: meta, + }, nil + }, + "operator keygen": func() (cli.Command, error) { + return &OperatorKeygenCommand{ + Meta: meta, + }, nil + }, + "operator keyring": func() (cli.Command, error) { + return &OperatorKeyringCommand{ + Meta: meta, + }, nil + }, + "operator raft": func() (cli.Command, error) { + return &OperatorRaftCommand{ + Meta: meta, + }, nil + }, + + "operator raft list-peers": func() (cli.Command, error) { + return &OperatorRaftListCommand{ + Meta: meta, + }, nil + }, + + "operator raft remove-peer": func() (cli.Command, error) { + return &OperatorRaftRemoveCommand{ + Meta: meta, + }, nil + }, + + "plan": func() (cli.Command, error) { + return &JobPlanCommand{ + Meta: meta, + }, nil + }, + + "quota": func() (cli.Command, error) { + return &QuotaCommand{ + Meta: meta, + }, nil + }, + + "quota apply": func() (cli.Command, error) { + return &QuotaApplyCommand{ + Meta: meta, + }, nil + }, + + "quota delete": func() (cli.Command, error) { + return &QuotaDeleteCommand{ + Meta: meta, + }, nil + }, + + "quota init": func() (cli.Command, error) { + return &QuotaInitCommand{ + Meta: meta, + }, nil + }, + + "quota inspect": func() (cli.Command, error) { + return &QuotaInspectCommand{ + Meta: meta, + }, nil + }, + + "quota list": func() (cli.Command, error) { + return &QuotaListCommand{ + Meta: meta, + }, nil + }, + + "quota status": func() (cli.Command, error) { + return &QuotaStatusCommand{ + Meta: meta, + }, nil + }, + + "run": func() (cli.Command, error) { + return &JobRunCommand{ + Meta: meta, + }, nil + }, + "sentinel": func() (cli.Command, error) { + return &SentinelCommand{ + Meta: meta, + }, nil + }, + "sentinel list": func() (cli.Command, error) { + return &SentinelListCommand{ + Meta: meta, + }, nil + }, + "sentinel apply": func() (cli.Command, error) { + return &SentinelApplyCommand{ + Meta: meta, + }, nil + }, + "sentinel delete": func() (cli.Command, error) { + return &SentinelDeleteCommand{ + Meta: meta, + }, nil + }, + "sentinel read": func() (cli.Command, error) { + return &SentinelReadCommand{ + Meta: meta, + }, nil + }, + "server": func() (cli.Command, error) { + return &ServerCommand{ + Meta: meta, + }, nil + }, + "server force-leave": func() (cli.Command, error) { + return &ServerForceLeaveCommand{ + Meta: meta, + }, nil + }, + "server join": func() (cli.Command, error) { + return &ServerJoinCommand{ + Meta: meta, + }, nil + }, + "server members": func() (cli.Command, error) { + return &ServerMembersCommand{ + Meta: meta, + }, nil + }, + "server-force-leave": func() (cli.Command, error) { + return &ServerForceLeaveCommand{ + Meta: meta, + }, nil + }, + "server-join": func() (cli.Command, error) { + return &ServerJoinCommand{ + Meta: meta, + }, nil + }, + "server-members": func() (cli.Command, error) { + return &ServerMembersCommand{ + Meta: meta, + }, nil + }, + "status": func() (cli.Command, error) { + return &StatusCommand{ + Meta: meta, + }, nil + }, + "stop": func() (cli.Command, error) { + return &JobStopCommand{ + Meta: meta, + }, nil + }, + "ui": func() (cli.Command, error) { + return &UiCommand{ + Meta: meta, + }, nil + }, + "validate": func() (cli.Command, error) { + return &JobValidateCommand{ + Meta: meta, + }, nil + }, + "version": func() (cli.Command, error) { + return &VersionCommand{ + Version: version.GetVersion(), + Ui: meta.Ui, + }, nil + }, + } + + deprecated := map[string]cli.CommandFactory{ + "client-config": func() (cli.Command, error) { + return &DeprecatedCommand{ + Old: "client-config", + New: "node config", + Meta: meta, + Command: &NodeConfigCommand{ + Meta: meta, + }, + }, nil + }, + + "keygen": func() (cli.Command, error) { + return &DeprecatedCommand{ + Old: "keygen", + New: "operator keygen", + Meta: meta, + Command: &OperatorKeygenCommand{ + Meta: meta, + }, + }, nil + }, + + "keyring": func() (cli.Command, error) { + return &DeprecatedCommand{ + Old: "keyring", + New: "operator keyring", + Meta: meta, + Command: &OperatorKeyringCommand{ + Meta: meta, + }, + }, nil + }, + + "server-force-leave": func() (cli.Command, error) { + return &DeprecatedCommand{ + Old: "server-force-leave", + New: "server force-leave", + Meta: meta, + Command: &ServerForceLeaveCommand{ + Meta: meta, + }, + }, nil + }, + + "server-join": func() (cli.Command, error) { + return &DeprecatedCommand{ + Old: "server-join", + New: "server join", + Meta: meta, + Command: &ServerJoinCommand{ + Meta: meta, + }, + }, nil + }, + + "server-members": func() (cli.Command, error) { + return &DeprecatedCommand{ + Old: "server-members", + New: "server members", + Meta: meta, + Command: &ServerMembersCommand{ + Meta: meta, + }, + }, nil + }, + } + + for k, v := range deprecated { + all[k] = v + } + return all +} diff --git a/command/deployment.go b/command/deployment.go index 8c4328a5380..d30bfa4a380 100644 --- a/command/deployment.go +++ b/command/deployment.go @@ -1,13 +1,43 @@ package command -import "github.com/mitchellh/cli" +import ( + "strings" + + "github.com/mitchellh/cli" +) type DeploymentCommand struct { Meta } func (f *DeploymentCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad deployment [options] [args] + + This command groups subcommands for interacting with deployments. Deployments + are used to manage a transistion between two versions of a Nomad job. Users + can inspect an ongoing deployment, promote canary allocations, force fail + deployments, and more. + + Examine a deployments status: + + $ nomad deployment status + + Promote the canaries to allow the remaining allocations to be updated in a + rolling deployment fashion: + + $ nomad deployment promote + + Mark a deployment as failed. This will stop new allocations from being placed + and if the job's upgrade stanza specifies auto_revert, causes the job to + revert back to the last stable version of the job: + + $ nomad deployment fail + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) } func (f *DeploymentCommand) Synopsis() string { diff --git a/command/eval.go b/command/eval.go new file mode 100644 index 00000000000..a1031634f20 --- /dev/null +++ b/command/eval.go @@ -0,0 +1,38 @@ +package command + +import ( + "strings" + + "github.com/mitchellh/cli" +) + +type EvalCommand struct { + Meta +} + +func (f *EvalCommand) Help() string { + helpText := ` +Usage: nomad eval [options] [args] + + This command groups subcommands for interacting with evaluations. Evaluations + are used to trigger a scheduling event. As such, evaluations are an internal + detail but can be useful for debugging placement failures when the cluster + does not have the resources to run a given job. + + Examine an evaluations status: + + $ nomad eval status + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) +} + +func (f *EvalCommand) Synopsis() string { + return "Interact with evaluations" +} + +func (f *EvalCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/eval_status.go b/command/eval_status.go index 0b7dcd0d388..04010fb81d8 100644 --- a/command/eval_status.go +++ b/command/eval_status.go @@ -16,7 +16,7 @@ type EvalStatusCommand struct { func (c *EvalStatusCommand) Help() string { helpText := ` -Usage: nomad eval-status [options] +Usage: nomad eval status [options] Display information about evaluations. This command can be used to inspect the current status of an evaluation as well as determine the reason an evaluation @@ -81,7 +81,7 @@ func (c *EvalStatusCommand) Run(args []string) int { var monitor, verbose, json bool var tmpl string - flags := c.Meta.FlagSet("eval-status", FlagSetClient) + flags := c.Meta.FlagSet("eval status", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&monitor, "monitor", false, "") flags.BoolVar(&verbose, "verbose", false, "") diff --git a/command/helpers.go b/command/helpers.go index 9b1b6fed86b..025dc6555e0 100644 --- a/command/helpers.go +++ b/command/helpers.go @@ -13,11 +13,15 @@ import ( gg "github.com/hashicorp/go-getter" "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/jobspec" + "github.com/kr/text" "github.com/posener/complete" "github.com/ryanuber/columnize" ) +// maxLineLength is the maximum width of any line. +const maxLineLength int = 78 + // formatKV takes a set of strings and formats them into properly // aligned k = v pairs using the columnize library. func formatKV(in []string) string { @@ -53,6 +57,22 @@ func limit(s string, length int) string { return s[:length] } +// wrapAtLengthWithPadding wraps the given text at the maxLineLength, taking +// into account any provided left padding. +func wrapAtLengthWithPadding(s string, pad int) string { + wrapped := text.Wrap(s, maxLineLength-pad) + lines := strings.Split(wrapped, "\n") + for i, line := range lines { + lines[i] = strings.Repeat(" ", pad) + line + } + return strings.Join(lines, "\n") +} + +// wrapAtLength wraps the given text to maxLineLength. +func wrapAtLength(s string) string { + return wrapAtLengthWithPadding(s, 0) +} + // formatTime formats the time to string based on RFC822 func formatTime(t time.Time) string { if t.Unix() < 1 { diff --git a/command/job.go b/command/job.go index 35477146fa6..36d0e1ce276 100644 --- a/command/job.go +++ b/command/job.go @@ -1,13 +1,41 @@ package command -import "github.com/mitchellh/cli" +import ( + "strings" + + "github.com/mitchellh/cli" +) type JobCommand struct { Meta } func (f *JobCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad job [options] [args] + + This command groups subcommands for interacting with jobs. + + Run a new job or update an existing job: + + $ nomad job run + + Plan the run of a job to determine what changes would occur: + + $ nomad job plan + + Stop a running job: + + $ nomad job stop + + Examine the status of a running job: + + $ nomad job status + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) } func (f *JobCommand) Synopsis() string { diff --git a/command/init.go b/command/job_init.go similarity index 97% rename from command/init.go rename to command/job_init.go index 3b6ca2dd067..b03ab73b2c7 100644 --- a/command/init.go +++ b/command/job_init.go @@ -13,15 +13,16 @@ const ( DefaultInitName = "example.nomad" ) -// InitCommand generates a new job template that you can customize to your +// JobInitCommand generates a new job template that you can customize to your // liking, like vagrant init -type InitCommand struct { +type JobInitCommand struct { Meta } -func (c *InitCommand) Help() string { +func (c *JobInitCommand) Help() string { helpText := ` -Usage: nomad init +Usage: nomad job init +Alias: nomad init Creates an example job file that can be used as a starting point to customize further. @@ -29,11 +30,11 @@ Usage: nomad init return strings.TrimSpace(helpText) } -func (c *InitCommand) Synopsis() string { +func (c *JobInitCommand) Synopsis() string { return "Create an example job file" } -func (c *InitCommand) Run(args []string) int { +func (c *JobInitCommand) Run(args []string) int { // Check for misuse if len(args) != 0 { c.Ui.Error(c.Help()) diff --git a/command/init_test.go b/command/job_init_test.go similarity index 95% rename from command/init_test.go rename to command/job_init_test.go index 4c0da57cb6d..dba6618067c 100644 --- a/command/init_test.go +++ b/command/job_init_test.go @@ -11,13 +11,13 @@ import ( func TestInitCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &InitCommand{} + var _ cli.Command = &JobInitCommand{} } func TestInitCommand_Run(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &InitCommand{Meta: Meta{Ui: ui}} + cmd := &JobInitCommand{Meta: Meta{Ui: ui}} // Fails on misuse if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { diff --git a/command/inspect.go b/command/job_inspect.go similarity index 90% rename from command/inspect.go rename to command/job_inspect.go index b16527b59f2..cf7a0491fcf 100644 --- a/command/inspect.go +++ b/command/job_inspect.go @@ -9,13 +9,14 @@ import ( "github.com/posener/complete" ) -type InspectCommand struct { +type JobInspectCommand struct { Meta } -func (c *InspectCommand) Help() string { +func (c *JobInspectCommand) Help() string { helpText := ` -Usage: nomad inspect [options] +Usage: nomad job inspect [options] +Alias: nomad inspect Inspect is used to see the specification of a submitted job. @@ -37,11 +38,11 @@ Inspect Options: return strings.TrimSpace(helpText) } -func (c *InspectCommand) Synopsis() string { +func (c *JobInspectCommand) Synopsis() string { return "Inspect a submitted job" } -func (c *InspectCommand) AutocompleteFlags() complete.Flags { +func (c *JobInspectCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ "-version": complete.PredictAnything, @@ -50,7 +51,7 @@ func (c *InspectCommand) AutocompleteFlags() complete.Flags { }) } -func (c *InspectCommand) AutocompleteArgs() complete.Predictor { +func (c *JobInspectCommand) AutocompleteArgs() complete.Predictor { return complete.PredictFunc(func(a complete.Args) []string { client, err := c.Meta.Client() if err != nil { @@ -65,11 +66,11 @@ func (c *InspectCommand) AutocompleteArgs() complete.Predictor { }) } -func (c *InspectCommand) Run(args []string) int { +func (c *JobInspectCommand) Run(args []string) int { var json bool var tmpl, versionStr string - flags := c.Meta.FlagSet("inspect", FlagSetClient) + flags := c.Meta.FlagSet("job inspect", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&json, "json", false, "") flags.StringVar(&tmpl, "t", "", "") diff --git a/command/inspect_test.go b/command/job_inspect_test.go similarity index 93% rename from command/inspect_test.go rename to command/job_inspect_test.go index 1eb51ff883c..43e6bb0a461 100644 --- a/command/inspect_test.go +++ b/command/job_inspect_test.go @@ -12,7 +12,7 @@ import ( func TestInspectCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &InspectCommand{} + var _ cli.Command = &JobInspectCommand{} } func TestInspectCommand_Fails(t *testing.T) { @@ -21,7 +21,7 @@ func TestInspectCommand_Fails(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &InspectCommand{Meta: Meta{Ui: ui}} + cmd := &JobInspectCommand{Meta: Meta{Ui: ui}} // Fails on misuse if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { @@ -67,7 +67,7 @@ func TestInspectCommand_AutocompleteArgs(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &InspectCommand{Meta: Meta{Ui: ui, flagAddress: url}} + cmd := &JobInspectCommand{Meta: Meta{Ui: ui, flagAddress: url}} state := srv.Agent.Server().State() j := mock.Job() diff --git a/command/plan.go b/command/job_plan.go similarity index 97% rename from command/plan.go rename to command/job_plan.go index c891e17aa41..a87acec8029 100644 --- a/command/plan.go +++ b/command/job_plan.go @@ -14,7 +14,7 @@ import ( const ( jobModifyIndexHelp = `To submit the job with version verification run: -nomad run -check-index %d %s +nomad job run -check-index %d %s When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has @@ -22,14 +22,15 @@ changed, another user has modified the job and the plan's results are potentially invalid.` ) -type PlanCommand struct { +type JobPlanCommand struct { Meta JobGetter } -func (c *PlanCommand) Help() string { +func (c *JobPlanCommand) Help() string { helpText := ` -Usage: nomad plan [options] +Usage: nomad job plan [options] +Alias: nomad plan Plan invokes a dry-run of the scheduler to determine the effects of submitting either a new or updated version of a job. The plan will not result in any @@ -75,11 +76,11 @@ Plan Options: return strings.TrimSpace(helpText) } -func (c *PlanCommand) Synopsis() string { +func (c *JobPlanCommand) Synopsis() string { return "Dry-run a job update to determine its effects" } -func (c *PlanCommand) AutocompleteFlags() complete.Flags { +func (c *JobPlanCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ "-diff": complete.PredictNothing, @@ -88,14 +89,14 @@ func (c *PlanCommand) AutocompleteFlags() complete.Flags { }) } -func (c *PlanCommand) AutocompleteArgs() complete.Predictor { +func (c *JobPlanCommand) AutocompleteArgs() complete.Predictor { return complete.PredictOr(complete.PredictFiles("*.nomad"), complete.PredictFiles("*.hcl")) } -func (c *PlanCommand) Run(args []string) int { +func (c *JobPlanCommand) Run(args []string) int { var diff, policyOverride, verbose bool - flags := c.Meta.FlagSet("plan", FlagSetClient) + flags := c.Meta.FlagSet("job plan", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&diff, "diff", true, "") flags.BoolVar(&policyOverride, "policy-override", false, "") diff --git a/command/plan_test.go b/command/job_plan_test.go similarity index 96% rename from command/plan_test.go rename to command/job_plan_test.go index 97b42476e66..c9360de6d95 100644 --- a/command/plan_test.go +++ b/command/job_plan_test.go @@ -13,13 +13,13 @@ import ( func TestPlanCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &RunCommand{} + var _ cli.Command = &JobRunCommand{} } func TestPlanCommand_Fails(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &PlanCommand{Meta: Meta{Ui: ui}} + cmd := &JobPlanCommand{Meta: Meta{Ui: ui}} // Create a server s := testutil.NewTestServer(t, nil) @@ -118,7 +118,7 @@ func TestPlanCommand_From_STDIN(t *testing.T) { } ui := new(cli.MockUi) - cmd := &PlanCommand{ + cmd := &JobPlanCommand{ Meta: Meta{Ui: ui}, JobGetter: JobGetter{testStdin: stdinR}, } @@ -156,7 +156,7 @@ job "job1" { func TestPlanCommand_From_URL(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &PlanCommand{ + cmd := &JobPlanCommand{ Meta: Meta{Ui: ui}, } diff --git a/command/run.go b/command/job_run.go similarity index 95% rename from command/run.go rename to command/job_run.go index e4d6912394f..6fb19b2bce2 100644 --- a/command/run.go +++ b/command/job_run.go @@ -19,14 +19,15 @@ var ( enforceIndexRegex = regexp.MustCompile(`\((Enforcing job modify index.*)\)`) ) -type RunCommand struct { +type JobRunCommand struct { Meta JobGetter } -func (c *RunCommand) Help() string { +func (c *JobRunCommand) Help() string { helpText := ` -Usage: nomad run [options] +Usage: nomad job run [options] +Alias: nomad run Starts running a new job or updates an existing job using the specification located at . This is the main command @@ -93,11 +94,11 @@ Run Options: return strings.TrimSpace(helpText) } -func (c *RunCommand) Synopsis() string { +func (c *JobRunCommand) Synopsis() string { return "Run a new job or update an existing job" } -func (c *RunCommand) AutocompleteFlags() complete.Flags { +func (c *JobRunCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ "-check-index": complete.PredictNothing, @@ -109,15 +110,15 @@ func (c *RunCommand) AutocompleteFlags() complete.Flags { }) } -func (c *RunCommand) AutocompleteArgs() complete.Predictor { +func (c *JobRunCommand) AutocompleteArgs() complete.Predictor { return complete.PredictOr(complete.PredictFiles("*.nomad"), complete.PredictFiles("*.hcl")) } -func (c *RunCommand) Run(args []string) int { +func (c *JobRunCommand) Run(args []string) int { var detach, verbose, output, override bool var checkIndexStr, vaultToken string - flags := c.Meta.FlagSet("run", FlagSetClient) + flags := c.Meta.FlagSet("job run", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&detach, "detach", false, "") flags.BoolVar(&verbose, "verbose", false, "") diff --git a/command/run_test.go b/command/job_run_test.go similarity index 96% rename from command/run_test.go rename to command/job_run_test.go index c42b3da4327..1db113ddf3a 100644 --- a/command/run_test.go +++ b/command/job_run_test.go @@ -13,13 +13,13 @@ import ( func TestRunCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &RunCommand{} + var _ cli.Command = &JobRunCommand{} } func TestRunCommand_Output_Json(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &RunCommand{Meta: Meta{Ui: ui}} + cmd := &JobRunCommand{Meta: Meta{Ui: ui}} fh, err := ioutil.TempFile("", "nomad") if err != nil { @@ -55,7 +55,7 @@ job "job1" { func TestRunCommand_Fails(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &RunCommand{Meta: Meta{Ui: ui}} + cmd := &JobRunCommand{Meta: Meta{Ui: ui}} // Create a server s := testutil.NewTestServer(t, nil) @@ -164,7 +164,7 @@ func TestRunCommand_From_STDIN(t *testing.T) { } ui := new(cli.MockUi) - cmd := &RunCommand{ + cmd := &JobRunCommand{ Meta: Meta{Ui: ui}, JobGetter: JobGetter{testStdin: stdinR}, } @@ -202,7 +202,7 @@ job "job1" { func TestRunCommand_From_URL(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &RunCommand{ + cmd := &JobRunCommand{ Meta: Meta{Ui: ui}, } diff --git a/command/stop.go b/command/job_stop.go similarity index 91% rename from command/stop.go rename to command/job_stop.go index 258679fec3a..b0da67d8b4e 100644 --- a/command/stop.go +++ b/command/job_stop.go @@ -8,13 +8,14 @@ import ( "github.com/posener/complete" ) -type StopCommand struct { +type JobStopCommand struct { Meta } -func (c *StopCommand) Help() string { +func (c *JobStopCommand) Help() string { helpText := ` -Usage: nomad stop [options] +Usage: nomad job stop [options] +Alias: nomad stop Stop an existing job. This command is used to signal allocations to shut down for the given job ID. Upon successful deregistration, @@ -47,11 +48,11 @@ Stop Options: return strings.TrimSpace(helpText) } -func (c *StopCommand) Synopsis() string { +func (c *JobStopCommand) Synopsis() string { return "Stop a running job" } -func (c *StopCommand) AutocompleteFlags() complete.Flags { +func (c *JobStopCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ "-detach": complete.PredictNothing, @@ -61,7 +62,7 @@ func (c *StopCommand) AutocompleteFlags() complete.Flags { }) } -func (c *StopCommand) AutocompleteArgs() complete.Predictor { +func (c *JobStopCommand) AutocompleteArgs() complete.Predictor { return complete.PredictFunc(func(a complete.Args) []string { client, err := c.Meta.Client() if err != nil { @@ -76,10 +77,10 @@ func (c *StopCommand) AutocompleteArgs() complete.Predictor { }) } -func (c *StopCommand) Run(args []string) int { +func (c *JobStopCommand) Run(args []string) int { var detach, purge, verbose, autoYes bool - flags := c.Meta.FlagSet("stop", FlagSetClient) + flags := c.Meta.FlagSet("job stop", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&detach, "detach", false, "") flags.BoolVar(&verbose, "verbose", false, "") diff --git a/command/stop_test.go b/command/job_stop_test.go similarity index 92% rename from command/stop_test.go rename to command/job_stop_test.go index 2390839fa0e..1389f537c75 100644 --- a/command/stop_test.go +++ b/command/job_stop_test.go @@ -12,7 +12,7 @@ import ( func TestStopCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &StopCommand{} + var _ cli.Command = &JobStopCommand{} } func TestStopCommand_Fails(t *testing.T) { @@ -21,7 +21,7 @@ func TestStopCommand_Fails(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &StopCommand{Meta: Meta{Ui: ui}} + cmd := &JobStopCommand{Meta: Meta{Ui: ui}} // Fails on misuse if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { @@ -58,7 +58,7 @@ func TestStopCommand_AutocompleteArgs(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &StopCommand{Meta: Meta{Ui: ui, flagAddress: url}} + cmd := &JobStopCommand{Meta: Meta{Ui: ui, flagAddress: url}} // Create a fake job state := srv.Agent.Server().State() diff --git a/command/validate.go b/command/job_validate.go similarity index 84% rename from command/validate.go rename to command/job_validate.go index 1dff70da955..950b1e3bba4 100644 --- a/command/validate.go +++ b/command/job_validate.go @@ -11,14 +11,15 @@ import ( "github.com/posener/complete" ) -type ValidateCommand struct { +type JobValidateCommand struct { Meta JobGetter } -func (c *ValidateCommand) Help() string { +func (c *JobValidateCommand) Help() string { helpText := ` -Usage: nomad validate [options] +Usage: nomad job validate [options] +Alias: nomad validate Checks if a given HCL job file has a valid specification. This can be used to check for any syntax errors or validation problems with a job. @@ -30,20 +31,20 @@ Usage: nomad validate [options] return strings.TrimSpace(helpText) } -func (c *ValidateCommand) Synopsis() string { +func (c *JobValidateCommand) Synopsis() string { return "Checks if a given job specification is valid" } -func (c *ValidateCommand) AutocompleteFlags() complete.Flags { +func (c *JobValidateCommand) AutocompleteFlags() complete.Flags { return nil } -func (c *ValidateCommand) AutocompleteArgs() complete.Predictor { +func (c *JobValidateCommand) AutocompleteArgs() complete.Predictor { return complete.PredictOr(complete.PredictFiles("*.nomad"), complete.PredictFiles("*.hcl")) } -func (c *ValidateCommand) Run(args []string) int { - flags := c.Meta.FlagSet("validate", FlagSetNone) +func (c *JobValidateCommand) Run(args []string) int { + flags := c.Meta.FlagSet("job validate", FlagSetNone) flags.Usage = func() { c.Ui.Output(c.Help()) } if err := flags.Parse(args); err != nil { return 1 @@ -110,7 +111,7 @@ func (c *ValidateCommand) Run(args []string) int { } // validateLocal validates without talking to a Nomad agent -func (c *ValidateCommand) validateLocal(aj *api.Job) (*api.JobValidateResponse, error) { +func (c *JobValidateCommand) validateLocal(aj *api.Job) (*api.JobValidateResponse, error) { var out api.JobValidateResponse job := agent.ApiJobToStructJob(aj) diff --git a/command/validate_test.go b/command/job_validate_test.go similarity index 95% rename from command/validate_test.go rename to command/job_validate_test.go index 20902068e0f..516d317503a 100644 --- a/command/validate_test.go +++ b/command/job_validate_test.go @@ -13,13 +13,13 @@ import ( func TestValidateCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &ValidateCommand{} + var _ cli.Command = &JobValidateCommand{} } func TestValidateCommand(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &ValidateCommand{Meta: Meta{Ui: ui}} + cmd := &JobValidateCommand{Meta: Meta{Ui: ui}} // Create a server s := testutil.NewTestServer(t, nil) @@ -60,7 +60,7 @@ job "job1" { func TestValidateCommand_Fails(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &ValidateCommand{Meta: Meta{Ui: ui}} + cmd := &JobValidateCommand{Meta: Meta{Ui: ui}} // Fails on misuse if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { @@ -123,7 +123,7 @@ func TestValidateCommand_From_STDIN(t *testing.T) { } ui := new(cli.MockUi) - cmd := &ValidateCommand{ + cmd := &JobValidateCommand{ Meta: Meta{Ui: ui}, JobGetter: JobGetter{testStdin: stdinR}, } @@ -164,7 +164,7 @@ job "job1" { func TestValidateCommand_From_URL(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &RunCommand{ + cmd := &JobRunCommand{ Meta: Meta{Ui: ui}, } diff --git a/command/meta.go b/command/meta.go index de1addd11a2..8dc96e933fe 100644 --- a/command/meta.go +++ b/command/meta.go @@ -181,7 +181,8 @@ func generalOptionsUsage() string { Defaults to the "default" namespace. -no-color - Disables colored command output. + Disables colored command output. Alternatively, NOMAD_CLI_NO_COLOR may be + set. -ca-cert= Path to a PEM encoded CA cert file to use to verify the diff --git a/command/namespace.go b/command/namespace.go index 5533614a4c6..d43deec8435 100644 --- a/command/namespace.go +++ b/command/namespace.go @@ -1,6 +1,8 @@ package command import ( + "strings" + "github.com/hashicorp/nomad/api/contexts" "github.com/mitchellh/cli" "github.com/posener/complete" @@ -11,7 +13,30 @@ type NamespaceCommand struct { } func (f *NamespaceCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad namespace [options] [args] + + This command groups subcommands for interacting with namespaces. Namespaces + allow jobs and their associated objects to be segmented from each other and + other users of the cluster. For a full guide on namespaces see: + https://www.nomadproject.io/guides/namespaces.html + + Create or update a namespace: + + $ nomad namespace apply -description "My new namespace" + + List namespaces: + + $ nomad namespace list + + View the status of a namespace: + + $ nomad namespace status + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) } func (f *NamespaceCommand) Synopsis() string { diff --git a/command/node.go b/command/node.go index 36436d9b786..0479d0b20ea 100644 --- a/command/node.go +++ b/command/node.go @@ -1,13 +1,41 @@ package command -import "github.com/mitchellh/cli" +import ( + "strings" + + "github.com/mitchellh/cli" +) type NodeCommand struct { Meta } func (f *NodeCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad nomad [options] [args] + + This command groups subcommands for interacting with nodes. Nodes in Nomad are + agent's that can run submitted workloads. This command can be used to examine + nodes and operate on nodes, such as draining workloads off of them. + + Examine the status of a node: + + $ nomad node status + + Mark a node as ineligible for running workloads. This is useful when the node + is expected to be removed or upgraded so new allocations aren't placed on it: + + $ nomad node eligibility -disabled + + Mark a node to be drained, allowing batch jobs four hours to finished before + forcing them off the node: + + $ nomad node drain -enable -deadline 4h + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) } func (f *NodeCommand) Synopsis() string { diff --git a/command/client_config.go b/command/node_config.go similarity index 76% rename from command/client_config.go rename to command/node_config.go index 541b2735fdb..cf88db8bbeb 100644 --- a/command/client_config.go +++ b/command/node_config.go @@ -7,20 +7,20 @@ import ( "github.com/posener/complete" ) -type ClientConfigCommand struct { +type NodeConfigCommand struct { Meta } -func (c *ClientConfigCommand) Help() string { +func (c *NodeConfigCommand) Help() string { helpText := ` -Usage: nomad client-config [options] +Usage: nomad node config [options] - View or modify client configuration details. This command only - works on client nodes, and can be used to update the running - client configurations it supports. + View or modify a client node's configuration details. This command only works + on client nodes, and can be used to update the running client configurations + it supports. - The arguments behave differently depending on the flags given. - See each flag's description for its specific requirements. + The arguments behave differently depending on the flags given. See each + flag's description for its specific requirements. General Options: @@ -41,19 +41,19 @@ Client Config Options: to configure. The set is updated atomically. Example: - $ nomad client-config -update-servers foo:4647 bar:4647 + $ nomad node config -update-servers foo:4647 bar:4647 ` return strings.TrimSpace(helpText) } -func (c *ClientConfigCommand) Synopsis() string { +func (c *NodeConfigCommand) Synopsis() string { return "View or modify client configuration details" } -func (c *ClientConfigCommand) Run(args []string) int { +func (c *NodeConfigCommand) Run(args []string) int { var listServers, updateServers bool - flags := c.Meta.FlagSet("client-servers", FlagSetClient) + flags := c.Meta.FlagSet("node config", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.BoolVar(&listServers, "servers", false, "") flags.BoolVar(&updateServers, "update-servers", false, "") @@ -111,7 +111,7 @@ func (c *ClientConfigCommand) Run(args []string) int { return 1 } -func (c *ClientConfigCommand) AutocompleteFlags() complete.Flags { +func (c *NodeConfigCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ "-servers": complete.PredictNothing, @@ -119,6 +119,6 @@ func (c *ClientConfigCommand) AutocompleteFlags() complete.Flags { }) } -func (c *ClientConfigCommand) AutocompleteArgs() complete.Predictor { +func (c *NodeConfigCommand) AutocompleteArgs() complete.Predictor { return complete.PredictNothing } diff --git a/command/client_config_test.go b/command/node_config_test.go similarity index 93% rename from command/client_config_test.go rename to command/node_config_test.go index cb9275ca0fb..8ddf3f44f42 100644 --- a/command/client_config_test.go +++ b/command/node_config_test.go @@ -10,7 +10,7 @@ import ( func TestClientConfigCommand_Implements(t *testing.T) { t.Parallel() - var _ cli.Command = &ClientConfigCommand{} + var _ cli.Command = &NodeConfigCommand{} } func TestClientConfigCommand_UpdateServers(t *testing.T) { @@ -21,7 +21,7 @@ func TestClientConfigCommand_UpdateServers(t *testing.T) { defer srv.Shutdown() ui := new(cli.MockUi) - cmd := &ClientConfigCommand{Meta: Meta{Ui: ui}} + cmd := &NodeConfigCommand{Meta: Meta{Ui: ui}} // Fails if trying to update with no servers code := cmd.Run([]string{"-update-servers"}) @@ -49,7 +49,7 @@ func TestClientConfigCommand_UpdateServers(t *testing.T) { func TestClientConfigCommand_Fails(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - cmd := &ClientConfigCommand{Meta: Meta{Ui: ui}} + cmd := &NodeConfigCommand{Meta: Meta{Ui: ui}} // Fails on misuse if code := cmd.Run([]string{"some", "bad", "args"}); code != 1 { diff --git a/command/operator.go b/command/operator.go index db5ed3574a3..850154ba626 100644 --- a/command/operator.go +++ b/command/operator.go @@ -18,7 +18,7 @@ Usage: nomad operator [options] the Raft subsystem. NOTE: Use this command with extreme caution, as improper use could lead to a Nomad outage and even loss of data. - Run nomad operator with no arguments for help on that subcommand. + Please see the individual subcommand help for detailed usage information. ` return strings.TrimSpace(helpText) } diff --git a/command/operator_autopilot.go b/command/operator_autopilot.go index d4c4cdd5b20..49fef0bc483 100644 --- a/command/operator_autopilot.go +++ b/command/operator_autopilot.go @@ -22,8 +22,49 @@ func (c *OperatorAutopilotCommand) Help() string { helpText := ` Usage: nomad operator autopilot [options] - The Autopilot operator command is used to interact with Nomad's Autopilot - subsystem. The command can be used to view or modify the current configuration. -` + This command groups subcommands for interacting with Nomad's Autopilot + subsystem. Autopilot provides automatic, operator-friendly management of Nomad + servers. The command can be used to view or modify the current Autopilot + configuration. + + Get the current Autopilot configuration: + + $ nomad operator autopilot get-config + + Set a new Autopilot configuration, enabling automatic dead server cleanup: + + $ nomad operator autopilot set-config -cleanup-dead-servers=true + + Please see the individual subcommand help for detailed usage information. + ` return strings.TrimSpace(helpText) + /* + helpText := ` + Usage: nomad deployment [options] [args] + + This command groups subcommands for interacting with deployments. Deployments + are used to manage a transistion between two versions of a Nomad job. Users + can inspect an ongoing deployment, promote canary allocations, force fail + deployments, and more. + + Examine a deployments status: + + $ nomad deployment status + + Promote the canaries to allow the remaining allocations to be updated in a + rolling deployment fashion: + + $ nomad deployment promote + + Mark a deployment as failed. This will stop new allocations from being placed + and if the job's upgrade stanza specifies auto_revert, causes the job to + revert back to the last stable version of the job: + + $ nomad deployment fail + + Please see the individual subcommand help for detailed usage information. + ` + + return strings.TrimSpace(helpText) + */ } diff --git a/command/keygen.go b/command/operator_keygen.go similarity index 70% rename from command/keygen.go rename to command/operator_keygen.go index 64a47e6bb70..621e915d87e 100644 --- a/command/keygen.go +++ b/command/operator_keygen.go @@ -7,19 +7,19 @@ import ( "strings" ) -// KeygenCommand is a Command implementation that generates an encryption +// OperatorKeygenCommand is a Command implementation that generates an encryption // key for use in `nomad agent`. -type KeygenCommand struct { +type OperatorKeygenCommand struct { Meta } -func (c *KeygenCommand) Synopsis() string { +func (c *OperatorKeygenCommand) Synopsis() string { return "Generates a new encryption key" } -func (c *KeygenCommand) Help() string { +func (c *OperatorKeygenCommand) Help() string { helpText := ` -Usage: nomad keygen +Usage: nomad operator keygen Generates a new encryption key that can be used to configure the agent to encrypt traffic. The output of this command is already @@ -28,7 +28,7 @@ Usage: nomad keygen return strings.TrimSpace(helpText) } -func (c *KeygenCommand) Run(_ []string) int { +func (c *OperatorKeygenCommand) Run(_ []string) int { key := make([]byte, 16) n, err := rand.Reader.Read(key) if err != nil { diff --git a/command/keygen_test.go b/command/operator_keygen_test.go similarity index 89% rename from command/keygen_test.go rename to command/operator_keygen_test.go index a9b3dec6d10..aef6156924f 100644 --- a/command/keygen_test.go +++ b/command/operator_keygen_test.go @@ -10,7 +10,7 @@ import ( func TestKeygenCommand(t *testing.T) { t.Parallel() ui := new(cli.MockUi) - c := &KeygenCommand{Meta: Meta{Ui: ui}} + c := &OperatorKeygenCommand{Meta: Meta{Ui: ui}} code := c.Run(nil) if code != 0 { t.Fatalf("bad: %d", code) diff --git a/command/keyring.go b/command/operator_keyring.go similarity index 87% rename from command/keyring.go rename to command/operator_keyring.go index 6e4ee28fce5..a7428587045 100644 --- a/command/keyring.go +++ b/command/operator_keyring.go @@ -9,15 +9,15 @@ import ( "github.com/posener/complete" ) -// KeyringCommand is a Command implementation that handles querying, installing, +// OperatorKeyringCommand is a Command implementation that handles querying, installing, // and removing gossip encryption keys from a keyring. -type KeyringCommand struct { +type OperatorKeyringCommand struct { Meta } -func (c *KeyringCommand) Help() string { +func (c *OperatorKeyringCommand) Help() string { helpText := ` -Usage: nomad keyring [options] +Usage: nomad operator keyring [options] Manages encryption keys used for gossip messages between Nomad servers. Gossip encryption is optional. When enabled, this command may be used to examine @@ -50,11 +50,11 @@ Keyring Options: return strings.TrimSpace(helpText) } -func (c *KeyringCommand) Synopsis() string { +func (c *OperatorKeyringCommand) Synopsis() string { return "Manages gossip layer encryption keys" } -func (c *KeyringCommand) AutocompleteFlags() complete.Flags { +func (c *OperatorKeyringCommand) AutocompleteFlags() complete.Flags { return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), complete.Flags{ "-install": complete.PredictAnything, @@ -63,15 +63,15 @@ func (c *KeyringCommand) AutocompleteFlags() complete.Flags { "-use": complete.PredictAnything, }) } -func (c *KeyringCommand) AutocompleteArgs() complete.Predictor { +func (c *OperatorKeyringCommand) AutocompleteArgs() complete.Predictor { return complete.PredictNothing } -func (c *KeyringCommand) Run(args []string) int { +func (c *OperatorKeyringCommand) Run(args []string) int { var installKey, useKey, removeKey string var listKeys bool - flags := c.Meta.FlagSet("keys", FlagSetClient) + flags := c.Meta.FlagSet("operator-keyring", FlagSetClient) flags.Usage = func() { c.Ui.Output(c.Help()) } flags.StringVar(&installKey, "install", "", "install key") @@ -158,7 +158,7 @@ func (c *KeyringCommand) Run(args []string) int { return 0 } -func (c *KeyringCommand) handleKeyResponse(resp *api.KeyringResponse) { +func (c *OperatorKeyringCommand) handleKeyResponse(resp *api.KeyringResponse) { out := make([]string, len(resp.Keys)+1) out[0] = "Key" i := 1 diff --git a/command/operator_raft.go b/command/operator_raft.go index 16d89e77f61..5d6df4eade8 100644 --- a/command/operator_raft.go +++ b/command/operator_raft.go @@ -14,9 +14,19 @@ func (c *OperatorRaftCommand) Help() string { helpText := ` Usage: nomad operator raft [options] - The Raft operator command is used to interact with Nomad's Raft subsystem. The - command can be used to verify Raft peers or in rare cases to recover quorum by - removing invalid peers. + This command groups subcommands for interacting with Nomad's Raft subsystem. + The command can be used to verify Raft peers or in rare cases to recover + quorum by removing invalid peers. + + List Raft peers: + + $ nomad operator raft list-peers + + Remove a Raft peer: + + $ nomad operator raft remove-peer -peer-address "IP:Port" + + Please see the individual subcommand help for detailed usage information. ` return strings.TrimSpace(helpText) } diff --git a/command/quota.go b/command/quota.go index 46959d5a43b..62d3570818e 100644 --- a/command/quota.go +++ b/command/quota.go @@ -1,6 +1,8 @@ package command import ( + "strings" + "github.com/hashicorp/nomad/api/contexts" "github.com/mitchellh/cli" "github.com/posener/complete" @@ -11,7 +13,31 @@ type QuotaCommand struct { } func (f *QuotaCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad quota [options] [args] + + This command groups subcommands for interacting with resource quotas. Resource + quotas allow operators to restrict the aggregate resource usage of namespaces. + Users can inspect existing quota specifications, create new quotas, delete and + list existing quotas, and more. For a full guide on resource quotas see: + https://www.nomadproject.io/guides/quotas.html + + Examine a quota's status: + + $ nomad quota status + + List existing quotas: + + $ nomad quota list + + Create a new quota specification: + + $ nomad quota apply + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) } func (f *QuotaCommand) Synopsis() string { diff --git a/command/sentinel.go b/command/sentinel.go index fe8ffba6006..4e30f98bfad 100644 --- a/command/sentinel.go +++ b/command/sentinel.go @@ -1,13 +1,44 @@ package command -import "github.com/mitchellh/cli" +import ( + "strings" + + "github.com/mitchellh/cli" +) type SentinelCommand struct { Meta } func (f *SentinelCommand) Help() string { - return "This command is accessed by using one of the subcommands below." + helpText := ` +Usage: nomad sentinel [options] [args] + + This command groups subcommands for interacting with Sentinel policies. + Sentinel policies allow operators to express fine-grained policies as code and + have their policies automatically enforced. This allows operators to define a + "sandbox" and restrict actions to only those compliant with policy. The + Sentinel integration builds on the ACL System. Users can read existing + Sentinel policies, create new policies, delete and list existing policies, and + more. For a full guide on Sentinel policies see: + https://www.nomadproject.io/guides/sentinel-policy.html + + Read an existing policy: + + $ nomad sentinel read + + List existing policies: + + $ nomad sentinel list + + Create a new Sentinel policy: + + $ nomad sentinel apply + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) } func (f *SentinelCommand) Synopsis() string { diff --git a/command/server.go b/command/server.go new file mode 100644 index 00000000000..f675869cbf0 --- /dev/null +++ b/command/server.go @@ -0,0 +1,44 @@ +package command + +import ( + "strings" + + "github.com/mitchellh/cli" +) + +type ServerCommand struct { + Meta +} + +func (f *ServerCommand) Help() string { + helpText := ` +Usage: nomad server [options] [args] + + This command groups subcommands for interacting with Nomad servers. Users can + list Servers, join a server to the cluster, and force leave a server. + + List Nomad servers: + + $ nomad server members + + Join a new server to another: + + $ nomad server join "IP:Port" + + Force a server to leave: + + $ nomad server force-leave + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) +} + +func (f *ServerCommand) Synopsis() string { + return "Interact with servers" +} + +func (f *ServerCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/server_force_leave.go b/command/server_force_leave.go index 666be7060da..dde9e949bf3 100644 --- a/command/server_force_leave.go +++ b/command/server_force_leave.go @@ -11,7 +11,7 @@ type ServerForceLeaveCommand struct { func (c *ServerForceLeaveCommand) Help() string { helpText := ` -Usage: nomad server-force-leave [options] +Usage: nomad server force-leave [options] Forces an server to enter the "left" state. This can be used to eject nodes which have failed and will not rejoin the cluster. diff --git a/command/server_join.go b/command/server_join.go index 9b9bacc5364..86208eaa5c0 100644 --- a/command/server_join.go +++ b/command/server_join.go @@ -11,7 +11,7 @@ type ServerJoinCommand struct { func (c *ServerJoinCommand) Help() string { helpText := ` -Usage: nomad server-join [options] [...] +Usage: nomad server join [options] [...] Joins the local server to one or more Nomad servers. Joining is only required for server nodes, and only needs to succeed diff --git a/command/server_members.go b/command/server_members.go index 55a31d268e4..61e97173c5f 100644 --- a/command/server_members.go +++ b/command/server_members.go @@ -17,7 +17,7 @@ type ServerMembersCommand struct { func (c *ServerMembersCommand) Help() string { helpText := ` -Usage: nomad server-members [options] +Usage: nomad server members [options] Display a list of the known servers and their status. Only Nomad servers are able to service this command. diff --git a/commands.go b/commands.go deleted file mode 100644 index 0b3a422f034..00000000000 --- a/commands.go +++ /dev/null @@ -1,453 +0,0 @@ -package main - -import ( - "os" - - "github.com/hashicorp/nomad/command" - "github.com/hashicorp/nomad/command/agent" - "github.com/hashicorp/nomad/version" - "github.com/mitchellh/cli" -) - -// Commands returns the mapping of CLI commands for Nomad. The meta -// parameter lets you set meta options for all commands. -func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { - if metaPtr == nil { - metaPtr = new(command.Meta) - } - - meta := *metaPtr - if meta.Ui == nil { - meta.Ui = &cli.BasicUi{ - Reader: os.Stdin, - Writer: os.Stdout, - ErrorWriter: os.Stderr, - } - } - - return map[string]cli.CommandFactory{ - "acl": func() (cli.Command, error) { - return &command.ACLCommand{ - Meta: meta, - }, nil - }, - "acl bootstrap": func() (cli.Command, error) { - return &command.ACLBootstrapCommand{ - Meta: meta, - }, nil - }, - "acl policy": func() (cli.Command, error) { - return &command.ACLPolicyCommand{ - Meta: meta, - }, nil - }, - "acl policy apply": func() (cli.Command, error) { - return &command.ACLPolicyApplyCommand{ - Meta: meta, - }, nil - }, - "acl policy delete": func() (cli.Command, error) { - return &command.ACLPolicyDeleteCommand{ - Meta: meta, - }, nil - }, - "acl policy info": func() (cli.Command, error) { - return &command.ACLPolicyInfoCommand{ - Meta: meta, - }, nil - }, - "acl policy list": func() (cli.Command, error) { - return &command.ACLPolicyListCommand{ - Meta: meta, - }, nil - }, - "acl token": func() (cli.Command, error) { - return &command.ACLTokenCommand{ - Meta: meta, - }, nil - }, - "acl token create": func() (cli.Command, error) { - return &command.ACLTokenCreateCommand{ - Meta: meta, - }, nil - }, - "acl token update": func() (cli.Command, error) { - return &command.ACLTokenUpdateCommand{ - Meta: meta, - }, nil - }, - "acl token delete": func() (cli.Command, error) { - return &command.ACLTokenDeleteCommand{ - Meta: meta, - }, nil - }, - "acl token info": func() (cli.Command, error) { - return &command.ACLTokenInfoCommand{ - Meta: meta, - }, nil - }, - "acl token self": func() (cli.Command, error) { - return &command.ACLTokenSelfCommand{ - Meta: meta, - }, nil - }, - "alloc-status": func() (cli.Command, error) { - return &command.AllocStatusCommand{ - Meta: meta, - }, nil - }, - "agent": func() (cli.Command, error) { - return &agent.Command{ - Version: version.GetVersion(), - Ui: meta.Ui, - ShutdownCh: make(chan struct{}), - }, nil - }, - "agent-info": func() (cli.Command, error) { - return &command.AgentInfoCommand{ - Meta: meta, - }, nil - }, - "check": func() (cli.Command, error) { - return &command.AgentCheckCommand{ - Meta: meta, - }, nil - }, - "client-config": func() (cli.Command, error) { - return &command.ClientConfigCommand{ - Meta: meta, - }, nil - }, - "deployment": func() (cli.Command, error) { - return &command.DeploymentCommand{ - Meta: meta, - }, nil - }, - "deployment fail": func() (cli.Command, error) { - return &command.DeploymentFailCommand{ - Meta: meta, - }, nil - }, - "deployment list": func() (cli.Command, error) { - return &command.DeploymentListCommand{ - Meta: meta, - }, nil - }, - "deployment pause": func() (cli.Command, error) { - return &command.DeploymentPauseCommand{ - Meta: meta, - }, nil - }, - "deployment promote": func() (cli.Command, error) { - return &command.DeploymentPromoteCommand{ - Meta: meta, - }, nil - }, - "deployment resume": func() (cli.Command, error) { - return &command.DeploymentResumeCommand{ - Meta: meta, - }, nil - }, - "deployment status": func() (cli.Command, error) { - return &command.DeploymentStatusCommand{ - Meta: meta, - }, nil - }, - "eval-status": func() (cli.Command, error) { - return &command.EvalStatusCommand{ - Meta: meta, - }, nil - }, - "executor": func() (cli.Command, error) { - return &command.ExecutorPluginCommand{ - Meta: meta, - }, nil - }, - "fs": func() (cli.Command, error) { - return &command.FSCommand{ - Meta: meta, - }, nil - }, - "init": func() (cli.Command, error) { - return &command.InitCommand{ - Meta: meta, - }, nil - }, - "inspect": func() (cli.Command, error) { - return &command.InspectCommand{ - Meta: meta, - }, nil - }, - "keygen": func() (cli.Command, error) { - return &command.KeygenCommand{ - Meta: meta, - }, nil - }, - "keyring": func() (cli.Command, error) { - return &command.KeyringCommand{ - Meta: meta, - }, nil - }, - "job": func() (cli.Command, error) { - return &command.JobCommand{ - Meta: meta, - }, nil - }, - "job deployments": func() (cli.Command, error) { - return &command.JobDeploymentsCommand{ - Meta: meta, - }, nil - }, - "job dispatch": func() (cli.Command, error) { - return &command.JobDispatchCommand{ - Meta: meta, - }, nil - }, - "job history": func() (cli.Command, error) { - return &command.JobHistoryCommand{ - Meta: meta, - }, nil - }, - "job promote": func() (cli.Command, error) { - return &command.JobPromoteCommand{ - Meta: meta, - }, nil - }, - "job revert": func() (cli.Command, error) { - return &command.JobRevertCommand{ - Meta: meta, - }, nil - }, - "job status": func() (cli.Command, error) { - return &command.JobStatusCommand{ - Meta: meta, - }, nil - }, - "logs": func() (cli.Command, error) { - return &command.LogsCommand{ - Meta: meta, - }, nil - }, - "namespace": func() (cli.Command, error) { - return &command.NamespaceCommand{ - Meta: meta, - }, nil - }, - "namespace apply": func() (cli.Command, error) { - return &command.NamespaceApplyCommand{ - Meta: meta, - }, nil - }, - "namespace delete": func() (cli.Command, error) { - return &command.NamespaceDeleteCommand{ - Meta: meta, - }, nil - }, - "namespace inspect": func() (cli.Command, error) { - return &command.NamespaceInspectCommand{ - Meta: meta, - }, nil - }, - "namespace list": func() (cli.Command, error) { - return &command.NamespaceListCommand{ - Meta: meta, - }, nil - }, - "namespace status": func() (cli.Command, error) { - return &command.NamespaceStatusCommand{ - Meta: meta, - }, nil - }, - "node": func() (cli.Command, error) { - return &command.NodeCommand{ - Meta: meta, - }, nil - }, - "node-drain": func() (cli.Command, error) { - return &command.NodeDrainCommand{ - Meta: meta, - }, nil - }, - "node drain": func() (cli.Command, error) { - return &command.NodeDrainCommand{ - Meta: meta, - }, nil - }, - "node eligibility": func() (cli.Command, error) { - return &command.NodeEligibilityCommand{ - Meta: meta, - }, nil - }, - "node-status": func() (cli.Command, error) { - return &command.NodeStatusCommand{ - Meta: meta, - }, nil - }, - "node status": func() (cli.Command, error) { - return &command.NodeStatusCommand{ - Meta: meta, - }, nil - }, - "operator": func() (cli.Command, error) { - return &command.OperatorCommand{ - Meta: meta, - }, nil - }, - - "operator autopilot": func() (cli.Command, error) { - return &command.OperatorAutopilotCommand{ - Meta: meta, - }, nil - }, - - "operator autopilot get-config": func() (cli.Command, error) { - return &command.OperatorAutopilotGetCommand{ - Meta: meta, - }, nil - }, - - "operator autopilot set-config": func() (cli.Command, error) { - return &command.OperatorAutopilotSetCommand{ - Meta: meta, - }, nil - }, - - "operator raft": func() (cli.Command, error) { - return &command.OperatorRaftCommand{ - Meta: meta, - }, nil - }, - - "operator raft list-peers": func() (cli.Command, error) { - return &command.OperatorRaftListCommand{ - Meta: meta, - }, nil - }, - - "operator raft remove-peer": func() (cli.Command, error) { - return &command.OperatorRaftRemoveCommand{ - Meta: meta, - }, nil - }, - - "plan": func() (cli.Command, error) { - return &command.PlanCommand{ - Meta: meta, - }, nil - }, - - "quota": func() (cli.Command, error) { - return &command.QuotaCommand{ - Meta: meta, - }, nil - }, - - "quota apply": func() (cli.Command, error) { - return &command.QuotaApplyCommand{ - Meta: meta, - }, nil - }, - - "quota delete": func() (cli.Command, error) { - return &command.QuotaDeleteCommand{ - Meta: meta, - }, nil - }, - - "quota init": func() (cli.Command, error) { - return &command.QuotaInitCommand{ - Meta: meta, - }, nil - }, - - "quota inspect": func() (cli.Command, error) { - return &command.QuotaInspectCommand{ - Meta: meta, - }, nil - }, - - "quota list": func() (cli.Command, error) { - return &command.QuotaListCommand{ - Meta: meta, - }, nil - }, - - "quota status": func() (cli.Command, error) { - return &command.QuotaStatusCommand{ - Meta: meta, - }, nil - }, - - "run": func() (cli.Command, error) { - return &command.RunCommand{ - Meta: meta, - }, nil - }, - "sentinel": func() (cli.Command, error) { - return &command.SentinelCommand{ - Meta: meta, - }, nil - }, - "sentinel list": func() (cli.Command, error) { - return &command.SentinelListCommand{ - Meta: meta, - }, nil - }, - "sentinel apply": func() (cli.Command, error) { - return &command.SentinelApplyCommand{ - Meta: meta, - }, nil - }, - "sentinel delete": func() (cli.Command, error) { - return &command.SentinelDeleteCommand{ - Meta: meta, - }, nil - }, - "sentinel read": func() (cli.Command, error) { - return &command.SentinelReadCommand{ - Meta: meta, - }, nil - }, - "server-force-leave": func() (cli.Command, error) { - return &command.ServerForceLeaveCommand{ - Meta: meta, - }, nil - }, - "server-join": func() (cli.Command, error) { - return &command.ServerJoinCommand{ - Meta: meta, - }, nil - }, - "server-members": func() (cli.Command, error) { - return &command.ServerMembersCommand{ - Meta: meta, - }, nil - }, - "status": func() (cli.Command, error) { - return &command.StatusCommand{ - Meta: meta, - }, nil - }, - "stop": func() (cli.Command, error) { - return &command.StopCommand{ - Meta: meta, - }, nil - }, - "ui": func() (cli.Command, error) { - return &command.UiCommand{ - Meta: meta, - }, nil - }, - "validate": func() (cli.Command, error) { - return &command.ValidateCommand{ - Meta: meta, - }, nil - }, - "version": func() (cli.Command, error) { - return &command.VersionCommand{ - Version: version.GetVersion(), - Ui: meta.Ui, - }, nil - }, - } -} diff --git a/main.go b/main.go index f482ca2838b..ff8216f6789 100644 --- a/main.go +++ b/main.go @@ -3,13 +3,56 @@ package main import ( "bytes" "fmt" + "io" "os" "sort" "strings" + "text/tabwriter" + "github.com/hashicorp/nomad/command" "github.com/hashicorp/nomad/version" "github.com/mitchellh/cli" "github.com/sean-/seed" + "golang.org/x/crypto/ssh/terminal" +) + +var ( + // Hidden hides the commands from both help and autocomplete. Commands that + // users should not be running should be placed here, versus hiding + // subcommands from the main help, which should be filtered out of the + // commands above. + hidden = []string{ + "alloc-status", + "check", + "client-config", + "eval-status", + "executor", + "fs", + "init", + "inspect", + "keygen", + "keyring", + "logs", + "node-drain", + "node-status", + "plan", + "server-force-leave", + "server-join", + "server-members", + "syslog", + "validate", + } + + // Common commands are grouped separately to call them out to operators. + commonCommands = []string{ + "run", + "stop", + "status", + "alloc", + "job", + "node", + "agent", + } ) func init() { @@ -21,42 +64,51 @@ func main() { } func Run(args []string) int { - return RunCustom(args, Commands(nil)) + return RunCustom(args) } -func RunCustom(args []string, commands map[string]cli.CommandFactory) int { - // Build the commands to include in the help now. - commandsInclude := make([]string, 0, len(commands)) - for k := range commands { - switch k { - case "deployment list", "deployment status", "deployment pause", - "deployment resume", "deployment fail", "deployment promote": - case "fs ls", "fs cat", "fs stat": - case "job deployments", "job dispatch", "job history", "job promote", "job revert": - case "namespace list", "namespace delete", "namespace apply", "namespace inspect", "namespace status": - case "quota list", "quota delete", "quota apply", "quota status", "quota inspect", "quota init": - case "operator raft", "operator raft list-peers", "operator raft remove-peer": - case "acl policy", "acl policy apply", "acl token", "acl token create": - case "node-drain", "node-status": - default: - commandsInclude = append(commandsInclude, k) - } +func RunCustom(args []string) int { + // Parse flags into env vars for global use + args = setupEnv(args) + + // Create the meta object + metaPtr := new(command.Meta) + + // Don't use color if disabled + color := true + if os.Getenv(command.EnvNomadCLINoColor) != "" { + color = false } - // Hidden hides the commands from both help and autocomplete. Commands that - // users should not be running should be placed here, versus hiding - // subcommands from the main help, which should be filtered out of the - // commands above. - hidden := []string{"check", "executor", "syslog", "node-drain", "node-status"} + isTerminal := terminal.IsTerminal(int(os.Stdout.Fd())) + metaPtr.Ui = &cli.BasicUi{ + Reader: os.Stdin, + Writer: os.Stdout, + ErrorWriter: os.Stderr, + } + // Only use colored UI if stdout is a tty, and not disabled + if isTerminal && color { + metaPtr.Ui = &cli.ColoredUi{ + ErrorColor: cli.UiColorRed, + WarnColor: cli.UiColorYellow, + Ui: metaPtr.Ui, + } + } + + commands := command.Commands(metaPtr) cli := &cli.CLI{ - Name: "nomad", - Version: version.GetVersion().FullVersionNumber(true), - Args: args, - Commands: commands, - Autocomplete: true, - HiddenCommands: hidden, - HelpFunc: cli.FilteredHelpFunc(commandsInclude, helpFunc), + Name: "nomad", + Version: version.GetVersion().FullVersionNumber(true), + Args: args, + Commands: commands, + HiddenCommands: hidden, + Autocomplete: true, + AutocompleteNoDefaultFlags: true, + HelpFunc: groupedHelpFunc( + cli.BasicHelpFunc("nomad"), + ), + HelpWriter: os.Stdout, } exitCode, err := cli.Run() @@ -109,3 +161,69 @@ func helpFunc(commands map[string]cli.CommandFactory) string { return buf.String() } + +func groupedHelpFunc(f cli.HelpFunc) cli.HelpFunc { + return func(commands map[string]cli.CommandFactory) string { + var b bytes.Buffer + tw := tabwriter.NewWriter(&b, 0, 2, 6, ' ', 0) + + fmt.Fprintf(tw, "Usage: nomad [-version] [-help] [-autocomplete-(un)install] [args]\n\n") + fmt.Fprintf(tw, "Common commands:\n") + for _, v := range commonCommands { + printCommand(tw, v, commands[v]) + } + + otherCommands := make([]string, 0, len(commands)) + for k := range commands { + found := false + for _, v := range commonCommands { + if k == v { + found = true + break + } + } + + if !found { + otherCommands = append(otherCommands, k) + } + } + sort.Strings(otherCommands) + + fmt.Fprintf(tw, "\n") + fmt.Fprintf(tw, "Other commands:\n") + for _, v := range otherCommands { + printCommand(tw, v, commands[v]) + } + + tw.Flush() + + return strings.TrimSpace(b.String()) + } +} + +func printCommand(w io.Writer, name string, cmdFn cli.CommandFactory) { + cmd, err := cmdFn() + if err != nil { + panic(fmt.Sprintf("failed to load %q command: %s", name, err)) + } + fmt.Fprintf(w, " %s\t%s\n", name, cmd.Synopsis()) +} + +// setupEnv parses args and may replace them and sets some env vars to known +// values based on format options +func setupEnv(args []string) []string { + noColor := false + for _, arg := range args { + // Check if color is set + if arg == "-no-color" || arg == "--no-color" { + noColor = true + } + } + + // Put back into the env for later + if noColor { + os.Setenv(command.EnvNomadCLINoColor, "true") + } + + return args +} diff --git a/website/redirects.txt b/website/redirects.txt index c1a799093e7..4924a1881d6 100644 --- a/website/redirects.txt +++ b/website/redirects.txt @@ -67,6 +67,24 @@ /docs/commands/operator-raft-list-peers.html /docs/commands/operator/raft-list-peers.html /docs/commands/operator-raft-remove-peer.html /docs/commands/operator/raft-remove-peer.html /docs/commands/job-dispatch.html /docs/commands/job/dispatch.html +/docs/commands/alloc-status.html /docs/commands/alloc/status.html +/docs/commands/fs.html /docs/commands/alloc/fs.html +/docs/commands/logs.html /docs/commands/alloc/logs.html +/docs/commands/init.html /docs/commands/job/init.html +/docs/commands/inspect.html /docs/commands/job/inspect.html +/docs/commands/run.html /docs/commands/job/run.html +/docs/commands/stop.html /docs/commands/job/stop.html +/docs/commands/plan.html /docs/commands/job/plan.html +/docs/commands/validate.html /docs/commands/job/validate.html +/docs/commands/client-config.html /docs/commands/node/config.html +/docs/commands/node-drain.html /docs/commands/node/drain.html +/docs/commands/node-status.html /docs/commands/node/status.html +/docs/commands/keygen.html /docs/commands/operator/keygen.html +/docs/commands/keyring.html /docs/commands/operator/keyring.html +/docs/commands/server-force-leave.html /docs/commands/server/force-leave.html +/docs/commands/server-join.html /docs/commands/server/join.html +/docs/commands/server-members.html /docs/commands/server/members.html + # API /docs/http/index.html /api/index.html diff --git a/website/source/api/json-jobs.html.md b/website/source/api/json-jobs.html.md index b8826d21ea5..332f6c1a805 100644 --- a/website/source/api/json-jobs.html.md +++ b/website/source/api/json-jobs.html.md @@ -13,7 +13,7 @@ This guide covers the JSON syntax for submitting jobs to Nomad. A useful command for generating valid JSON versions of HCL jobs is: ```shell -$ nomad run -output my-job.nomad +$ nomad job run -output my-job.nomad ``` ## Syntax diff --git a/website/source/docs/agent/encryption.html.md b/website/source/docs/agent/encryption.html.md index 06c75009caf..2ddeb97a75e 100644 --- a/website/source/docs/agent/encryption.html.md +++ b/website/source/docs/agent/encryption.html.md @@ -20,10 +20,11 @@ starting the Nomad server. The key can be set via the of this setting is a server configuration file containing the encryption key. The key must be 16 bytes, base64 encoded. As a convenience, Nomad provides the -[`nomad keygen`](/docs/commands/keygen.html) command to generate a cryptographically suitable key: +[`nomad operator keygen`](/docs/commands/operator/keygen.html) command to +generate a cryptographically suitable key: ```sh -$ nomad keygen +$ nomad operator keygen cg8StVXbQJ0gPvMd9o7yrg== ``` diff --git a/website/source/docs/agent/index.html.md b/website/source/docs/agent/index.html.md index dad7f9c67bc..d98bcbd43ad 100644 --- a/website/source/docs/agent/index.html.md +++ b/website/source/docs/agent/index.html.md @@ -93,7 +93,7 @@ leave the [consensus](/docs/internals/consensus.html) peer set. It is especially important that a server node be allowed to leave gracefully so that there will be a minimal impact on availability as the server leaves the consensus peer set. If a server does not gracefully leave, and will not -return into service, the [`server-force-leave` command](/docs/commands/server-force-leave.html) +return into service, the [`server force-leave` command](/docs/commands/server/force-leave.html) should be used to eject it from the consensus peer set. ## Lifecycle @@ -125,7 +125,7 @@ participate in a [gossip protocol](/docs/internals/gossip.html) both to cluster within a region and to support multi-region configurations. When a server is first started, it does not know the address of other servers in the cluster. To discover its peers, it must _join_ the cluster. This is done with the -[`server-join` command](/docs/commands/server-join.html) or by providing the +[`server join` command](/docs/commands/server/join.html) or by providing the proper configuration on start. Once a node joins, this information is gossiped to the entire cluster, meaning all nodes will eventually be aware of each other. diff --git a/website/source/docs/commands/_general_options.html.md b/website/source/docs/commands/_general_options.html.md index 5a1811f9bd0..86cba60fa8f 100644 --- a/website/source/docs/commands/_general_options.html.md +++ b/website/source/docs/commands/_general_options.html.md @@ -5,7 +5,8 @@ Overrides the `NOMAD_REGION` environment variable if set. Defaults to the Agent's local region. -- `-no-color`: Disables colored command output. +- `-no-color`: Disables colored command output. Alternatively, + `NOMAD_CLI_NO_COLOR` may be set. - `-ca-cert=`: Path to a PEM encoded CA cert file to use to verify the Nomad server SSL certificate. Overrides the `NOMAD_CACERT` environment diff --git a/website/source/docs/commands/acl.html.md.erb b/website/source/docs/commands/acl.html.md.erb index dc60e1851ae..05b1c2485df 100644 --- a/website/source/docs/commands/acl.html.md.erb +++ b/website/source/docs/commands/acl.html.md.erb @@ -6,9 +6,7 @@ description: > The acl command is used to interact with ACL policies and tokens. --- -# Nomad ACL - -Command: `nomad acl` +# Command: acl The `acl` command is used to interact with ACL policies and tokens. diff --git a/website/source/docs/commands/alloc.html.md.erb b/website/source/docs/commands/alloc.html.md.erb new file mode 100644 index 00000000000..6b9e453b8bb --- /dev/null +++ b/website/source/docs/commands/alloc.html.md.erb @@ -0,0 +1,26 @@ +--- +layout: "docs" +page_title: "Commands: alloc" +sidebar_current: "docs-commands-alloc" +description: > + The alloc command is used to interact with allocations. +--- + +# Command: alloc + +The `alloc` command is used to interact with allocations. + +## Usage + +Usage: `nomad alloc [options]` + +Run `nomad alloc -h` for help on that subcommand. The following +subcommands are available: + +* [`alloc fs`][fs] - Inspect the contents of an allocation directory +* [`alloc logs`][logs] - Streams the logs of a task +* [`alloc status`][status] - Display allocation status information and metadata + +[fs]: /docs/commands/alloc/fs.html "Inspect the contents of an allocation directory" +[logs]: /docs/commands/alloc/logs.html "Streams the logs of a task" +[status]: /docs/commands/alloc/status.html "Display allocation status information and metadata" diff --git a/website/source/docs/commands/fs.html.md.erb b/website/source/docs/commands/alloc/fs.html.md.erb similarity index 83% rename from website/source/docs/commands/fs.html.md.erb rename to website/source/docs/commands/alloc/fs.html.md.erb index 05a6c89dd38..2cf1844f864 100644 --- a/website/source/docs/commands/fs.html.md.erb +++ b/website/source/docs/commands/alloc/fs.html.md.erb @@ -1,14 +1,15 @@ --- layout: "docs" -page_title: "Commands: fs" -sidebar_current: "docs-commands-fs" +page_title: "Commands: alloc fs" +sidebar_current: "docs-commands-alloc-fs" description: > Introspect an allocation directory on a Nomad client --- -# Command: fs +# Command: alloc fs +**Alias: `nomad fs`** -The `fs` command allows a user to navigate an allocation directory on a Nomad +The `alloc fs` command allows a user to navigate an allocation directory on a Nomad client. The following functionalities are available - `cat`, `tail`, `ls` and `stat`. @@ -23,7 +24,7 @@ client. The following functionalities are available - `cat`, `tail`, `ls` and ## Usage ``` -nomad fs [options] +nomad alloc fs [options] ``` This command accepts a single allocation ID (unless the `-job` flag is specified, @@ -61,29 +62,29 @@ end of the file. ## Examples ``` -$ nomad fs eb17e557 +$ nomad alloc fs eb17e557 Mode Size Modified Time Name drwxrwxr-x 4096 28 Jan 16 05:39 UTC alloc/ drwxrwxr-x 4096 28 Jan 16 05:39 UTC redis/ -rw-rw-r-- 0 28 Jan 16 05:39 UTC redis_exit_status -$ nomad fs eb17e557 redis/local +$ nomad alloc fs eb17e557 redis/local Mode Size Modified Time Name -rw-rw-rw- 0 28 Jan 16 05:39 UTC redis.stderr -rw-rw-rw- 17 28 Jan 16 05:39 UTC redis.stdout -$ nomad fs -stat eb17e557 redis/local/redis.stdout +$ nomad alloc fs -stat eb17e557 redis/local/redis.stdout Mode Size Modified Time Name -rw-rw-rw- 17 28 Jan 16 05:39 UTC redis.stdout -$ nomad fs eb17e557 redis/local/redis.stdout +$ nomad alloc fs eb17e557 redis/local/redis.stdout foobar baz -$ nomad fs -tail -f -n 3 eb17e557 redis/local/redis.stdout +$ nomad alloc fs -tail -f -n 3 eb17e557 redis/local/redis.stdout foobar baz bam @@ -98,7 +99,7 @@ if no running allocations for the job are found, Nomad will use a dead allocation. ``` -nomad fs -job +nomad alloc fs -job ``` diff --git a/website/source/docs/commands/logs.html.md.erb b/website/source/docs/commands/alloc/logs.html.md.erb similarity index 77% rename from website/source/docs/commands/logs.html.md.erb rename to website/source/docs/commands/alloc/logs.html.md.erb index 33d2301a4d2..1da0f96eccf 100644 --- a/website/source/docs/commands/logs.html.md.erb +++ b/website/source/docs/commands/alloc/logs.html.md.erb @@ -1,19 +1,20 @@ --- layout: "docs" -page_title: "Commands: logs" -sidebar_current: "docs-commands-logs" +page_title: "Commands: alloc logs" +sidebar_current: "docs-commands-alloc-logs" description: > Stream the logs of a task. --- -# Command: logs +# Command: alloc logs +**Alias: `nomad logs`** -The `logs` command displays the log of a given task. +The `alloc logs` command displays the log of a given task. ## Usage ``` -nomad logs [options] +nomad alloc logs [options] ``` This command streams the logs of the given task in the allocation. If the @@ -48,24 +49,24 @@ end of the logs. ## Examples ``` -$ nomad logs eb17e557 redis +$ nomad alloc logs eb17e557 redis foobar baz bam -$ nomad logs -stderr eb17e557 redis +$ nomad alloc logs -stderr eb17e557 redis [ERR]: foo [ERR]: bar -$ nomad logs -job example +$ nomad alloc logs -job example [ERR]: foo [ERR]: bar -$ nomad logs -tail -n 2 eb17e557 redis +$ nomad alloc logs -tail -n 2 eb17e557 redis foobar baz -$ nomad logs -tail -f -n 3 eb17e557 redis +$ nomad alloc logs -tail -f -n 3 eb17e557 redis foobar baz bam @@ -80,7 +81,7 @@ if no running allocations for the job are found, Nomad will use a dead allocation. ``` -nomad logs -job +nomad alloc logs -job ``` diff --git a/website/source/docs/commands/alloc-status.html.md.erb b/website/source/docs/commands/alloc/status.html.md.erb similarity index 94% rename from website/source/docs/commands/alloc-status.html.md.erb rename to website/source/docs/commands/alloc/status.html.md.erb index d0195d46fd8..a4e789ed52a 100644 --- a/website/source/docs/commands/alloc-status.html.md.erb +++ b/website/source/docs/commands/alloc/status.html.md.erb @@ -1,14 +1,14 @@ --- layout: "docs" -page_title: "Commands: alloc-status" +page_title: "Commands: alloc status" sidebar_current: "docs-commands-alloc-status" description: > Display status and metadata about existing allocations and their tasks. --- -# Command: alloc-status +# Command: alloc status -The `alloc-status` command displays status information and metadata about an +The `alloc status` command displays status information and metadata about an existing allocation and its tasks. It can be useful while debugging to reveal the underlying reasons for scheduling decisions or failures, as well as the current state of its tasks. As of Nomad 0.7.1, alloc status also shows allocation @@ -18,7 +18,7 @@ information about reschedule attempts. ## Usage ``` -nomad alloc-status [options] +nomad alloc status [options] ``` An allocation ID or prefix must be provided. If there is an exact match, the @@ -41,7 +41,7 @@ allocations and information will be displayed. Short status of an alloc: ``` -$ nomad alloc-status --short 0af996ed +$ nomad alloc status --short 0af996ed ID = 0af996ed Eval ID = be9bde98 Name = example.cache[0] @@ -65,7 +65,7 @@ web running Started 07/25/17 16:12:49 UTC Full status of an alloc, which shows one of the tasks dying and then being restarted: ``` -$ nomad alloc-status 0af996ed +$ nomad alloc status 0af996ed ID = 0af996ed Eval ID = be9bde98 Name = example.cache[0] @@ -107,7 +107,6 @@ CPU Memory Disk IOPS Addresses Task Events: Started At = 07/25/17 16:12:49 UTC ->>>>>>> alloc-status Finished At = N/A Total Restarts = 0 Last Restart = N/A @@ -121,7 +120,7 @@ Recent Events: Verbose status can also be accessed: ``` -$ nomad alloc-status -verbose 0af996ed +$ nomad alloc status -verbose 0af996ed ID = 0af996ed-aff4-8ddb-a566-e55ebf8969c9 Eval ID = be9bde98-0490-1beb-ced0-012d10ddf22e Name = example.cache[0] diff --git a/website/source/docs/commands/deployment.html.md.erb b/website/source/docs/commands/deployment.html.md.erb index 39ba2a94fea..dd0abb50216 100644 --- a/website/source/docs/commands/deployment.html.md.erb +++ b/website/source/docs/commands/deployment.html.md.erb @@ -6,10 +6,8 @@ description: > The deployment command is used to interact with deployments. --- -# Nomad Deployment +# Command: deployment -Command: `nomad deployment` - The `deployment` command is used to interact with deployments. ## Usage diff --git a/website/source/docs/commands/deployment/fail.html.md.erb b/website/source/docs/commands/deployment/fail.html.md.erb index 774f75b0a6c..7b447f9f527 100644 --- a/website/source/docs/commands/deployment/fail.html.md.erb +++ b/website/source/docs/commands/deployment/fail.html.md.erb @@ -30,7 +30,7 @@ prefix. * `-detach`: Return immediately instead of monitoring. A new evaluation ID will be output, which can be used to examine the evaluation using the - [eval-status](/docs/commands/eval-status.html) command. + [eval status](/docs/commands/eval-status.html) command. * `-verbose`: Show full information. diff --git a/website/source/docs/commands/deployment/promote.html.md.erb b/website/source/docs/commands/deployment/promote.html.md.erb index 4f55fcd67d4..aafd1ea5dc1 100644 --- a/website/source/docs/commands/deployment/promote.html.md.erb +++ b/website/source/docs/commands/deployment/promote.html.md.erb @@ -40,7 +40,7 @@ select particular groups to promote. * `-detach`: Return immediately instead of monitoring. A new evaluation ID will be output, which can be used to examine the evaluation using the - [eval-status](/docs/commands/eval-status.html) command + [eval status](/docs/commands/eval-status.html) command * `-verbose`: Show full information. diff --git a/website/source/docs/commands/deployment/resume.html.md.erb b/website/source/docs/commands/deployment/resume.html.md.erb index c548dcde2e3..db59c4f5a0e 100644 --- a/website/source/docs/commands/deployment/resume.html.md.erb +++ b/website/source/docs/commands/deployment/resume.html.md.erb @@ -29,7 +29,7 @@ prefix. * `-detach`: Return immediately instead of monitoring. A new evaluation ID will be output, which can be used to examine the evaluation using the - [eval-status](/docs/commands/eval-status.html) command + [eval status](/docs/commands/eval-status.html) command * `-verbose`: Show full information. diff --git a/website/source/docs/commands/eval-status.html.md.erb b/website/source/docs/commands/eval-status.html.md.erb index 13d9e4822bd..b28ee5ab319 100644 --- a/website/source/docs/commands/eval-status.html.md.erb +++ b/website/source/docs/commands/eval-status.html.md.erb @@ -1,15 +1,15 @@ --- layout: "docs" -page_title: "Commands: eval-status" +page_title: "Commands: eval status" sidebar_current: "docs-commands-eval-status" description: > - The eval-status command is used to see the status and potential failed + The eval status command is used to see the status and potential failed allocations of an evaluation. --- -# Command: eval-status +# Command: eval status -The `eval-status` command is used to display information about an existing +The `eval status` command is used to display information about an existing evaluation. In the case an evaluation could not place all the requested allocations, this command can be used to determine the failure reasons. @@ -21,7 +21,7 @@ evaluation reaches a terminal state. ## Usage ``` -nomad eval-status [options] +nomad eval status [options] ``` An evaluation ID or prefix must be provided. If there is an exact match, the @@ -57,7 +57,7 @@ indicated by exit code 1. Show the status of an evaluation that has placement failures ``` -$ nomad eval-status 2ae0e6a5 +$ nomad eval status 2ae0e6a5 ID = 2ae0e6a5 Status = complete Status Description = complete @@ -79,7 +79,7 @@ Evaluation "67493a64" waiting for additional capacity to place remainder Monitor an existing evaluation ``` -$ nomad eval-status -monitor 8262bc83 +$ nomad eval status -monitor 8262bc83 ==> Monitoring evaluation "8262bc83" Allocation "bd6bd0de" created: node "6f299da5", group "group1" Evaluation status changed: "pending" -> "complete" diff --git a/website/source/docs/commands/index.html.md.erb b/website/source/docs/commands/index.html.md.erb index a39c18ecf7e..b25db2bcab6 100644 --- a/website/source/docs/commands/index.html.md.erb +++ b/website/source/docs/commands/index.html.md.erb @@ -42,10 +42,10 @@ the CLI is most commonly used to manipulate or query jobs, you can assume that any given command is working in that context unless the command name implies otherwise. -For example, the `nomad run` command is used to run a new job, the `nomad +For example, the `nomad job run` command is used to run a new job, the `nomad status` command queries information about existing jobs, etc. Conversely, commands with a prefix in their name likely operate in a different context. -Examples include the `nomad agent-info` or `nomad node-drain` commands, +Examples include the `nomad agent-info` or `nomad node drain` commands, which operate in the agent or node contexts respectively. ### Remote Usage diff --git a/website/source/docs/commands/job.html.md.erb b/website/source/docs/commands/job.html.md.erb index dc8c2f458e2..1677fd51486 100644 --- a/website/source/docs/commands/job.html.md.erb +++ b/website/source/docs/commands/job.html.md.erb @@ -6,10 +6,8 @@ description: > The job command is used to interact with jobs. --- -# Nomad Job +# Command: job -Command: `nomad job` - The `job` command is used to interact with jobs. ## Usage diff --git a/website/source/docs/commands/job/dispatch.html.md.erb b/website/source/docs/commands/job/dispatch.html.md.erb index 9c3c1d14628..6aa10553656 100644 --- a/website/source/docs/commands/job/dispatch.html.md.erb +++ b/website/source/docs/commands/job/dispatch.html.md.erb @@ -54,7 +54,7 @@ client connection issues or internal errors, are indicated by exit code 1. * `-detach`: Return immediately instead of monitoring. A new evaluation ID will be output, which can be used to examine the evaluation using the - [eval-status](/docs/commands/eval-status.html) command + [eval status](/docs/commands/eval-status.html) command * `-verbose`: Show full information. diff --git a/website/source/docs/commands/init.html.md.erb b/website/source/docs/commands/job/init.html.md.erb similarity index 61% rename from website/source/docs/commands/init.html.md.erb rename to website/source/docs/commands/job/init.html.md.erb index 61efa4b084a..9f4f2407733 100644 --- a/website/source/docs/commands/init.html.md.erb +++ b/website/source/docs/commands/job/init.html.md.erb @@ -1,14 +1,15 @@ --- layout: "docs" -page_title: "Commands: init" -sidebar_current: "docs-commands-init" +page_title: "Commands: job init" +sidebar_current: "docs-commands-job-init" description: > - Generate a skeleton jobspec template. + The job init command is used to generate a skeleton jobspec template. --- -# Command: init +# Command: job init +**Alias: `nomad init`** -The `init` command creates an example [job specification][jobspec] in the +The `job init` command creates an example [job specification][jobspec] in the current directory that demonstrates some common configurations for tasks, task groups, runtime constraints, and resource allocation. @@ -20,7 +21,7 @@ pages to learn how to customize the template. Generate an example job file: ```text -$ nomad init +$ nomad job init Example job file written to example.nomad ``` diff --git a/website/source/docs/commands/inspect.html.md.erb b/website/source/docs/commands/job/inspect.html.md.erb similarity index 91% rename from website/source/docs/commands/inspect.html.md.erb rename to website/source/docs/commands/job/inspect.html.md.erb index ebe2e37415e..485dc23862e 100644 --- a/website/source/docs/commands/inspect.html.md.erb +++ b/website/source/docs/commands/job/inspect.html.md.erb @@ -1,22 +1,23 @@ --- layout: "docs" -page_title: "Commands: inspect" -sidebar_current: "docs-commands-inspect" +page_title: "Commands: job inspect" +sidebar_current: "docs-commands-job-inspect" description: > - The inspect command is used to inspect a submitted job. + The job inspect command is used to inspect a submitted job. --- -# Command: inspect +# Command: job inspect +**Alias: `nomad inspect`** -The `inspect` command is used to inspect the content of a submitted job. +The `job inspect` command is used to inspect the content of a submitted job. ## Usage ``` -nomad inspect [options] +nomad job inspect [options] ``` -The `inspect` command requires a single argument, a submitted job's name, and +The `job inspect` command requires a single argument, a submitted job's name, and will retrieve the JSON version of the job. This JSON is valid to be submitted to the [Job HTTP API](/api/jobs.html). This command is useful to inspect what version of a job Nomad is running. @@ -38,7 +39,7 @@ version of a job Nomad is running. Inspect a submitted job: ``` -$ nomad inspect redis +$ nomad job inspect redis { "Job": { "Region": "global", diff --git a/website/source/docs/commands/plan.html.md.erb b/website/source/docs/commands/job/plan.html.md.erb similarity index 86% rename from website/source/docs/commands/plan.html.md.erb rename to website/source/docs/commands/job/plan.html.md.erb index d72c2da17df..ce6c0caf911 100644 --- a/website/source/docs/commands/plan.html.md.erb +++ b/website/source/docs/commands/job/plan.html.md.erb @@ -1,14 +1,15 @@ --- layout: "docs" -page_title: "Commands: plan" -sidebar_current: "docs-commands-plan" +page_title: "Commands: job plan" +sidebar_current: "docs-commands-job-plan" description: > - The plan command is used to dry-run a job update to determine its effects. + The job plan command is used to dry-run a job update to determine its effects. --- -# Command: plan +# Command: job plan +**Alias: `nomad plan`** -The `plan` command can be used to invoke the scheduler in a dry-run mode with +The `job plan` command can be used to invoke the scheduler in a dry-run mode with new jobs or when updating existing jobs to determine what would happen if the job is submitted. Job files must conform to the [job specification](/docs/job-specification/index.html) format. @@ -16,10 +17,10 @@ specification](/docs/job-specification/index.html) format. ## Usage ``` -nomad plan [options] +nomad job plan [options] ``` -The plan command requires a single argument, specifying the path to a file +The `job plan` command requires a single argument, specifying the path to a file containing a [HCL job specification](/docs/job-specification/index.html). This file will be read and the resulting parsed job will be validated. If the supplied path is "-", the job file is read from STDIN. Otherwise it is read @@ -34,8 +35,8 @@ changes to the cluster but gives insight into whether the job could be run successfully and how it would affect existing allocations. A job modify index is returned with the plan. This value can be used when -submitting the job using [`nomad run --check-index`](/docs/commands/run.html#check-index), which will check that the +submitting the job using [`nomad job run +-check-index`](/docs/commands/job/run.html#check-index), which will check that the job was not modified between the plan and run command before invoking the scheduler. This ensures the job has not been modified since the plan. @@ -69,8 +70,8 @@ Plan will return one of the following exit codes: Plan a new job that has not been previously submitted: ``` -$ nomad run job1.nomad -nomad plan example.nomad +$ nomad job plan job1.nomad +nomad job plan example.nomad + Job: "example" + Task Group: "cache" (1 create) + Task: "redis" (forces create) @@ -81,7 +82,7 @@ Scheduler dry-run: Job Modify Index: 0 To submit the job with version verification run: -nomad run -check-index 0 example.nomad +nomad job run -check-index 0 example.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has @@ -93,7 +94,7 @@ potentially invalid. Increase the count of an existing without sufficient cluster capacity: ``` -$ nomad plan example.nomad +$ nomad job plan example.nomad +/- Job: "example" +/- Task Group: "cache" (7 create, 1 in-place update) +/- Count: "1" => "8" (forces create) @@ -108,7 +109,7 @@ Scheduler dry-run: Job Modify Index: 15 To submit the job with version verification run: -nomad run -check-index 15 example.nomad +nomad job run -check-index 15 example.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has @@ -119,7 +120,7 @@ potentially invalid. Update an existing job such that it would cause a rolling update: ``` -$ nomad plan example.nomad +$ nomad job plan example.nomad +/- Job: "example" +/- Task Group: "cache" (3 create/destroy update) +/- Task: "redis" (forces create/destroy update) @@ -135,7 +136,7 @@ Scheduler dry-run: Job Modify Index: 7 To submit the job with version verification run: -nomad run -check-index 7 example.nomad +nomad job run -check-index 7 example.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has @@ -146,7 +147,7 @@ potentially invalid. Add a task to the task group using verbose mode: ``` -$ nomad plan -verbose example.nomad +$ nomad job plan -verbose example.nomad +/- Job: "example" +/- Task Group: "cache" (3 create/destroy update) + Task: "my-website" (forces create/destroy update) @@ -194,7 +195,7 @@ Scheduler dry-run: Job Modify Index: 7 To submit the job with version verification run: -nomad run -check-index 7 example.nomad +nomad job run -check-index 7 example.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has diff --git a/website/source/docs/commands/job/promote.html.md.erb b/website/source/docs/commands/job/promote.html.md.erb index 28b7fba77ef..860d223c1f0 100644 --- a/website/source/docs/commands/job/promote.html.md.erb +++ b/website/source/docs/commands/job/promote.html.md.erb @@ -40,7 +40,7 @@ select particular groups to promote. * `-detach`: Return immediately instead of monitoring. A new evaluation ID will be output, which can be used to examine the evaluation using the - [eval-status](/docs/commands/eval-status.html) command + [eval status](/docs/commands/eval-status.html) command * `-verbose`: Show full information. diff --git a/website/source/docs/commands/job/revert.html.md.erb b/website/source/docs/commands/job/revert.html.md.erb index 22bf6cfd8ac..3c069524694 100644 --- a/website/source/docs/commands/job/revert.html.md.erb +++ b/website/source/docs/commands/job/revert.html.md.erb @@ -29,7 +29,7 @@ to revert to. * `-detach`: Return immediately instead of monitoring. A new evaluation ID will be output, which can be used to examine the evaluation using the - [eval-status](/docs/commands/eval-status.html) command + [eval status](/docs/commands/eval-status.html) command * `-verbose`: Show full information. diff --git a/website/source/docs/commands/run.html.md.erb b/website/source/docs/commands/job/run.html.md.erb similarity index 86% rename from website/source/docs/commands/run.html.md.erb rename to website/source/docs/commands/job/run.html.md.erb index 2ea69810ec4..b2bdc078293 100644 --- a/website/source/docs/commands/run.html.md.erb +++ b/website/source/docs/commands/job/run.html.md.erb @@ -1,24 +1,25 @@ --- layout: "docs" -page_title: "Commands: run" -sidebar_current: "docs-commands-run" +page_title: "Commands: job run" +sidebar_current: "docs-commands-job-run" description: > - The run command is used to run a new job. + The job run command is used to run a new job. --- -# Command: run +# Command: job run +**Alias: `nomad run`** -The `run` command is used to submit new jobs to Nomad or to update existing +The `job run` command is used to submit new jobs to Nomad or to update existing jobs. Job files must conform to the [job specification](/docs/job-specification/index.html) format. ## Usage ``` -nomad run [options] +nomad job run [options] ``` -The run command requires a single argument, specifying the path to a file +The `job run` command requires a single argument, specifying the path to a file containing a valid [job specification](/docs/job-specification/index.html). This file will be read and the job will be submitted to Nomad for scheduling. If the supplied path is "-", the job file is read from STDIN. Otherwise it is read @@ -54,11 +55,11 @@ precedence, going from highest to lowest: the `-vault-token` flag, the If a check-index value of zero is passed, the job is only registered if it does not yet exist. If a non-zero value is passed, it ensures that the job is being updated from a known state. The use of this flag is most common in conjunction - with [plan command](/docs/commands/plan.html). + with [`job plan` command](/docs/commands/job/plan.html). * `-detach`: Return immediately instead of monitoring. A new evaluation ID will be output, which can be used to examine the evaluation using the - [eval-status](/docs/commands/eval-status.html) command + [eval status](/docs/commands/eval-status.html) command * `-output`: Output the JSON that would be submitted to the HTTP API without submitting the job. @@ -77,7 +78,7 @@ precedence, going from highest to lowest: the `-vault-token` flag, the Schedule the job contained in the file `job1.nomad`, monitoring placement: ``` -$ nomad run job1.nomad +$ nomad job run job1.nomad ==> Monitoring evaluation "52dee78a" Evaluation triggered by job "example" Evaluation within deployment: "62eb607c" @@ -90,11 +91,11 @@ $ nomad run job1.nomad Update the job using `check-index`: ``` -$ nomad run -check-index 5 example.nomad +$ nomad job run -check-index 5 example.nomad Enforcing job modify index 5: job exists with conflicting job modify index: 6 Job not updated -$ nomad run -check-index 6 example.nomad +$ nomad job run -check-index 6 example.nomad ==> Monitoring evaluation "5ef16dff" Evaluation triggered by job "example" Evaluation within deployment: "62eb607c" @@ -106,7 +107,7 @@ $ nomad run -check-index 6 example.nomad Schedule the job contained in `job1.nomad` and return immediately: ``` -$ nomad run -detach job1.nomad +$ nomad job run -detach job1.nomad 4947e728 ``` @@ -114,7 +115,7 @@ Schedule a job which cannot be successfully placed. This results in a scheduling failure and the specifics of the placement are printed: ``` -$ nomad run failing.nomad +$ nomad job run failing.nomad ==> Monitoring evaluation "2ae0e6a5" Evaluation triggered by job "example" Evaluation status changed: "pending" -> "complete" diff --git a/website/source/docs/commands/stop.html.md.erb b/website/source/docs/commands/job/stop.html.md.erb similarity index 73% rename from website/source/docs/commands/stop.html.md.erb rename to website/source/docs/commands/job/stop.html.md.erb index 9040ae1db3d..b44d3ec9aa7 100644 --- a/website/source/docs/commands/stop.html.md.erb +++ b/website/source/docs/commands/job/stop.html.md.erb @@ -1,23 +1,24 @@ --- layout: "docs" -page_title: "Commands: stop" -sidebar_current: "docs-commands-stop" +page_title: "Commands: job stop" +sidebar_current: "docs-commands-job-stop" description: > - The stop command is used to stop a running job. + The job stop command is used to stop a running job. --- -# Command: stop +# Command: job stop +**Alias: `nomad stop`** -The `stop` command is used to stop a running job and signals the scheduler +The `job stop` command is used to stop a running job and signals the scheduler to cancel all of the running allocations. ## Usage ``` -nomad stop [options] +nomad job stop [options] ``` -The stop command requires a single argument, specifying the job ID or prefix to +The `job stop` command requires a single argument, specifying the job ID or prefix to cancel. If there is an exact match based on the provided job ID or prefix, then the job will be cancelled. Otherwise, a list of matching jobs and information will be displayed. @@ -35,7 +36,7 @@ the request. It is safe to exit the monitor early using ctrl+c. * `-detach`: Return immediately instead of entering monitor mode. After the deregister command is submitted, a new evaluation ID is printed to the screen, which can be used to examine the evaluation using the - [eval-status](/docs/commands/eval-status.html) command. + [eval status](/docs/commands/eval-status.html) command. * `-verbose`: Show full information. @@ -51,7 +52,7 @@ collector. Stop the job with ID "job1": ``` -$ nomad stop job1 +$ nomad job stop job1 ==> Monitoring evaluation "43bfe672" Evaluation status changed: "pending" -> "complete" ==> Evaluation "43bfe672" finished with status "complete" @@ -60,6 +61,6 @@ $ nomad stop job1 Stop the job with ID "job1" and return immediately: ``` -$ nomad stop -detach job1 +$ nomad job stop -detach job1 507d26cb ``` diff --git a/website/source/docs/commands/validate.html.md.erb b/website/source/docs/commands/job/validate.html.md.erb similarity index 68% rename from website/source/docs/commands/validate.html.md.erb rename to website/source/docs/commands/job/validate.html.md.erb index 7988544c3ab..1da8a62c855 100644 --- a/website/source/docs/commands/validate.html.md.erb +++ b/website/source/docs/commands/job/validate.html.md.erb @@ -1,23 +1,24 @@ --- layout: "docs" -page_title: "Commands: validate" -sidebar_current: "docs-commands-validate" +page_title: "Commands: job validate" +sidebar_current: "docs-commands-job-validate" description: > - The validate command is used to check a job specification for syntax errors and validation problems. + The job validate command is used to check a job specification for syntax errors and validation problems. --- -# Command: validate +# Command: job validate +**Alias: `nomad validate`** -The `validate` command is used to check a [HCL job specification](/docs/job-specification/index.html) +The `job validate` command is used to check a [HCL job specification](/docs/job-specification/index.html) for any syntax errors or validation problems. ## Usage ``` -nomad validate +nomad job validate ``` -The validate command requires a single argument, specifying the path to a file +The `job validate` command requires a single argument, specifying the path to a file containing a [HCL job specification](/docs/job-specification/index.html). This file will be read and the job checked for any problems. If the supplied path is "-", the job file is read from STDIN. Otherwise it is read @@ -33,7 +34,7 @@ of 1 indicates an error. Validate a job with invalid syntax: ``` -$ nomad validate example.nomad +$ nomad job validate example.nomad Job validation errors: 1 error(s) occurred: @@ -45,7 +46,7 @@ Job validation errors: Validate a job that has a configuration that causes warnings: ``` -$ nomad validate example.nomad +$ nomad job validate example.nomad Job Warnings: 1 warning(s): diff --git a/website/source/docs/commands/namespace.html.md.erb b/website/source/docs/commands/namespace.html.md.erb index cfdc2d6f4a1..ccb90ebcc3b 100644 --- a/website/source/docs/commands/namespace.html.md.erb +++ b/website/source/docs/commands/namespace.html.md.erb @@ -6,12 +6,13 @@ description: > The namespace command is used to interact with namespaces. --- -# Nomad Namespace - -Command: `nomad namespace` +# Command: namespace The `namespace` command is used to interact with namespaces. +~> Namespace commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage Usage: `nomad namespace [options]` diff --git a/website/source/docs/commands/namespace/inspect.html.md.erb b/website/source/docs/commands/namespace/inspect.html.md.erb index 34788da1b21..e24ba498b27 100644 --- a/website/source/docs/commands/namespace/inspect.html.md.erb +++ b/website/source/docs/commands/namespace/inspect.html.md.erb @@ -12,6 +12,9 @@ description: > The `namespace inspect` command is used to view raw information about a particular namespace. +~> Namespace commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/namespace/status.html.md.erb b/website/source/docs/commands/namespace/status.html.md.erb index 8c16fa91faa..ce26d90ecc2 100644 --- a/website/source/docs/commands/namespace/status.html.md.erb +++ b/website/source/docs/commands/namespace/status.html.md.erb @@ -12,6 +12,9 @@ description: > The `namespace status` command is used to view the status of a particular namespace. +~> Namespace commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/node.html.md.erb b/website/source/docs/commands/node.html.md.erb new file mode 100644 index 00000000000..58c7be7b955 --- /dev/null +++ b/website/source/docs/commands/node.html.md.erb @@ -0,0 +1,26 @@ +--- +layout: "docs" +page_title: "Commands: node" +sidebar_current: "docs-commands-node" +description: > + The node command is used to interact with nodes. +--- + +# Command: node + +The `node` command is used to interact with nodes. + +## Usage + +Usage: `nomad node [options]` + +Run `nomad node -h` for help on that subcommand. The following +subcommands are available: + +* [`node config`][config] - View or modify client configuration details +* [`node drain`][drain] - Toggle drain mode on a given node +* [`node status`][status] - Display status information about nodes + +[config]: /docs/commands/node/config.html "View or modify client configuration details" +[drain]: /docs/commands/node/drain.html "Toggle drain mode on a given node" +[status]: /docs/commands/node/status.html "Display status information about nodes" diff --git a/website/source/docs/commands/client-config.html.md.erb b/website/source/docs/commands/node/config.html.md.erb similarity index 75% rename from website/source/docs/commands/client-config.html.md.erb rename to website/source/docs/commands/node/config.html.md.erb index 7c0839b8c8b..aeda023a96a 100644 --- a/website/source/docs/commands/client-config.html.md.erb +++ b/website/source/docs/commands/node/config.html.md.erb @@ -1,21 +1,21 @@ --- layout: "docs" -page_title: "Commands: client-config" -sidebar_current: "docs-commands-client-config" +page_title: "Commands: node config" +sidebar_current: "docs-commands-node-config" description: > - The client-config command is used to view or modify client configuration. + The node config command is used to view or modify client configuration. --- -# Command: client-config +# Command: node config -The `client-config` command is used to view or modify client configuration +The `node config` command is used to view or modify client configuration details. This command only works on client nodes, and can be used to update the running client configurations it supports. ## Usage ``` -nomad client-config [options] +nomad node config [options] ``` The arguments behave differently depending on the flags given. See each flag's @@ -25,7 +25,7 @@ description below for specific usage information and requirements. <%= partial "docs/commands/_general_options" %> -## Client Config Options +## Node Config Options * `-servers`: List the client's known servers. Client nodes do not participate in the gossip pool, and instead register with these servers periodically over @@ -45,7 +45,7 @@ description below for specific usage information and requirements. Query the currently known servers: ``` -$ nomad client-config -servers +$ nomad node config -servers server1:4647 server2:4647 ``` @@ -53,5 +53,5 @@ server2:4647 Update the list of servers: ``` -$ nomad client-config -update-servers server1:4647 server2:4647 server3:4647 server4 +$ nomad node config -update-servers server1:4647 server2:4647 server3:4647 server4 ``` diff --git a/website/source/docs/commands/node-drain.html.md.erb b/website/source/docs/commands/node/drain.html.md.erb similarity index 72% rename from website/source/docs/commands/node-drain.html.md.erb rename to website/source/docs/commands/node/drain.html.md.erb index d0971157574..ca8944daf46 100644 --- a/website/source/docs/commands/node-drain.html.md.erb +++ b/website/source/docs/commands/node/drain.html.md.erb @@ -1,24 +1,24 @@ --- layout: "docs" -page_title: "Commands: node-drain" +page_title: "Commands: node drain" sidebar_current: "docs-commands-node-drain" description: > - Toggle drain mode for a given node. + The node drain command is used to configure a node's drain strategy. --- -# Command: node-drain +# Command: node drain -The `node-drain` command is used to toggle drain mode on a given node. Drain +The `node drain` command is used to toggle drain mode on a given node. Drain mode prevents any new tasks from being allocated to the node, and begins migrating all existing allocations away. -The [node-status](/docs/commands/node-status.html) command compliments this +The [node status](/docs/commands/node/status.html) command compliments this nicely by providing the current drain status of a given node. ## Usage ``` -nomad node-drain [options] +nomad node drain [options] ``` A `-self` flag can be used to drain the local node. If this is not supplied, a @@ -33,7 +33,7 @@ operation is desired. <%= partial "docs/commands/_general_options" %> -## Node Drain Options +## Drain Options * `-enable`: Enable node drain mode. * `-disable`: Disable node drain mode. @@ -45,11 +45,11 @@ operation is desired. Enable drain mode on node with ID prefix "4d2ba53b": ``` -$ nomad node-drain -enable 4d2ba53b +$ nomad node drain -enable 4d2ba53b ``` Enable drain mode on the local node: ``` -$ nomad node-drain -enable -self +$ nomad node drain -enable -self ``` diff --git a/website/source/docs/commands/node-status.html.md.erb b/website/source/docs/commands/node/status.html.md.erb similarity index 94% rename from website/source/docs/commands/node-status.html.md.erb rename to website/source/docs/commands/node/status.html.md.erb index 8231fe8bde4..a00da802f21 100644 --- a/website/source/docs/commands/node-status.html.md.erb +++ b/website/source/docs/commands/node/status.html.md.erb @@ -1,21 +1,21 @@ --- layout: "docs" -page_title: "Commands: node-status" +page_title: "Commands: node status" sidebar_current: "docs-commands-node-status" description: > - Display information about nodes. + The node status command is used to display information about nodes. --- -# Command: node-status +# Command: node status -The `node-status` command is used to display information about client nodes. A +The `node status` command is used to display information about client nodes. A node must first be registered with the servers before it will be visible in this output. ## Usage ``` -nomad node-status [options] [node] +nomad node status [options] [node] ``` If no node ID is passed, then the command will enter "list mode" and dump a @@ -32,7 +32,7 @@ information will be displayed. If running the command on a Nomad Client, the <%= partial "docs/commands/_general_options" %> -## Node Status Options +## Status Options * `-self`: Query the status of the local node. @@ -55,7 +55,7 @@ information will be displayed. If running the command on a Nomad Client, the List view: ``` -$ nomad node-status +$ nomad node status ID DC Name Drain Status a72dfba2 dc1 node1 false ready 1f3f03ea dc1 node2 false ready @@ -64,7 +64,7 @@ a72dfba2 dc1 node1 false ready List view, with running allocations: ``` -$ nomad node-status -allocs +$ nomad node status -allocs ID DC Name Class Drain Status Running Allocs 4d2ba53b dc1 node1 false ready 1 34dfba32 dc1 node2 false ready 3 @@ -73,7 +73,7 @@ ID DC Name Class Drain Status Running Allocs Single-node view in short mode: ``` -$ nomad node-status -short 1f3f03ea +$ nomad node status -short 1f3f03ea ID = c754da1f Name = nomad Class = @@ -90,7 +90,7 @@ ID Eval ID Job ID Task Group Desired Status Client Status Full output for a single node: ``` -$ nomad node-status 1f3f03ea +$ nomad node status 1f3f03ea ID = c754da1f Name = nomad-server01 Class = @@ -119,7 +119,7 @@ ID Eval ID Job ID Task Group Desired Status Client Status Using `-self` when on a Nomad Client: ``` -$ nomad node-status -self +$ nomad node status -self ID = c754da1f Name = nomad-client01 Class = @@ -170,7 +170,7 @@ the following: Using `-stats` to see detailed to resource usage information on the node: ``` -$ nomad node-status -stats c754da1f +$ nomad node status -stats c754da1f ID = c754da1f Name = nomad-client01 Class = @@ -237,7 +237,7 @@ ed3665f5 8bf94335 example cache run running To view verbose information about the node: ``` -$ nomad node-status -verbose c754da1f +$ nomad node status -verbose c754da1f ID = c754da1f-6337-b86d-47dc-2ef4c71aca14 Name = nomad Class = diff --git a/website/source/docs/commands/operator.html.md.erb b/website/source/docs/commands/operator.html.md.erb index 8189e7b8881..c96d14e5440 100644 --- a/website/source/docs/commands/operator.html.md.erb +++ b/website/source/docs/commands/operator.html.md.erb @@ -6,9 +6,7 @@ description: > The operator command provides cluster-level tools for Nomad operators. --- -# Nomad Operator - -Command: `nomad operator` +# Command: operator The `operator` command provides cluster-level tools for Nomad operators, such as interacting with the Raft subsystem. This was added in Nomad 0.5.5. @@ -28,12 +26,16 @@ Usage: `nomad operator [options]` Run `nomad operator ` with no arguments for help on that subcommand. The following subcommands are available: -* [`autopilot get-config`][get-config] - Display the current Autopilot configuration -* [`autopilot set-config`][set-config] - Modify the current Autopilot configuration -* [`raft list-peers`][list] - Display the current Raft peer configuration -* [`raft remove-peer`][remove] - Remove a Nomad server from the Raft configuration +* [`operator autopilot get-config`][get-config] - Display the current Autopilot configuration +* [`operator autopilot set-config`][set-config] - Modify the current Autopilot configuration +* [`operator keygen`][keygen] - Generates a new encryption key +* [`operator keyring`][keyring] - Manages gossip layer encryption keys +* [`operator raft list-peers`][list] - Display the current Raft peer configuration +* [`operator raft remove-peer`][remove] - Remove a Nomad server from the Raft configuration [get-config]: /docs/commands/operator/autopilot-get-config.html "Autopilot Get Config command" [set-config]: /docs/commands/operator/autopilot-set-config.html "Autopilot Set Config command" +[keygen]: /docs/commands/operator/keygen.html "Generates a new encryption key" +[keyring]: /docs/commands/operator/keyring.html "Manages gossip layer encryption keys" [list]: /docs/commands/operator/raft-list-peers.html "Raft List Peers command" [remove]: /docs/commands/operator/raft-remove-peer.html "Raft Remove Peer command" diff --git a/website/source/docs/commands/operator/autopilot-get-config.html.md.erb b/website/source/docs/commands/operator/autopilot-get-config.html.md.erb index b3eefad290c..3e8d0618632 100644 --- a/website/source/docs/commands/operator/autopilot-get-config.html.md.erb +++ b/website/source/docs/commands/operator/autopilot-get-config.html.md.erb @@ -6,7 +6,7 @@ description: > Display the current Autopilot configuration. --- -# Command: `operator autopilot get-config` +# Command: operator autopilot get-config The Autopilot operator command is used to view the current Autopilot configuration. See the [Autopilot Guide](/guides/cluster/autopilot.html) for more information about Autopilot. @@ -60,4 +60,4 @@ UpgradeMigrationTag = "" - `UpgradeVersionTag` - Controls the node-meta key to use for version info when performing upgrade migrations. If left blank, the Nomad - version will be used. \ No newline at end of file + version will be used. diff --git a/website/source/docs/commands/operator/autopilot-set-config.html.md.erb b/website/source/docs/commands/operator/autopilot-set-config.html.md.erb index 6a683899eca..08efbc99d1c 100644 --- a/website/source/docs/commands/operator/autopilot-set-config.html.md.erb +++ b/website/source/docs/commands/operator/autopilot-set-config.html.md.erb @@ -6,7 +6,7 @@ description: > Modify the current Autopilot configuration. --- -# Command: `operator autopilot set-config` +# Command: operator autopilot set-config The Autopilot operator command is used to set the current Autopilot configuration. See the [Autopilot Guide](/guides/cluster/autopilot.html) for more information about Autopilot. diff --git a/website/source/docs/commands/keygen.html.md.erb b/website/source/docs/commands/operator/keygen.html.md.erb similarity index 54% rename from website/source/docs/commands/keygen.html.md.erb rename to website/source/docs/commands/operator/keygen.html.md.erb index d92a79ce712..18e88567439 100644 --- a/website/source/docs/commands/keygen.html.md.erb +++ b/website/source/docs/commands/operator/keygen.html.md.erb @@ -1,30 +1,29 @@ --- layout: "docs" -page_title: "Commands: keygen" -sidebar_current: "docs-commands-keygen" +page_title: "Commands: operator keygen" +sidebar_current: "docs-commands-operator-keygen" description: > - The `keygen` command generates an encryption key that can be used for Nomad + The `operator keygen` command generates an encryption key that can be used for Nomad server's gossip traffic encryption. The keygen command uses a cryptographically strong pseudo-random number generator to generate the key. --- +# Command: operator keygen -# Command: `keygen` - -The `keygen` command generates an encryption key that can be used for Nomad +The `operator keygen` command generates an encryption key that can be used for Nomad server's gossip traffic encryption. The keygen command uses a cryptographically strong pseudo-random number generator to generate the key. ## Usage ``` -nomad keygen +nomad operator keygen ``` ## Example ``` -nomad keygen +nomad operator keygen YgZOXLMhC7TtZqeghMT8+w== ``` diff --git a/website/source/docs/commands/keyring.html.md.erb b/website/source/docs/commands/operator/keyring.html.md.erb similarity index 74% rename from website/source/docs/commands/keyring.html.md.erb rename to website/source/docs/commands/operator/keyring.html.md.erb index 46e45c4d7c5..6a136efaf8e 100644 --- a/website/source/docs/commands/keyring.html.md.erb +++ b/website/source/docs/commands/operator/keyring.html.md.erb @@ -1,15 +1,15 @@ --- layout: "docs" -page_title: "Commands: keyring" -sidebar_current: "docs-commands-keyring" +page_title: "Commands: operator keyring" +sidebar_current: "docs-commands-operator-keyring" --- -# Command: `keyring` +# Command: operator keyring -The `keyring` command is used to examine and modify the encryption keys used in -Nomad server. It is capable of distributing new encryption keys to the cluster, -retiring old encryption keys, and changing the keys used by the cluster to -encrypt messages. +The `operator keyring` command is used to examine and modify the encryption keys +used in Nomad server. It is capable of distributing new encryption keys to the +cluster, retiring old encryption keys, and changing the keys used by the cluster +to encrypt messages. Nomad allows multiple encryption keys to be in use simultaneously. This is intended to provide a transition state while the cluster converges. It is the @@ -27,7 +27,7 @@ will be 1. ## Usage -Usage: `nomad keyring [options]` +Usage: `nomad operator keyring [options]` Only one actionable argument may be specified per run, including `-list`, `-install`, `-remove`, and `-use`. @@ -47,7 +47,7 @@ The list of available flags are: ## Output -The output of the `nomad keyring -list` command consolidates information from +The output of the `nomad operator keyring -list` command consolidates information from all the Nomad servers from all datacenters and regions to provide a simple and easy to understand view of the cluster. diff --git a/website/source/docs/commands/operator/raft-list-peers.html.md.erb b/website/source/docs/commands/operator/raft-list-peers.html.md.erb index 95819f6a940..027a87fab24 100644 --- a/website/source/docs/commands/operator/raft-list-peers.html.md.erb +++ b/website/source/docs/commands/operator/raft-list-peers.html.md.erb @@ -6,7 +6,7 @@ description: > Display the current Raft peer configuration. --- -# Command: `operator raft list-peers` +# Command: operator raft list-peers The Raft list-peers command is used to display the current Raft peer configuration. diff --git a/website/source/docs/commands/operator/raft-remove-peer.html.md.erb b/website/source/docs/commands/operator/raft-remove-peer.html.md.erb index 6629df925f2..0cf66000e64 100644 --- a/website/source/docs/commands/operator/raft-remove-peer.html.md.erb +++ b/website/source/docs/commands/operator/raft-remove-peer.html.md.erb @@ -6,7 +6,7 @@ description: > Remove a Nomad server from the Raft configuration. --- -# Command: `operator raft remove-peer` +# Command: operator raft remove-peer Remove the Nomad server with given address from the Raft configuration. @@ -14,9 +14,9 @@ There are rare cases where a peer may be left behind in the Raft quorum even though the server is no longer present and known to the cluster. This command can be used to remove the failed server so that it is no longer affects the Raft quorum. If the server still shows in the output of the [`nomad -server-members`](/docs/commands/server-members.html) command, it is preferable +server members`](/docs/commands/server/members.html) command, it is preferable to clean up by simply running [`nomad -server-force-leave`](/docs/commands/server-force-leave.html) instead of this +server force-leave`](/docs/commands/server/force-leave.html) instead of this command. See the [Outage Recovery](/guides/outage.html) guide for some examples of how diff --git a/website/source/docs/commands/quota.html.md.erb b/website/source/docs/commands/quota.html.md.erb index 52463b1ab4a..38ae5102ca6 100644 --- a/website/source/docs/commands/quota.html.md.erb +++ b/website/source/docs/commands/quota.html.md.erb @@ -6,12 +6,13 @@ description: > The quota command is used to interact with quota specifications. --- -# Nomad Quota - -Command: `nomad quota` +# Command: quota The `quota` command is used to interact with quota specifications. +~> Quota commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage Usage: `nomad quota [options]` diff --git a/website/source/docs/commands/quota/apply.html.md.erb b/website/source/docs/commands/quota/apply.html.md.erb index af738b25dc1..ec023362edb 100644 --- a/website/source/docs/commands/quota/apply.html.md.erb +++ b/website/source/docs/commands/quota/apply.html.md.erb @@ -10,6 +10,9 @@ description: > The `quota apply` command is used to create or update quota specifications. +~> Quota commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/quota/delete.html.md.erb b/website/source/docs/commands/quota/delete.html.md.erb index 8f5b13d152a..4baa2bf5846 100644 --- a/website/source/docs/commands/quota/delete.html.md.erb +++ b/website/source/docs/commands/quota/delete.html.md.erb @@ -10,6 +10,9 @@ description: > The `quota delete` command is used to delete an existing quota specification. +~> Quota commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/quota/init.html.md.erb b/website/source/docs/commands/quota/init.html.md.erb index 1f80d2bcc30..d1b2222f6ea 100644 --- a/website/source/docs/commands/quota/init.html.md.erb +++ b/website/source/docs/commands/quota/init.html.md.erb @@ -11,6 +11,9 @@ description: > The `quota init` command is used to create an example quota specification file that can be used as a starting point to customize further. +~> Quota commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/quota/inspect.html.md.erb b/website/source/docs/commands/quota/inspect.html.md.erb index 8057d1017ff..5ed911e3891 100644 --- a/website/source/docs/commands/quota/inspect.html.md.erb +++ b/website/source/docs/commands/quota/inspect.html.md.erb @@ -12,6 +12,9 @@ description: > The `quota inspect` command is used to view raw information about a particular quota. +~> Quota commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/quota/list.html.md.erb b/website/source/docs/commands/quota/list.html.md.erb index 63365966efb..7380df3fd35 100644 --- a/website/source/docs/commands/quota/list.html.md.erb +++ b/website/source/docs/commands/quota/list.html.md.erb @@ -10,6 +10,9 @@ description: > The `quota list` command is used to list available quota specifications. +~> Quota commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/quota/status.html.md.erb b/website/source/docs/commands/quota/status.html.md.erb index 2734e9220c8..626654bffc7 100644 --- a/website/source/docs/commands/quota/status.html.md.erb +++ b/website/source/docs/commands/quota/status.html.md.erb @@ -12,6 +12,9 @@ description: > The `quota status` command is used to view the status of a particular quota specification. +~> Quota commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/sentinel.html.md.erb b/website/source/docs/commands/sentinel.html.md.erb index 92bcf621f1e..e3895423c08 100644 --- a/website/source/docs/commands/sentinel.html.md.erb +++ b/website/source/docs/commands/sentinel.html.md.erb @@ -6,12 +6,13 @@ description: > The sentinel command is used to interact with Sentinel policies. --- -# Nomad Sentinel - -Command: `nomad sentinel` +# Command: sentinel The `sentinel` command is used to interact with Sentinel policies. +~> Sentinel commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage Usage: `nomad sentinel [options]` diff --git a/website/source/docs/commands/sentinel/apply.html.md.erb b/website/source/docs/commands/sentinel/apply.html.md.erb index 093a2aa6619..8cc64200c47 100644 --- a/website/source/docs/commands/sentinel/apply.html.md.erb +++ b/website/source/docs/commands/sentinel/apply.html.md.erb @@ -10,6 +10,9 @@ description: > The `sentinel apply` command is used to write a new, or update an existing, Sentinel policy. +~> Sentinel commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/sentinel/delete.html.md.erb b/website/source/docs/commands/sentinel/delete.html.md.erb index 62fa2b0e11a..93b4a74dc5c 100644 --- a/website/source/docs/commands/sentinel/delete.html.md.erb +++ b/website/source/docs/commands/sentinel/delete.html.md.erb @@ -10,6 +10,9 @@ description: > The `sentinel delete` command is used to delete a Sentinel policy. +~> Sentinel commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/sentinel/list.html.md.erb b/website/source/docs/commands/sentinel/list.html.md.erb index d8a3a867904..4a979115c11 100644 --- a/website/source/docs/commands/sentinel/list.html.md.erb +++ b/website/source/docs/commands/sentinel/list.html.md.erb @@ -10,6 +10,9 @@ description: > The `sentinel list` command is used to display all the installed Sentinel policies. +~> Sentinel commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/sentinel/read.html.md.erb b/website/source/docs/commands/sentinel/read.html.md.erb index 76644251acc..782d79cadef 100644 --- a/website/source/docs/commands/sentinel/read.html.md.erb +++ b/website/source/docs/commands/sentinel/read.html.md.erb @@ -10,6 +10,9 @@ description: > The `sentinel read` command is used to inspect a Sentinel policy. +~> Sentinel commands are new in Nomad 0.7 and are only available with Nomad +Enterprise. + ## Usage ``` diff --git a/website/source/docs/commands/server.html.md.erb b/website/source/docs/commands/server.html.md.erb new file mode 100644 index 00000000000..912e1389549 --- /dev/null +++ b/website/source/docs/commands/server.html.md.erb @@ -0,0 +1,28 @@ +--- +layout: "docs" +page_title: "Commands: server" +sidebar_current: "docs-commands-server" +description: > + The server command is used to interact with Nomad servers. +--- + +# Command: server + +Command: `nomad server` + +The `server` command is used to interact with servers. + +## Usage + +Usage: `nomad server [options]` + +Run `nomad server -h` for help on that subcommand. The following +subcommands are available: + +* [`server force-leave`][force-leave] - Force a server into the 'left' state +* [`server join`][join] - Join server nodes together +* [`server members`][members] - Display a list of known servers and their status + +[force-leave]: /docs/commands/server/force-leave.html "Force a server into the 'left' state" +[join]: /docs/commands/server/join.html "Join server nodes together" +[members]: /docs/commands/server/members.html "Display a list of known servers and their status" diff --git a/website/source/docs/commands/server-force-leave.html.md.erb b/website/source/docs/commands/server/force-leave.html.md.erb similarity index 64% rename from website/source/docs/commands/server-force-leave.html.md.erb rename to website/source/docs/commands/server/force-leave.html.md.erb index fb46cd26773..dcab1c668c9 100644 --- a/website/source/docs/commands/server-force-leave.html.md.erb +++ b/website/source/docs/commands/server/force-leave.html.md.erb @@ -1,14 +1,14 @@ --- layout: "docs" -page_title: "Commands: server-force-leave" +page_title: "Commands: server force-leave" sidebar_current: "docs-commands-server-force-leave" description: > - Force a server into the "left" state. + The server force-leave command is used to force a server into the "left" state. --- -# Command: server-force-leave +# Command: server force-leave -The `server-force-leave` command forces a server to enter the "left" state. +The `server force-leave` command forces a server to enter the "left" state. This can be used to eject server nodes which have failed and will not rejoin the cluster. Note that if the server is actually still alive, it will eventually rejoin the cluster again. @@ -16,7 +16,7 @@ eventually rejoin the cluster again. ## Usage ``` -nomad server-force-leave [options] +nomad server force-leave [options] ``` This command expects only one argument - the node which should be forced @@ -31,5 +31,5 @@ to enter the "left" state. Force-leave the server "node1": ``` -$ nomad server-force-leave node1 +$ nomad server force-leave node1 ``` diff --git a/website/source/docs/commands/server-join.html.md.erb b/website/source/docs/commands/server/join.html.md.erb similarity index 71% rename from website/source/docs/commands/server-join.html.md.erb rename to website/source/docs/commands/server/join.html.md.erb index 03bf90c4026..60388ef8c22 100644 --- a/website/source/docs/commands/server-join.html.md.erb +++ b/website/source/docs/commands/server/join.html.md.erb @@ -1,14 +1,14 @@ --- layout: "docs" -page_title: "Commands: server-join" +page_title: "Commands: server join" sidebar_current: "docs-commands-server-join" description: > - Joins the local server to one or more Nomad servers. + The server join command is used to join the local server to one or more Nomad servers. --- -# Command: server-join +# Command: server join -The `server-join` command joins the local server to one or more Nomad servers. +The `server join` command joins the local server to one or more Nomad servers. Joining is only required for server nodes, and only needs to succeed against one or more of the provided addresses. Once joined, the gossip layer will handle discovery of the other server nodes in the cluster. @@ -16,7 +16,7 @@ handle discovery of the other server nodes in the cluster. ## Usage ``` -nomad server-join [options] [...] +nomad server join [options] [...] ``` One or more server addresses are required. If multiple server addresses are @@ -33,6 +33,6 @@ be 1. Join the local server to a remote server: ``` -$ nomad server-join 10.0.0.8:4648 +$ nomad server join 10.0.0.8:4648 Joined 1 servers successfully ``` diff --git a/website/source/docs/commands/server-members.html.md.erb b/website/source/docs/commands/server/members.html.md.erb similarity index 76% rename from website/source/docs/commands/server-members.html.md.erb rename to website/source/docs/commands/server/members.html.md.erb index 1d1811a989c..d2667339f70 100644 --- a/website/source/docs/commands/server-members.html.md.erb +++ b/website/source/docs/commands/server/members.html.md.erb @@ -1,21 +1,21 @@ --- layout: "docs" -page_title: "Commands: server-members" +page_title: "Commands: server members" sidebar_current: "docs-commands-server-members" description: > - Display a list of the known server members and their status. + The server members command is used to display a list of the known server members and their status. --- -# Command: server-members +# Command: server members -The `server-members` command displays a list of the known servers in the cluster +The `server members` command displays a list of the known servers in the cluster and their current status. Member information is provided by the gossip protocol, which is only run on server nodes. ## Usage ``` -nomad server-members [options] +nomad server members [options] ``` ## General Options @@ -33,7 +33,7 @@ nomad server-members [options] Default view: ``` -$ nomad server-members +$ nomad server members Name Addr Port Status Proto Build DC Region node1.global 10.0.0.8 4648 alive 2 0.1.0dev dc1 global node2.global 10.0.0.9 4648 alive 2 0.1.0dev dc1 global @@ -42,7 +42,7 @@ node2.global 10.0.0.9 4648 alive 2 0.1.0dev dc1 global Detailed view: ``` -$ nomad server-members -detailed +$ nomad server members -detailed Name Addr Port Tags node1 10.0.0.8 4648 bootstrap=1,build=0.1.0dev,vsn=1,vsn_max=1,dc=dc1,port=4647,region=global,role=nomad,vsn_min=1 node2 10.0.0.9 4648 bootstrap=0,build=0.1.0dev,vsn=1,vsn_max=1,dc=dc1,port=4647,region=global,role=nomad,vsn_min=1 diff --git a/website/source/docs/job-specification/job.html.md b/website/source/docs/job-specification/job.html.md index 81eeb47117a..e67994572cb 100644 --- a/website/source/docs/job-specification/job.html.md +++ b/website/source/docs/job-specification/job.html.md @@ -212,7 +212,7 @@ job "docs" { When submitting this job, you would run: ``` -$ VAULT_TOKEN="..." nomad run example.nomad +$ VAULT_TOKEN="..." nomad job run example.nomad ``` [constraint]: /docs/job-specification/constraint.html "Nomad constraint Job Specification" diff --git a/website/source/docs/job-specification/logs.html.md b/website/source/docs/job-specification/logs.html.md index 862c6a5e7b5..f2b806f45a2 100644 --- a/website/source/docs/job-specification/logs.html.md +++ b/website/source/docs/job-specification/logs.html.md @@ -47,7 +47,7 @@ job "docs" { ``` For information on how to interact with logs after they have been configured, -please see the [`nomad logs`][logs-command] command. +please see the [`nomad alloc logs`][logs-command] command. ## `logs` Parameters @@ -87,4 +87,4 @@ logs { } ``` -[logs-command]: /docs/commands/logs.html "Nomad logs command" +[logs-command]: /docs/commands/alloc/logs.html "Nomad logs command" diff --git a/website/source/docs/operating-a-job/accessing-logs.html.md b/website/source/docs/operating-a-job/accessing-logs.html.md index 89def7cb8e6..a15301be48d 100644 --- a/website/source/docs/operating-a-job/accessing-logs.html.md +++ b/website/source/docs/operating-a-job/accessing-logs.html.md @@ -4,8 +4,8 @@ page_title: "Accessing Logs - Operating a Job" sidebar_current: "docs-operating-a-job-accessing-logs" description: |- Nomad provides a top-level mechanism for viewing application logs and data - files via the command line interface. This section discusses the nomad logs - command and API interface. + files via the command line interface. This section discusses the nomad alloc + logs command and API interface. --- # Accessing Logs @@ -15,7 +15,7 @@ problems, or even just verifying the application started correctly. To make this as simple as possible, Nomad provides: - Job specification for [log rotation](/docs/job-specification/logs.html) -- CLI command for [log viewing](/docs/commands/logs.html) +- CLI command for [log viewing](/docs/commands/alloc/logs.html) - API for programatic [log access](/api/client.html#stream-logs) This section will utilize the job named "docs" from the [previous @@ -25,7 +25,7 @@ and command largely apply to all jobs in Nomad. As a reminder, here is the output of the run command from the previous example: ```text -$ nomad run docs.nomad +$ nomad job run docs.nomad ==> Monitoring evaluation "42d788a3" Evaluation triggered by job "docs" Allocation "04d9627d" created: node "a1f934c9", group "example" @@ -40,7 +40,7 @@ command) is required to access the application's logs. To access the logs of our application, we issue the following command: ```shell -$ nomad logs 04d9627d +$ nomad alloc logs 04d9627d ``` The output will look something like this: @@ -55,7 +55,7 @@ By default, this will return the logs of the task. If more than one task is defined in the job file, the name of the task is a required argument: ```shell -$ nomad logs 04d9627d server +$ nomad alloc logs 04d9627d server ``` The logs command supports both displaying the logs as well as following logs, @@ -63,7 +63,7 @@ blocking for more output, similar to `tail -f`. To follow the logs, use the appropriately named `-f` flag: ```shell -$ nomad logs -f 04d9627d +$ nomad alloc logs -f 04d9627d ``` This will stream logs to our console. @@ -71,7 +71,7 @@ This will stream logs to our console. If you wish to see only the tail of a log, use the `-tail` and `-n` flags: ```shell -$ nomad logs -tail -n 25 04d9627d +$ nomad alloc logs -tail -n 25 04d9627d ``` This will show the last 25 lines. If you omit the `-n` flag, `-tail` will default to 10 lines. @@ -80,7 +80,7 @@ By default, only the logs on stdout are displayed. To show the log output from stderr, use the `-stderr` flag: ```shell -$ nomad logs -stderr 04d9627d +$ nomad alloc logs -stderr 04d9627d ``` ## Log Shipper Pattern diff --git a/website/source/docs/operating-a-job/inspecting-state.html.md b/website/source/docs/operating-a-job/inspecting-state.html.md index f141b016910..6c20a49732b 100644 --- a/website/source/docs/operating-a-job/inspecting-state.html.md +++ b/website/source/docs/operating-a-job/inspecting-state.html.md @@ -105,14 +105,14 @@ In the above example we see that the job has a "blocked" evaluation that is in progress. When Nomad can not place all the desired allocations, it creates a blocked evaluation that waits for more resources to become available. -The `eval-status` command enables us to examine any evaluation in more detail. +The `eval status` command enables us to examine any evaluation in more detail. For the most part this should never be necessary but can be useful to see why all of a job's allocations were not placed. For example if we run it on the job named docs, which had a placement failure according to the above output, we might see: ```text -$ nomad eval-status 8e38e6cf +$ nomad eval status 8e38e6cf ID = 8e38e6cf Status = complete Status Description = complete @@ -130,17 +130,17 @@ Task Group "example" (failed to place 3 allocations): Evaluation "5744eb15" waiting for additional capacity to place remainder ``` -For more information on the `eval-status` command, please see the [CLI documentation for eval-status](/docs/commands/eval-status.html). +For more information on the `eval status` command, please see the [CLI documentation for eval status](/docs/commands/eval-status.html). ## Allocation Status You can think of an allocation as an instruction to schedule. Just like an -application or service, an allocation has logs and state. The `alloc-status` +application or service, an allocation has logs and state. The `alloc status` command gives us the most recent events that occurred for a task, its resource usage, port allocations and more: ```text -$ nomad alloc-status 04d9627d +$ nomad alloc status 04d9627d ID = 04d9627d Eval ID = 42d788a3 Name = docs.example[2] @@ -159,16 +159,16 @@ Time Type Description 10/09/16 00:36:05 UTC Received Task received by client ``` -The `alloc-status` command is a good starting to point for debugging an +The `alloc status` command is a good starting to point for debugging an application that did not start. Hypothetically assume a user meant to start a Docker container named "redis:2.8", but accidentally put a comma instead of a period, typing "redis:2,8". -When the job is executed, it produces a failed allocation. The `alloc-status` +When the job is executed, it produces a failed allocation. The `alloc status` command will give us the reason why: ```text -$ nomad alloc-status 04d9627d +$ nomad alloc status 04d9627d # ... Recent Events: @@ -178,12 +178,12 @@ Time Type Description 06/28/16 15:50:22 UTC Received Task received by client ``` -Unfortunately not all failures are as easily debuggable. If the `alloc-status` +Unfortunately not all failures are as easily debuggable. If the `alloc status` command shows many restarts, there is likely an application-level issue during start up. For example: ```text -$ nomad alloc-status 04d9627d +$ nomad alloc status 04d9627d # ... Recent Events: @@ -201,5 +201,5 @@ To debug these failures, we will need to utilize the "logs" command, which is discussed in the [accessing logs](/docs/operating-a-job/accessing-logs.html) section of this documentation. -For more information on the `alloc-status` command, please see the [CLI -documentation for alloc-status](/docs/commands/alloc-status.html). +For more information on the `alloc status` command, please see the [CLI +documentation for alloc status](/docs/commands/alloc/status.html). diff --git a/website/source/docs/operating-a-job/resource-utilization.html.md b/website/source/docs/operating-a-job/resource-utilization.html.md index 1e6a8847ca2..4ea77b20a3d 100644 --- a/website/source/docs/operating-a-job/resource-utilization.html.md +++ b/website/source/docs/operating-a-job/resource-utilization.html.md @@ -12,7 +12,7 @@ description: |- Understanding the resource utilization of an application is important, and Nomad supports reporting detailed statistics in many of its drivers. The main -interface for seeing resource utilization is the `alloc-status` command with the +interface for seeing resource utilization is the `alloc status` command with the `-stats` flag. This section will utilize the job named "docs" from the [previous @@ -22,7 +22,7 @@ and command largely apply to all jobs in Nomad. As a reminder, here is the output of the run command from the previous example: ```text -$ nomad run docs.nomad +$ nomad job run docs.nomad ==> Monitoring evaluation "42d788a3" Evaluation triggered by job "docs" Allocation "04d9627d" created: node "a1f934c9", group "example" @@ -35,7 +35,7 @@ $ nomad run docs.nomad To see the detailed usage statistics, we can issue the command: ```shell -$ nomad alloc-status -stats 04d9627d +$ nomad alloc status -stats 04d9627d ID = 04d9627d Eval ID = 42d788a3 Name = docs.example[2] diff --git a/website/source/docs/operating-a-job/submitting-jobs.html.md b/website/source/docs/operating-a-job/submitting-jobs.html.md index c3de6e45374..e1f39416e6f 100644 --- a/website/source/docs/operating-a-job/submitting-jobs.html.md +++ b/website/source/docs/operating-a-job/submitting-jobs.html.md @@ -65,12 +65,12 @@ especially if you are working in a team. ## Planning the Job -Once the job file is authored, we need to plan out the changes. The `nomad plan` +Once the job file is authored, we need to plan out the changes. The `nomad job plan` command invokes a dry-run of the scheduler and inform us of which scheduling decisions would take place. ```text -$ nomad plan docs.nomad +$ nomad job plan docs.nomad + Job: "docs" + Task Group: "example" (1 create) + Task: "server" (forces create) @@ -81,7 +81,7 @@ Scheduler dry-run: Job Modify Index: 0 To submit the job with version verification run: -nomad run -check-index 0 docs.nomad +nomad job run -check-index 0 docs.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has @@ -95,12 +95,12 @@ dry-run and no allocations have taken place. ## Submitting the Job Assuming the output of the plan looks acceptable, we can ask Nomad to execute -this job. This is done via the `nomad run` command. We can optionally supply +this job. This is done via the `nomad job run` command. We can optionally supply the modify index provided to us by the plan command to ensure no changes to this job have taken place between our plan and now. ```text -$ nomad run docs.nomad +$ nomad job run docs.nomad ==> Monitoring evaluation "0d159869" Evaluation triggered by job "docs" Allocation "5cbf23a1" created: node "1e1aa1e0", group "example" @@ -132,7 +132,7 @@ then the run command. For example: After we save these changes to disk, run the plan command: ```text -$ nomad plan docs.nomad +$ nomad job plan docs.nomad +/- Job: "docs" +/- Task Group: "example" (2 create, 1 in-place update) +/- Count: "1" => "3" (forces create) @@ -144,7 +144,7 @@ Scheduler dry-run: Job Modify Index: 131 To submit the job with version verification run: -nomad run -check-index 131 docs.nomad +nomad job run -check-index 131 docs.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has @@ -157,7 +157,7 @@ including the "check-index" parameter. This will ensure that no remote changes have taken place to the job between our plan and run phases. ```text -nomad run -check-index 131 docs.nomad +nomad job run -check-index 131 docs.nomad ==> Monitoring evaluation "42d788a3" Evaluation triggered by job "docs" Allocation "04d9627d" created: node "a1f934c9", group "example" diff --git a/website/source/docs/operating-a-job/update-strategies/blue-green-and-canary-deployments.html.md b/website/source/docs/operating-a-job/update-strategies/blue-green-and-canary-deployments.html.md index 015975d074e..725e378f1d5 100644 --- a/website/source/docs/operating-a-job/update-strategies/blue-green-and-canary-deployments.html.md +++ b/website/source/docs/operating-a-job/update-strategies/blue-green-and-canary-deployments.html.md @@ -76,7 +76,7 @@ can see how this works by changing the image to run the new version: Next we plan and run these changes: ```text -$ nomad plan docs.nomad +$ nomad job plan docs.nomad +/- Job: "docs" +/- Task Group: "api" (5 canary, 5 ignore) +/- Task: "api-server" (forces create/destroy update) @@ -90,14 +90,14 @@ Scheduler dry-run: Job Modify Index: 7 To submit the job with version verification run: -nomad run -check-index 7 example.nomad +nomad job run -check-index 7 example.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has changed, another user has modified the job and the plan's results are potentially invalid. -$ nomad run docs.nomad +$ nomad job run docs.nomad # ... ``` @@ -334,7 +334,7 @@ changing the image to run the new version: Next we plan and run these changes: ```text -$ nomad plan docs.nomad +$ nomad job plan docs.nomad +/- Job: "docs" +/- Task Group: "api" (1 canary, 5 ignore) +/- Task: "api-server" (forces create/destroy update) @@ -348,14 +348,14 @@ Scheduler dry-run: Job Modify Index: 7 To submit the job with version verification run: -nomad run -check-index 7 example.nomad +nomad job run -check-index 7 example.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has changed, another user has modified the job and the plan's results are potentially invalid. -$ nomad run docs.nomad +$ nomad job run docs.nomad # ... ``` diff --git a/website/source/docs/operating-a-job/update-strategies/rolling-upgrades.html.md b/website/source/docs/operating-a-job/update-strategies/rolling-upgrades.html.md index 1619b7f3861..1d1751dcb43 100644 --- a/website/source/docs/operating-a-job/update-strategies/rolling-upgrades.html.md +++ b/website/source/docs/operating-a-job/update-strategies/rolling-upgrades.html.md @@ -86,12 +86,12 @@ that is configured with the same rolling update strategy from above. + image = "geo-api-server:0.2" ``` -The [`nomad plan` command](/docs/commands/plan.html) allows +The [`nomad job plan` command](/docs/commands/job/plan.html) allows us to visualize the series of steps the scheduler would perform. We can analyze this output to confirm it is correct: ```text -$ nomad plan geo-api-server.nomad +$ nomad job plan geo-api-server.nomad +/- Job: "geo-api-server" +/- Task Group: "api-server" (2 create/destroy update, 4 ignore) +/- Task: "server" (forces create/destroy update) @@ -105,7 +105,7 @@ Scheduler dry-run: Job Modify Index: 7 To submit the job with version verification run: -nomad run -check-index 7 my-web.nomad +nomad job run -check-index 7 my-web.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has diff --git a/website/source/docs/runtime/environment.html.md.erb b/website/source/docs/runtime/environment.html.md.erb index a7c3e743fa3..f92f27ba0e6 100644 --- a/website/source/docs/runtime/environment.html.md.erb +++ b/website/source/docs/runtime/environment.html.md.erb @@ -68,7 +68,7 @@ Nomad makes the following directories available to tasks: * `local/`: This directory is private to each task. It can be used to store arbitrary data that should not be shared by tasks in the task group. * `secrets/`: This directory is private to each task, not accessible via the - `nomad fs` command or filesystem APIs and where possible backed by an + `nomad alloc fs` command or filesystem APIs and where possible backed by an in-memory filesystem. It can be used to store secret data that should not be visible outside the task. diff --git a/website/source/docs/upgrade/index.html.md b/website/source/docs/upgrade/index.html.md index 5f816af0c56..d45c8aee1c8 100644 --- a/website/source/docs/upgrade/index.html.md +++ b/website/source/docs/upgrade/index.html.md @@ -75,7 +75,7 @@ raft Continue with the upgrades across the Server fleet making sure to do a single Nomad server at a time. You can check state of the servers and clients with the -`nomad server-members` and `nomad node-status` commands which indicate state of the +`nomad server members` and `nomad node status` commands which indicate state of the nodes. ### 3. Remove the old versions from servers @@ -87,9 +87,9 @@ If you are doing an upgrade by adding new servers and removing old servers from the fleet you need to ensure that the server has left the fleet safely. 1. Stop the service on the existing host -2. On another server issue a `nomad server-members` and check the status, if +2. On another server issue a `nomad server members` and check the status, if the server is now in a left state you are safe to continue. -3. If the server is not in a left state, issue a `nomad server-force-leave ` +3. If the server is not in a left state, issue a `nomad server force-leave ` to remove the server from the cluster. Monitor the logs of the other hosts in the Nomad cluster over this period. @@ -102,15 +102,15 @@ Use the same actions in step #2 above to confirm cluster health. Following the successful upgrade of the servers you can now update your clients using a similar process as the servers. If you wish to gracefully -move tasks on a client use the `nomad node-drain ` command to -gracefully migrate jobs to another client in the cluster. The `node-drain` +move tasks on a client use the `nomad node drain ` command to +gracefully migrate jobs to another client in the cluster. The `node drain` command prevents new tasks from being allocated to the client and begins migrating existing allocations to another client. ## Done! You are now running the latest Nomad version. You can verify all -Clients joined by running `nomad node-status` and checking all the clients +Clients joined by running `nomad node status` and checking all the clients are in a `ready` state. ## Upgrading to Nomad Enterprise diff --git a/website/source/docs/upgrade/upgrade-specific.html.md b/website/source/docs/upgrade/upgrade-specific.html.md index 57386c63a24..d70efa4603c 100644 --- a/website/source/docs/upgrade/upgrade-specific.html.md +++ b/website/source/docs/upgrade/upgrade-specific.html.md @@ -156,6 +156,6 @@ be resubmitted with the updated job syntax using a Nomad 0.3.0 binary. After updating the Servers and job files, Nomad Clients can be upgraded by first draining the node so no tasks are running on it. This can be verified by running -`nomad node-status ` and verify there are no tasks in the `running` +`nomad node status ` and verify there are no tasks in the `running` state. Once that is done the client can be killed, the `data_dir` should be deleted and then Nomad 0.3.0 can be launched. diff --git a/website/source/guides/cluster/autopilot.html.md b/website/source/guides/cluster/autopilot.html.md index 15f65073243..9e94365986e 100644 --- a/website/source/guides/cluster/autopilot.html.md +++ b/website/source/guides/cluster/autopilot.html.md @@ -203,7 +203,7 @@ To check the Nomad version of the servers, either the [autopilot health] command can be used: ``` -$ nomad server-members +$ nomad server members Name Address Port Status Leader Protocol Build Datacenter Region node1 127.0.0.1 4648 alive true 3 0.7.1 dc1 global node2 127.0.0.1 4748 alive false 3 0.7.1 dc1 global diff --git a/website/source/guides/cluster/manual.html.md b/website/source/guides/cluster/manual.html.md index b1138d80ac9..e54504beda1 100644 --- a/website/source/guides/cluster/manual.html.md +++ b/website/source/guides/cluster/manual.html.md @@ -3,7 +3,7 @@ layout: "guides" page_title: "Manually Bootstrapping a Nomad Cluster" sidebar_current: "guides-cluster-manual" description: |- - Learn how to manually bootstrap a Nomad cluster using the server-join + Learn how to manually bootstrap a Nomad cluster using the server join command. This section also discusses Nomad federation across multiple datacenters and regions. --- @@ -36,12 +36,12 @@ server { ``` Alternatively, the address can be supplied after the servers have all been -started by running the [`server-join` command](/docs/commands/server-join.html) +started by running the [`server join` command](/docs/commands/server/join.html) on the servers individually to cluster the servers. All servers can join just one other server, and then rely on the gossip protocol to discover the rest. ``` -$ nomad server-join +$ nomad server join ``` For Nomad clients, the configuration may look something like: @@ -53,8 +53,12 @@ client { } ``` -At this time, there is no equivalent of the server-join command for -Nomad clients. +The client node's server list can be updated at run time using the [`node +config` command](/docs/commands/node/config.html). + +``` +$ nomad node config -update-servers :4647 +``` The port corresponds to the RPC port. If no port is specified with the IP address, the default RPC port of `4647` is assumed. diff --git a/website/source/guides/outage.html.markdown b/website/source/guides/outage.html.markdown index c6b697cc36d..4f936dd3b1f 100644 --- a/website/source/guides/outage.html.markdown +++ b/website/source/guides/outage.html.markdown @@ -48,10 +48,10 @@ to a fully healthy state. Both of these strategies involve a potentially lengthy time to reboot or rebuild a failed server. If this is impractical or if building a new server with the same IP isn't an option, you need to remove the failed server. Usually, you can issue -a [`nomad server-force-leave`](/docs/commands/server-force-leave.html) command +a [`nomad server force-leave`](/docs/commands/server/force-leave.html) command to remove the failed server if it's still a member of the cluster. -If [`nomad server-force-leave`](/docs/commands/server-force-leave.html) isn't +If [`nomad server force-leave`](/docs/commands/server/force-leave.html) isn't able to remove the server, you have two methods available to remove it, depending on your version of Nomad: @@ -92,7 +92,7 @@ once the remaining servers are all restarted with an identical `raft/peers.json` configuration. Any new servers you introduce later can be fresh with totally clean data directories -and joined using Nomad's `server-join` command. +and joined using Nomad's `server join` command. In extreme cases, it should be possible to recover with just a single remaining server by starting that single server with itself as the only peer in the @@ -158,10 +158,10 @@ later you will see them ingest recovery file: ``` If any servers managed to perform a graceful leave, you may need to have them -rejoin the cluster using the [`server-join`](/docs/commands/server-join.html) command: +rejoin the cluster using the [`server join`](/docs/commands/server/join.html) command: ```text -$ nomad server-join +$ nomad server join Successfully joined cluster by contacting 1 nodes. ``` diff --git a/website/source/guides/quotas.html.md b/website/source/guides/quotas.html.md index 10631ea2700..c6397b34ee6 100644 --- a/website/source/guides/quotas.html.md +++ b/website/source/guides/quotas.html.md @@ -105,10 +105,10 @@ Successfully applied namespace "default"! Lets now run a job in the default namespace now that we have attached a quota: ``` -$ nomad init +$ nomad job init Example job file written to example.nomad -$ nomad run -detach example.nomad +$ nomad job run -detach example.nomad Job registration successful Evaluation ID: 985a1df8-0221-b891-5dc1-4d31ad4e2dc3 @@ -128,7 +128,7 @@ scale up the job from `count = 1` to `count = 4`: ``` # Change count -$ nomad run -detach example.nomad +$ nomad job run -detach example.nomad Job registration successful Evaluation ID: ce8e1941-0189-b866-3dc4-7cd92dc38a69 diff --git a/website/source/guides/securing-nomad.html.md b/website/source/guides/securing-nomad.html.md index e3a379405fc..8c9c5d884b0 100644 --- a/website/source/guides/securing-nomad.html.md +++ b/website/source/guides/securing-nomad.html.md @@ -288,7 +288,7 @@ $ # ...and in another $ nomad agent -config client1.hcl ``` -If you run `nomad node-status` now, you'll get an error, like: +If you run `nomad node status` now, you'll get an error, like: ```text Error querying node status: Get http://127.0.0.1:4646/v1/nodes: malformed HTTP response "\x15\x03\x01\x00\x02\x02" @@ -299,7 +299,7 @@ HTTPS. We can configure the local Nomad client to connect using TLS and specify our custom keys and certificates using the command line: ```shell -$ nomad node-status -ca-cert=nomad-ca.pem -client-cert=cli.pem -client-key=cli-key.pem -address=https://127.0.0.1:4646 +$ nomad node status -ca-cert=nomad-ca.pem -client-cert=cli.pem -client-key=cli-key.pem -address=https://127.0.0.1:4646 ``` This process can be cumbersome to type each time, so the Nomad CLI also @@ -325,13 +325,13 @@ After these environment variables are correctly configured, the CLI will respond as expected: ```text -$ nomad node-status +$ nomad node status ID DC Name Class Drain Status 237cd4c5 dc1 nomad false ready -$ nomad init +$ nomad job init Example job file written to example.nomad -vagrant@nomad:~$ nomad run example.nomad +vagrant@nomad:~$ nomad job run example.nomad ==> Monitoring evaluation "e9970e1d" Evaluation triggered by job "example" Allocation "a1f6c3e7" created: node "237cd4c5", group "cache" @@ -355,11 +355,11 @@ This encryption key must be added to every server's configuration using the [`encrypt`](/docs/agent/configuration/server.html#encrypt) parameter or with the [`-encrypt` command line option](/docs/commands/agent.html). -The Nomad CLI includes a `keygen` command for generating a new secure gossip +The Nomad CLI includes a `operator keygen` command for generating a new secure gossip encryption key: ```text -$ nomad keygen +$ nomad operator keygen cg8StVXbQJ0gPvMd9o7yrg== ``` diff --git a/website/source/guides/sentinel-policy.html.markdown b/website/source/guides/sentinel-policy.html.markdown index 17bbef1d3b8..ee7ff3e2f70 100644 --- a/website/source/guides/sentinel-policy.html.markdown +++ b/website/source/guides/sentinel-policy.html.markdown @@ -88,13 +88,13 @@ $ nomad sentinel apply -level=advisory test-policy test.sentinel Successfully wrote "test-policy" Sentinel policy! ``` -Use `nomad init` to create a job file and attempt to submit it: +Use `nomad job init` to create a job file and attempt to submit it: ``` -$ nomad init +$ nomad job init Example job file written to example.nomad -$ nomad run example.nomad +$ nomad job run example.nomad Job Warnings: 1 warning(s): @@ -161,7 +161,7 @@ Because our policy is failing, the job was rejected. Since this is a `soft-manda submit with the `-policy-override` flag set: ``` -$ nomad run -policy-override example.nomad +$ nomad job run -policy-override example.nomad Job Warnings: 1 warning(s): diff --git a/website/source/guides/spark/customizing.html.md b/website/source/guides/spark/customizing.html.md index bb7f09f9e8c..138284f3124 100644 --- a/website/source/guides/spark/customizing.html.md +++ b/website/source/guides/spark/customizing.html.md @@ -66,7 +66,7 @@ An alternative to using the default template is to set the containing a custom job template. There are two important considerations: * The template must use the JSON format. You can convert an HCL jobspec to - JSON by running `nomad run -output `. + JSON by running `nomad job run -output `. * `spark.nomad.job.template` should be set to a path on the submitting machine, not to a URL (even in cluster mode). The template does not need to diff --git a/website/source/guides/spark/hdfs.html.md b/website/source/guides/spark/hdfs.html.md index b9459c59a7f..d7d95013b64 100644 --- a/website/source/guides/spark/hdfs.html.md +++ b/website/source/guides/spark/hdfs.html.md @@ -121,10 +121,10 @@ Another viable option for DataNode task group is to use a dedicated This will deploy a DataNode to every client node in the system, which may or may not be desirable depending on your use case. -The HDFS job can be deployed using the `nomad run` command: +The HDFS job can be deployed using the `nomad job run` command: ```shell -$ nomad run hdfs.nomad +$ nomad job run hdfs.nomad ``` ## Production Deployment Considerations diff --git a/website/source/guides/spark/monitoring.html.md b/website/source/guides/spark/monitoring.html.md index 0b4ddce42a8..ac2f512ce6d 100644 --- a/website/source/guides/spark/monitoring.html.md +++ b/website/source/guides/spark/monitoring.html.md @@ -95,7 +95,7 @@ $ hdfs dfs -fs hdfs://hdfs.service.consul:8020 -mkdir /spark-events You can then deploy the history server with: ```shell -$ nomad run spark-history-server-hdfs.nomad +$ nomad job run spark-history-server-hdfs.nomad ``` You can get the private IP for the history server with a Consul DNS lookup: diff --git a/website/source/index.html.erb b/website/source/index.html.erb index f957ecc3573..0f04a0273ae 100644 --- a/website/source/index.html.erb +++ b/website/source/index.html.erb @@ -319,13 +319,13 @@ description: |-   admin@hashicorp.com: - nomad validate example.nomad + nomad job validate example.nomad Job validation successful   admin@hashicorp.com: - nomad run example.nomad + nomad job run example.nomad ==> Monitoring evaluation "feb23392" Evaluation triggered by job "example" @@ -364,7 +364,7 @@ description: |-
admin@hashicorp.com: - nomad plan example.nomad + nomad job plan example.nomad +/- Job: "example" +/- Task Group: "cache" (2 create, 1 in-place update) @@ -378,7 +378,7 @@ description: |-   admin@hashicorp.com: - nomad run -check-index 7 example.nomad + nomad job run -check-index 7 example.nomad ==> Monitoring evaluation "e338a6ae" Evaluation triggered by job "example" @@ -412,7 +412,7 @@ description: |-
admin@hashicorp.com: - nomad logs -tail -job example + nomad alloc logs -tail -job example <%= Time.now.strftime("%d %b %H:%M:%S") %> # Server started, Redis version 3.2.9 <%= Time.now.strftime("%d %b %H:%M:%S") %> * The server is now ready to accept connections on port 6379 diff --git a/website/source/intro/getting-started/cluster.html.md b/website/source/intro/getting-started/cluster.html.md index b85d102e1be..5e3a76abd96 100644 --- a/website/source/intro/getting-started/cluster.html.md +++ b/website/source/intro/getting-started/cluster.html.md @@ -135,11 +135,11 @@ In the output we can see the agent is running in client mode only. This agent will be available to run tasks but will not participate in managing the cluster or making scheduling decisions. -Using the [`node-status` command](/docs/commands/node-status.html) +Using the [`node status` command](/docs/commands/node/status.html) we should see both nodes in the `ready` state: ```text -$ nomad node-status +$ nomad node status ID Datacenter Name Class Drain Status fca62612 dc1 nomad false ready c887deef dc1 nomad false ready @@ -155,10 +155,10 @@ Now that we have a simple cluster, we can use it to schedule a job. We should still have the `example.nomad` job file from before, but verify that the `count` is still set to 3. -Then, use the [`run` command](/docs/commands/run.html) to submit the job: +Then, use the [`job run` command](/docs/commands/job/run.html) to submit the job: ```text -$ nomad run example.nomad +$ nomad job run example.nomad ==> Monitoring evaluation "8e0a7cf9" Evaluation triggered by job "example" Evaluation within deployment: "0917b771" @@ -209,7 +209,7 @@ ID Eval ID Node ID Task Group Desired Status Created At We can see that all our tasks have been allocated and are running. Once we are satisfied that our job is happily running, we can tear -it down with `nomad stop`. +it down with `nomad job stop`. ## Next Steps diff --git a/website/source/intro/getting-started/install.html.md b/website/source/intro/getting-started/install.html.md index d91be7839c6..1d5ddc131c8 100644 --- a/website/source/intro/getting-started/install.html.md +++ b/website/source/intro/getting-started/install.html.md @@ -49,40 +49,29 @@ $ vagrant ssh ... vagrant@nomad:~$ nomad - -Usage: nomad [-version] [-help] [-autocomplete-(un)install] [] - -Available commands are: - acl Interact with ACL policies and tokens - agent Runs a Nomad agent - agent-info Display status information about the local agent - alloc-status Display allocation status information and metadata - client-config View or modify client configuration details - deployment Interact with deployments - eval-status Display evaluation status and placement failure reasons - fs Inspect the contents of an allocation directory - init Create an example job file - inspect Inspect a submitted job - job Interact with jobs - keygen Generates a new encryption key - keyring Manages gossip layer encryption keys - logs Streams the logs of a task. - namespace Interact with namespaces - node-drain Toggle drain mode on a given node - node-status Display status information about nodes - operator Provides cluster-level tools for Nomad operators - plan Dry-run a job update to determine its effects - quota Interact with quotas - run Run a new job or update an existing job - sentinel Interact with Sentinel policies - server-force-leave Force a server into the 'left' state - server-join Join server nodes together - server-members Display a list of known servers and their status - status Display the status output for a resource - stop Stop a running job - ui Open the Nomad Web UI - validate Checks if a given job specification is valid - version Prints the Nomad version +Usage: nomad [-version] [-help] [-autocomplete-(un)install] [args] + +Common commands: + run Run a new job or update an existing job + stop Stop a running job + status Display the status output for a resource + alloc Interact with allocations + job Interact with jobs + node Interact with nodes + agent Runs a Nomad agent + +Other commands: + acl Interact with ACL policies and tokens + agent-info Display status information about the local agent + deployment Interact with deployments + eval Interact with evaluations + namespace Interact with namespaces + operator Provides cluster-level tools for Nomad operators + quota Interact with quotas + sentinel Interact with Sentinel policies + server Interact with servers + ui Open the Nomad Web UI + version Prints the Nomad version ``` If you get an error that Nomad could not be found, then your Vagrant box diff --git a/website/source/intro/getting-started/jobs.html.md b/website/source/intro/getting-started/jobs.html.md index c64092bfbb7..2572c6a97fa 100644 --- a/website/source/intro/getting-started/jobs.html.md +++ b/website/source/intro/getting-started/jobs.html.md @@ -19,25 +19,25 @@ however we recommend only using JSON when the configuration is generated by a ma ## Running a Job -To get started, we will use the [`init` command](/docs/commands/init.html) which +To get started, we will use the [`job init` command](/docs/commands/job/init.html) which generates a skeleton job file: ```text -$ nomad init +$ nomad job init Example job file written to example.nomad ``` You can view the contents of this file by running `cat example.nomad`. In this example job file, we have declared a single task 'redis' which is using the Docker driver to run the task. The primary way you interact with Nomad -is with the [`run` command](/docs/commands/run.html). The `run` command takes +is with the [`job run` command](/docs/commands/job/run.html). The `run` command takes a job file and registers it with Nomad. This is used both to register new jobs and to update existing jobs. We can register our example job now: ```text -$ nomad run example.nomad +$ nomad job run example.nomad ==> Monitoring evaluation "13ebb66d" Evaluation triggered by job "example" Allocation "883269bf" created: node "e42d6f19", group "cache" @@ -87,10 +87,10 @@ Here we can see that the result of our evaluation was the creation of an allocation that is now running on the local node. An allocation represents an instance of Task Group placed on a node. To inspect -an allocation we use the [`alloc-status` command](/docs/commands/alloc-status.html): +an allocation we use the [`alloc status` command](/docs/commands/alloc/status.html): ```text -$ nomad alloc-status 883269bf +$ nomad alloc status 883269bf ID = 883269bf Eval ID = 13ebb66d Name = example.cache[0] @@ -129,10 +129,10 @@ We can see that Nomad reports the state of the allocation as well as its current resource usage. By supplying the `-stats` flag, more detailed resource usage statistics will be reported. -To see the logs of a task, we can use the [logs command](/docs/commands/logs.html): +To see the logs of a task, we can use the [logs command](/docs/commands/alloc/logs.html): ```text -$ nomad logs 883269bf redis +$ nomad alloc logs 883269bf redis _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.2.1 (00000000/0) 64 bit @@ -168,12 +168,12 @@ For now, edit the `example.nomad` file to update the count and set it to 3: count = 3 ``` -Once you have finished modifying the job specification, use the [`plan` -command](/docs/commands/plan.html) to invoke a dry-run of the scheduler to see +Once you have finished modifying the job specification, use the [`job plan` +command](/docs/commands/job/plan.html) to invoke a dry-run of the scheduler to see what would happen if you ran the updated job: ```text -$ nomad plan example.nomad +$ nomad job plan example.nomad +/- Job: "example" +/- Task Group: "cache" (2 create, 1 in-place update) +/- Count: "1" => "3" (forces create) @@ -185,7 +185,7 @@ Scheduler dry-run: Job Modify Index: 7 To submit the job with version verification run: -nomad run -check-index 7 example.nomad +nomad job run -check-index 7 example.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has @@ -205,7 +205,7 @@ interacting with the job at the same time to ensure the job hasn't changed before you apply your modifications. ``` -$ nomad run -check-index 7 example.nomad +$ nomad job run -check-index 7 example.nomad ==> Monitoring evaluation "93d16471" Evaluation triggered by job "example" Evaluation within deployment: "0d06e1b6" @@ -248,7 +248,7 @@ Scheduler dry-run: Job Modify Index: 1127 To submit the job with version verification run: -nomad run -check-index 1127 example.nomad +nomad job run -check-index 1127 example.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has @@ -264,7 +264,7 @@ a time. Once ready, use `run` to push the updated specification: ```text -$ nomad run example.nomad +$ nomad job run example.nomad ==> Monitoring evaluation "293b313a" Evaluation triggered by job "example" Evaluation within deployment: "f4047b3a" @@ -285,10 +285,10 @@ scale. ## Stopping a Job So far we've created, run and modified a job. The final step in a job lifecycle -is stopping the job. This is done with the [`stop` command](/docs/commands/stop.html): +is stopping the job. This is done with the [`job stop` command](/docs/commands/job/stop.html): ```text -$ nomad stop example +$ nomad job stop example ==> Monitoring evaluation "6d4cd6ca" Evaluation triggered by job "example" Evaluation within deployment: "f4047b3a" diff --git a/website/source/intro/getting-started/running.html.md b/website/source/intro/getting-started/running.html.md index b495460f3b0..49e498fcc98 100644 --- a/website/source/intro/getting-started/running.html.md +++ b/website/source/intro/getting-started/running.html.md @@ -74,14 +74,14 @@ certain task drivers will not be available. ## Cluster Nodes -If you run [`nomad node-status`](/docs/commands/node-status.html) in another terminal, you -can see the registered nodes of the Nomad cluster: +If you run [`nomad node status`](/docs/commands/node/status.html) in another +terminal, you can see the registered nodes of the Nomad cluster: ```text $ vagrant ssh ... -$ nomad node-status +$ nomad node status ID Datacenter Name Class Drain Status 171a583b dc1 nomad false ready ``` @@ -94,10 +94,10 @@ currently off. The agent is also running in server mode, which means it is part of the [gossip protocol](/docs/internals/gossip.html) used to connect all the server instances together. We can view the members of the gossip -ring using the [`server-members`](/docs/commands/server-members.html) command: +ring using the [`server members`](/docs/commands/server/members.html) command: ```text -$ nomad server-members +$ nomad server members Name Address Port Status Leader Protocol Build Datacenter Region nomad.global 127.0.0.1 4648 alive true 2 0.7.0 dc1 global ``` @@ -138,7 +138,7 @@ If an agent is operating as a server, a graceful leave is important to avoid causing a potential availability outage affecting the [consensus protocol](/docs/internals/consensus.html). If a server does forcefully exit and will not be returning into service, the -[`server-force-leave` command](/docs/commands/server-force-leave.html) should +[`server force-leave` command](/docs/commands/server/force-leave.html) should be used to force the server from a _failed_ to a _left_ state. ## Next Steps diff --git a/website/source/intro/getting-started/ui.html.md b/website/source/intro/getting-started/ui.html.md index 41f733fcb85..f4a220fe298 100644 --- a/website/source/intro/getting-started/ui.html.md +++ b/website/source/intro/getting-started/ui.html.md @@ -48,7 +48,7 @@ for the task group. [![Nomad UI Task Group Detail][img-task-group-detail]][img-task-group-detail] Click on the allocation in the allocations table. This page lists all tasks for an allocation as well -as the recent events for each task. It is similar to the `nomad alloc-status` command. +as the recent events for each task. It is similar to the `nomad alloc status` command. [![Nomad UI Alloc Status][img-alloc-status]][img-alloc-status] diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index 585082d42ca..87b0cd50b72 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -177,34 +177,34 @@ acl @@ -214,104 +214,120 @@ > agent-info - > - alloc-status - - > - client-config + > + alloc + > deployment > - eval-status - - > - fs - - > - init - - > - inspect + eval status > job - > - keygen - - > - keyring - - > - logs - > namespace - > - node-drain - - > - node-status + > + node + > operator @@ -322,6 +338,12 @@ > autopilot set-config + > + keygen + + > + keyring + > raft list-peers @@ -330,73 +352,66 @@ - > - plan - > quota - > - run - > sentinel - > - server-force-leave - - > - server-join - - > - server-members + > + server + > status - > - stop - > ui - > - validate - > version