github.com/manicqin/nomad@v0.9.5/command/alloc_stop.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 type AllocStopCommand struct { 9 Meta 10 } 11 12 func (a *AllocStopCommand) Help() string { 13 helpText := ` 14 Usage: nomad alloc stop [options] <allocation> 15 Alias: nomad stop 16 17 stop an existing allocation. This command is used to signal a specific alloc 18 to shut down. When the allocation has been shut down, it will then be 19 rescheduled. An interactive monitoring session will display log lines as the 20 allocation completes shutting down. It is safe to exit the monitor early with 21 ctrl-c. 22 23 General Options: 24 25 ` + generalOptionsUsage() + ` 26 27 Stop Specific Options: 28 29 -detach 30 Return immediately instead of entering monitor mode. After the 31 stop command is submitted, a new evaluation ID is printed to the 32 screen, which can be used to examine the rescheduling evaluation using the 33 eval-status command. 34 35 -verbose 36 Show full information. 37 ` 38 return strings.TrimSpace(helpText) 39 } 40 41 func (c *AllocStopCommand) Name() string { return "alloc stop" } 42 43 func (c *AllocStopCommand) Run(args []string) int { 44 var detach, verbose bool 45 46 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 47 flags.Usage = func() { c.Ui.Output(c.Help()) } 48 flags.BoolVar(&detach, "detach", false, "") 49 flags.BoolVar(&verbose, "verbose", false, "") 50 51 if err := flags.Parse(args); err != nil { 52 return 1 53 } 54 55 // Check that we got exactly one alloc 56 args = flags.Args() 57 if len(args) != 1 { 58 c.Ui.Error("This command takes one argument: <alloc-id>") 59 c.Ui.Error(commandErrorText(c)) 60 return 1 61 } 62 63 allocID := args[0] 64 65 // Truncate the id unless full length is requested 66 length := shortId 67 if verbose { 68 length = fullId 69 } 70 71 // Query the allocation info 72 if len(allocID) == 1 { 73 c.Ui.Error(fmt.Sprintf("Alloc ID must contain at least two characters.")) 74 return 1 75 } 76 77 allocID = sanitizeUUIDPrefix(allocID) 78 79 // Get the HTTP client 80 client, err := c.Meta.Client() 81 if err != nil { 82 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 83 return 1 84 } 85 86 allocs, _, err := client.Allocations().PrefixList(allocID) 87 if err != nil { 88 c.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) 89 return 1 90 } 91 92 if len(allocs) == 0 { 93 c.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) 94 return 1 95 } 96 97 if len(allocs) > 1 { 98 // Format the allocs 99 out := formatAllocListStubs(allocs, verbose, length) 100 c.Ui.Error(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", out)) 101 return 1 102 } 103 104 // Prefix lookup matched a single allocation 105 alloc, _, err := client.Allocations().Info(allocs[0].ID, nil) 106 if err != nil { 107 c.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) 108 return 1 109 } 110 111 resp, err := client.Allocations().Stop(alloc, nil) 112 if err != nil { 113 c.Ui.Error(fmt.Sprintf("Error stopping allocation: %s", err)) 114 return 1 115 } 116 117 if detach { 118 c.Ui.Output(resp.EvalID) 119 return 0 120 } 121 122 mon := newMonitor(c.Ui, client, length) 123 return mon.monitor(resp.EvalID, false) 124 } 125 126 func (a *AllocStopCommand) Synopsis() string { 127 return "Stop and reschedule a running allocation" 128 }