github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/job_eval.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hashicorp/nomad/api" 8 "github.com/hashicorp/nomad/api/contexts" 9 "github.com/posener/complete" 10 ) 11 12 type JobEvalCommand struct { 13 Meta 14 forceRescheduling bool 15 } 16 17 func (c *JobEvalCommand) Help() string { 18 helpText := ` 19 Usage: nomad job eval [options] <job_id> 20 21 Force an evaluation of the provided job ID. Forcing an evaluation will 22 trigger the scheduler to re-evaluate the job. The force flags allow 23 operators to force the scheduler to create new allocations under certain 24 scenarios. 25 26 When ACLs are enabled, this command requires a token with the 'submit-job' 27 capability for the job's namespace. 28 29 General Options: 30 31 ` + generalOptionsUsage(usageOptsDefault) + ` 32 33 Eval Options: 34 35 -force-reschedule 36 Force reschedule failed allocations even if they are not currently 37 eligible for rescheduling. 38 39 -detach 40 Return immediately instead of entering monitor mode. The ID 41 of the evaluation created will be printed to the screen, which can be 42 used to examine the evaluation using the eval-status command. 43 44 -verbose 45 Display full information. 46 ` 47 return strings.TrimSpace(helpText) 48 } 49 50 func (c *JobEvalCommand) Synopsis() string { 51 return "Force an evaluation for the job" 52 } 53 54 func (c *JobEvalCommand) AutocompleteFlags() complete.Flags { 55 return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), 56 complete.Flags{ 57 "-force-reschedule": complete.PredictNothing, 58 "-detach": complete.PredictNothing, 59 "-verbose": complete.PredictNothing, 60 }) 61 } 62 63 func (c *JobEvalCommand) AutocompleteArgs() complete.Predictor { 64 return complete.PredictFunc(func(a complete.Args) []string { 65 client, err := c.Meta.Client() 66 if err != nil { 67 return nil 68 } 69 70 resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Jobs, nil) 71 if err != nil { 72 return []string{} 73 } 74 return resp.Matches[contexts.Jobs] 75 }) 76 } 77 78 func (c *JobEvalCommand) Name() string { return "job eval" } 79 80 func (c *JobEvalCommand) Run(args []string) int { 81 var detach, verbose bool 82 83 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 84 flags.Usage = func() { c.Ui.Output(c.Help()) } 85 flags.BoolVar(&c.forceRescheduling, "force-reschedule", false, "") 86 flags.BoolVar(&detach, "detach", false, "") 87 flags.BoolVar(&verbose, "verbose", false, "") 88 89 if err := flags.Parse(args); err != nil { 90 return 1 91 } 92 93 // Check that we either got no jobs or exactly one. 94 args = flags.Args() 95 if len(args) != 1 { 96 c.Ui.Error("This command takes one argument: <job>") 97 c.Ui.Error(commandErrorText(c)) 98 return 1 99 } 100 101 // Get the HTTP client 102 client, err := c.Meta.Client() 103 if err != nil { 104 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 105 return 1 106 } 107 108 // Truncate the id unless full length is requested 109 length := shortId 110 if verbose { 111 length = fullId 112 } 113 // Call eval endpoint 114 jobID := args[0] 115 116 opts := api.EvalOptions{ 117 ForceReschedule: c.forceRescheduling, 118 } 119 evalId, _, err := client.Jobs().EvaluateWithOpts(jobID, opts, nil) 120 if err != nil { 121 c.Ui.Error(fmt.Sprintf("Error evaluating job: %s", err)) 122 return 1 123 } 124 125 if detach { 126 c.Ui.Output(fmt.Sprintf("Created eval ID: %q ", limit(evalId, length))) 127 return 0 128 } 129 130 mon := newMonitor(c.Ui, client, length) 131 return mon.monitor(evalId) 132 }