diff --git a/command/alloc.go b/command/alloc.go new file mode 100644 index 000000000..f2729a42f --- /dev/null +++ b/command/alloc.go @@ -0,0 +1,19 @@ +package command + +import "github.com/mitchellh/cli" + +type AllocCommand struct { + Meta +} + +func (f *AllocCommand) Help() string { + return "This command is accessed by using one of the subcommands below." +} + +func (f *AllocCommand) Synopsis() string { + return "Interact with allocations" +} + +func (f *AllocCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/alloc_status.go b/command/alloc_status.go index 7abaffcbc..7ce4c9e41 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/client_config.go b/command/client_config.go index 541b2735f..cf88db8bb 100644 --- a/command/client_config.go +++ b/command/client_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/client_config_test.go index cb9275ca0..8ddf3f44f 100644 --- a/command/client_config_test.go +++ b/command/client_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/eval.go b/command/eval.go new file mode 100644 index 000000000..70959d181 --- /dev/null +++ b/command/eval.go @@ -0,0 +1,19 @@ +package command + +import "github.com/mitchellh/cli" + +type EvalCommand struct { + Meta +} + +func (f *EvalCommand) Help() string { + return "This command is accessed by using one of the subcommands below." +} + +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 0b7dcd0d3..04010fb81 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/fs.go b/command/fs.go index e875c6483..85fbf8872 100644 --- a/command/fs.go +++ b/command/fs.go @@ -27,13 +27,13 @@ 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] 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 +75,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 +93,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 +108,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 +333,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/fs_test.go index 342eeb2a3..0e15b5034 100644 --- a/command/fs_test.go +++ b/command/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/init.go b/command/init.go index 3b6ca2dd0..6acd342b9 100644 --- a/command/init.go +++ b/command/init.go @@ -13,15 +13,15 @@ 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 Creates an example job file that can be used as a starting point to customize further. @@ -29,11 +29,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/init_test.go index 4c0da57cb..dba661806 100644 --- a/command/init_test.go +++ b/command/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/inspect.go index b16527b59..52efd5457 100644 --- a/command/inspect.go +++ b/command/inspect.go @@ -9,13 +9,13 @@ 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] Inspect is used to see the specification of a submitted job. @@ -37,11 +37,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 +50,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 +65,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/inspect_test.go index 1eb51ff88..43e6bb0a4 100644 --- a/command/inspect_test.go +++ b/command/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/keygen.go b/command/keygen.go index 64a47e6bb..621e915d8 100644 --- a/command/keygen.go +++ b/command/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/keygen_test.go index a9b3dec6d..aef615692 100644 --- a/command/keygen_test.go +++ b/command/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/keyring.go index 6e4ee28fc..a74285870 100644 --- a/command/keyring.go +++ b/command/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/logs.go b/command/logs.go index e0d53c65c..7ca23dce9 100644 --- a/command/logs.go +++ b/command/logs.go @@ -14,13 +14,13 @@ 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] Streams the stdout/stderr of the given allocation and task. @@ -57,11 +57,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 +74,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 +89,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 +262,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/logs_test.go index c56628320..868a9cb91 100644 --- a/command/logs_test.go +++ b/command/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/plan.go b/command/plan.go index c891e17aa..ac1f63b77 100644 --- a/command/plan.go +++ b/command/plan.go @@ -22,14 +22,14 @@ 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] 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 +75,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 +88,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/plan_test.go index 97b42476e..c9360de6d 100644 --- a/command/plan_test.go +++ b/command/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/run.go index e4d691239..33d9f266f 100644 --- a/command/run.go +++ b/command/run.go @@ -19,14 +19,14 @@ 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] Starts running a new job or updates an existing job using the specification located at . This is the main command @@ -93,11 +93,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 +109,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/run_test.go index c42b3da43..1db113ddf 100644 --- a/command/run_test.go +++ b/command/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/server.go b/command/server.go new file mode 100644 index 000000000..7735fcc87 --- /dev/null +++ b/command/server.go @@ -0,0 +1,19 @@ +package command + +import "github.com/mitchellh/cli" + +type ServerCommand struct { + Meta +} + +func (f *ServerCommand) Help() string { + return "This command is accessed by using one of the subcommands below." +} + +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 666be7060..dde9e949b 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 9b9bacc53..86208eaa5 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 55a31d268..61e97173c 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/command/stop.go b/command/stop.go index 258679fec..cd86abb4f 100644 --- a/command/stop.go +++ b/command/stop.go @@ -8,13 +8,13 @@ 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] Stop an existing job. This command is used to signal allocations to shut down for the given job ID. Upon successful deregistration, @@ -47,11 +47,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 +61,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 +76,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/stop_test.go index 2390839fa..1389f537c 100644 --- a/command/stop_test.go +++ b/command/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/validate.go index 1dff70da9..ace9aa2dd 100644 --- a/command/validate.go +++ b/command/validate.go @@ -11,14 +11,14 @@ 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] 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 +30,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 +110,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/validate_test.go index 20902068e..516d31750 100644 --- a/command/validate_test.go +++ b/command/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/commands.go b/commands.go index 0b3a422f0..02abb39a4 100644 --- a/commands.go +++ b/commands.go @@ -91,6 +91,26 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, + "alloc": func() (cli.Command, error) { + return &command.AllocCommand{ + Meta: meta, + }, nil + }, + "alloc fs": func() (cli.Command, error) { + return &command.AllocFSCommand{ + Meta: meta, + }, nil + }, + "alloc logs": func() (cli.Command, error) { + return &command.AllocLogsCommand{ + Meta: meta, + }, nil + }, + "alloc status": func() (cli.Command, error) { + return &command.AllocStatusCommand{ + Meta: meta, + }, nil + }, "alloc-status": func() (cli.Command, error) { return &command.AllocStatusCommand{ Meta: meta, @@ -114,7 +134,7 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { }, nil }, "client-config": func() (cli.Command, error) { - return &command.ClientConfigCommand{ + return &command.NodeConfigCommand{ Meta: meta, }, nil }, @@ -153,6 +173,16 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, + "eval": func() (cli.Command, error) { + return &command.EvalCommand{ + Meta: meta, + }, nil + }, + "eval status": func() (cli.Command, error) { + return &command.EvalStatusCommand{ + Meta: meta, + }, nil + }, "eval-status": func() (cli.Command, error) { return &command.EvalStatusCommand{ Meta: meta, @@ -164,27 +194,27 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { }, nil }, "fs": func() (cli.Command, error) { - return &command.FSCommand{ + return &command.AllocFSCommand{ Meta: meta, }, nil }, "init": func() (cli.Command, error) { - return &command.InitCommand{ + return &command.JobInitCommand{ Meta: meta, }, nil }, "inspect": func() (cli.Command, error) { - return &command.InspectCommand{ + return &command.JobInspectCommand{ Meta: meta, }, nil }, "keygen": func() (cli.Command, error) { - return &command.KeygenCommand{ + return &command.OperatorKeygenCommand{ Meta: meta, }, nil }, "keyring": func() (cli.Command, error) { - return &command.KeyringCommand{ + return &command.OperatorKeyringCommand{ Meta: meta, }, nil }, @@ -208,6 +238,21 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, + "job init": func() (cli.Command, error) { + return &command.JobInitCommand{ + Meta: meta, + }, nil + }, + "job inspect": func() (cli.Command, error) { + return &command.JobInspectCommand{ + Meta: meta, + }, nil + }, + "job plan": func() (cli.Command, error) { + return &command.JobPlanCommand{ + Meta: meta, + }, nil + }, "job promote": func() (cli.Command, error) { return &command.JobPromoteCommand{ Meta: meta, @@ -218,13 +263,28 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, + "job run": func() (cli.Command, error) { + return &command.JobRunCommand{ + Meta: meta, + }, nil + }, "job status": func() (cli.Command, error) { return &command.JobStatusCommand{ Meta: meta, }, nil }, + "job stop": func() (cli.Command, error) { + return &command.JobStopCommand{ + Meta: meta, + }, nil + }, + "job validate": func() (cli.Command, error) { + return &command.JobValidateCommand{ + Meta: meta, + }, nil + }, "logs": func() (cli.Command, error) { - return &command.LogsCommand{ + return &command.AllocLogsCommand{ Meta: meta, }, nil }, @@ -263,6 +323,11 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, + "node config": func() (cli.Command, error) { + return &command.NodeConfigCommand{ + Meta: meta, + }, nil + }, "node-drain": func() (cli.Command, error) { return &command.NodeDrainCommand{ Meta: meta, @@ -311,7 +376,16 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, - + "operator keygen": func() (cli.Command, error) { + return &command.OperatorKeygenCommand{ + Meta: meta, + }, nil + }, + "operator keyring": func() (cli.Command, error) { + return &command.OperatorKeyringCommand{ + Meta: meta, + }, nil + }, "operator raft": func() (cli.Command, error) { return &command.OperatorRaftCommand{ Meta: meta, @@ -331,7 +405,7 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { }, "plan": func() (cli.Command, error) { - return &command.PlanCommand{ + return &command.JobPlanCommand{ Meta: meta, }, nil }, @@ -379,7 +453,7 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { }, "run": func() (cli.Command, error) { - return &command.RunCommand{ + return &command.JobRunCommand{ Meta: meta, }, nil }, @@ -408,6 +482,26 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { Meta: meta, }, nil }, + "server": func() (cli.Command, error) { + return &command.ServerCommand{ + 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 + }, "server-force-leave": func() (cli.Command, error) { return &command.ServerForceLeaveCommand{ Meta: meta, @@ -429,7 +523,7 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { }, nil }, "stop": func() (cli.Command, error) { - return &command.StopCommand{ + return &command.JobStopCommand{ Meta: meta, }, nil }, @@ -439,7 +533,7 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory { }, nil }, "validate": func() (cli.Command, error) { - return &command.ValidateCommand{ + return &command.JobValidateCommand{ Meta: meta, }, nil }, diff --git a/main.go b/main.go index f482ca283..b73c14e1a 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,29 @@ func RunCustom(args []string, commands map[string]cli.CommandFactory) int { // 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"} + hidden := []string{ + "check", + "executor", + "syslog", + "alloc-status", + "eval-status", + "node-drain", + "node-status", + "validate", + "plan", + "init", + "inspect", + "run", + "stop", + "keygen", + "keyring", + "server-force-leave", + "server-join", + "server-members", + "fs", + "logs", + "client-config", + } cli := &cli.CLI{ Name: "nomad",