github.com/ranjib/nomad@v0.1.1-0.20160225204057-97751b02f70b/command/stop.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 type StopCommand struct { 9 Meta 10 } 11 12 func (c *StopCommand) Help() string { 13 helpText := ` 14 Usage: nomad stop [options] <job> 15 16 Stop an existing job. This command is used to signal allocations 17 to shut down for the given job ID. Upon successful deregistraion, 18 an interactive monitor session will start to display log lines as 19 the job unwinds its allocations and completes shutting down. It 20 is safe to exit the monitor early using ctrl+c. 21 22 General Options: 23 24 ` + generalOptionsUsage() + ` 25 26 Stop Options: 27 28 -detach 29 Return immediately instead of entering monitor mode. After the 30 deregister command is submitted, a new evaluation ID is printed 31 to the screen, which can be used to call up a monitor later if 32 needed using the eval-monitor command. 33 34 -verbose 35 Display full information. 36 ` 37 return strings.TrimSpace(helpText) 38 } 39 40 func (c *StopCommand) Synopsis() string { 41 return "Stop a running job" 42 } 43 44 func (c *StopCommand) Run(args []string) int { 45 var detach, verbose bool 46 47 flags := c.Meta.FlagSet("stop", FlagSetClient) 48 flags.Usage = func() { c.Ui.Output(c.Help()) } 49 flags.BoolVar(&detach, "detach", false, "") 50 flags.BoolVar(&verbose, "verbose", false, "") 51 52 if err := flags.Parse(args); err != nil { 53 return 1 54 } 55 56 // Truncate the id unless full length is requested 57 length := shortId 58 if verbose { 59 length = fullId 60 } 61 62 // Check that we got exactly one job 63 args = flags.Args() 64 if len(args) != 1 { 65 c.Ui.Error(c.Help()) 66 return 1 67 } 68 jobID := args[0] 69 70 // Get the HTTP client 71 client, err := c.Meta.Client() 72 if err != nil { 73 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 74 return 1 75 } 76 77 // Check if the job exists 78 job, _, err := client.Jobs().Info(jobID, nil) 79 if err != nil { 80 jobs, _, err := client.Jobs().PrefixList(jobID) 81 if err != nil { 82 c.Ui.Error(fmt.Sprintf("Error deregistering job: %s", err)) 83 return 1 84 } 85 if len(jobs) == 0 { 86 c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID)) 87 return 1 88 } 89 if len(jobs) > 1 { 90 out := make([]string, len(jobs)+1) 91 out[0] = "ID|Type|Priority|Status" 92 for i, job := range jobs { 93 out[i+1] = fmt.Sprintf("%s|%s|%d|%s", 94 job.ID, 95 job.Type, 96 job.Priority, 97 job.Status) 98 } 99 c.Ui.Output(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", formatList(out))) 100 return 0 101 } 102 // Prefix lookup matched a single job 103 job, _, err = client.Jobs().Info(jobs[0].ID, nil) 104 if err != nil { 105 c.Ui.Error(fmt.Sprintf("Error deregistering job: %s", err)) 106 return 1 107 } 108 } 109 110 // Invoke the stop 111 evalID, _, err := client.Jobs().Deregister(job.ID, nil) 112 if err != nil { 113 c.Ui.Error(fmt.Sprintf("Error deregistering job: %s", err)) 114 return 1 115 } 116 117 // If we are stopping a periodic job there won't be an evalID. 118 if evalID == "" { 119 return 0 120 } 121 122 if detach { 123 c.Ui.Output(evalID) 124 return 0 125 } 126 127 // Start monitoring the stop eval 128 mon := newMonitor(c.Ui, client, length) 129 return mon.monitor(evalID, false) 130 }