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