github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/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 (c *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 -no-shutdown-delay 42 Ignore the the group and task shutdown_delay configuration so there is no 43 delay between service deregistration and task shutdown. Note that using 44 this flag will result in failed network connections to the allocation 45 being stopped. 46 47 -verbose 48 Show full information. 49 ` 50 return strings.TrimSpace(helpText) 51 } 52 53 func (c *AllocStopCommand) Name() string { return "alloc stop" } 54 55 func (c *AllocStopCommand) Run(args []string) int { 56 var detach, verbose, noShutdownDelay bool 57 58 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 59 flags.Usage = func() { c.Ui.Output(c.Help()) } 60 flags.BoolVar(&detach, "detach", false, "") 61 flags.BoolVar(&verbose, "verbose", false, "") 62 flags.BoolVar(&noShutdownDelay, "no-shutdown-delay", false, "") 63 64 if err := flags.Parse(args); err != nil { 65 return 1 66 } 67 68 // Check that we got exactly one alloc 69 args = flags.Args() 70 if len(args) != 1 { 71 c.Ui.Error("This command takes one argument: <alloc-id>") 72 c.Ui.Error(commandErrorText(c)) 73 return 1 74 } 75 76 allocID := args[0] 77 78 // Truncate the id unless full length is requested 79 length := shortId 80 if verbose { 81 length = fullId 82 } 83 84 // Query the allocation info 85 if len(allocID) == 1 { 86 c.Ui.Error("Alloc ID must contain at least two characters.") 87 return 1 88 } 89 90 allocID = sanitizeUUIDPrefix(allocID) 91 92 // Get the HTTP client 93 client, err := c.Meta.Client() 94 if err != nil { 95 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 96 return 1 97 } 98 99 allocs, _, err := client.Allocations().PrefixList(allocID) 100 if err != nil { 101 c.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) 102 return 1 103 } 104 105 if len(allocs) == 0 { 106 c.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) 107 return 1 108 } 109 110 if len(allocs) > 1 { 111 // Format the allocs 112 out := formatAllocListStubs(allocs, verbose, length) 113 c.Ui.Error(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", out)) 114 return 1 115 } 116 117 // Prefix lookup matched a single allocation 118 q := &api.QueryOptions{Namespace: allocs[0].Namespace} 119 alloc, _, err := client.Allocations().Info(allocs[0].ID, q) 120 if err != nil { 121 c.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) 122 return 1 123 } 124 125 var opts *api.QueryOptions 126 if noShutdownDelay { 127 opts = &api.QueryOptions{Params: map[string]string{"no_shutdown_delay": "true"}} 128 } 129 130 resp, err := client.Allocations().Stop(alloc, opts) 131 if err != nil { 132 c.Ui.Error(fmt.Sprintf("Error stopping allocation: %s", err)) 133 return 1 134 } 135 136 if detach { 137 c.Ui.Output(resp.EvalID) 138 return 0 139 } 140 141 mon := newMonitor(c.Ui, client, length) 142 return mon.monitor(resp.EvalID) 143 } 144 145 func (c *AllocStopCommand) Synopsis() string { 146 return "Stop and reschedule a running allocation" 147 }