github.com/adityamillind98/nomad@v0.11.8/command/alloc_signal.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hashicorp/nomad/api/contexts" 8 "github.com/posener/complete" 9 ) 10 11 type AllocSignalCommand struct { 12 Meta 13 } 14 15 func (a *AllocSignalCommand) Help() string { 16 helpText := ` 17 Usage: nomad alloc signal [options] <signal> <allocation> <task> 18 19 signal an existing allocation. This command is used to signal a specific alloc 20 and its subtasks. If no task is provided then all of the allocations subtasks 21 will receive the signal. 22 23 General Options: 24 25 ` + generalOptionsUsage() + ` 26 27 Signal Specific Options: 28 29 -s 30 Specify the signal that the selected tasks should receive. 31 32 -verbose 33 Show full information. 34 ` 35 return strings.TrimSpace(helpText) 36 } 37 38 func (c *AllocSignalCommand) Name() string { return "alloc signal" } 39 40 func (c *AllocSignalCommand) Run(args []string) int { 41 var verbose bool 42 var signal string 43 44 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 45 flags.Usage = func() { c.Ui.Output(c.Help()) } 46 flags.BoolVar(&verbose, "verbose", false, "") 47 flags.StringVar(&signal, "s", "SIGKILL", "") 48 49 if err := flags.Parse(args); err != nil { 50 return 1 51 } 52 53 // Check that we got exactly one alloc 54 args = flags.Args() 55 if len(args) < 1 || len(args) > 2 { 56 c.Ui.Error("This command takes up to two arguments: <alloc-id> <task>") 57 c.Ui.Error(commandErrorText(c)) 58 return 1 59 } 60 61 allocID := args[0] 62 63 // Truncate the id unless full length is requested 64 length := shortId 65 if verbose { 66 length = fullId 67 } 68 69 // Query the allocation info 70 if len(allocID) == 1 { 71 c.Ui.Error(fmt.Sprintf("Alloc ID must contain at least two characters.")) 72 return 1 73 } 74 75 allocID = sanitizeUUIDPrefix(allocID) 76 77 // Get the HTTP client 78 client, err := c.Meta.Client() 79 if err != nil { 80 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 81 return 1 82 } 83 84 allocs, _, err := client.Allocations().PrefixList(allocID) 85 if err != nil { 86 c.Ui.Error(fmt.Sprintf("Error querying allocation: %v", err)) 87 return 1 88 } 89 90 if len(allocs) == 0 { 91 c.Ui.Error(fmt.Sprintf("No allocation(s) with prefix or id %q found", allocID)) 92 return 1 93 } 94 95 if len(allocs) > 1 { 96 // Format the allocs 97 out := formatAllocListStubs(allocs, verbose, length) 98 c.Ui.Error(fmt.Sprintf("Prefix matched multiple allocations\n\n%s", out)) 99 return 1 100 } 101 102 // Prefix lookup matched a single allocation 103 alloc, _, err := client.Allocations().Info(allocs[0].ID, nil) 104 if err != nil { 105 c.Ui.Error(fmt.Sprintf("Error querying allocation: %s", err)) 106 return 1 107 } 108 109 var taskName string 110 if len(args) == 2 { 111 // Validate Task 112 taskName = args[1] 113 err := validateTaskExistsInAllocation(taskName, alloc) 114 if err != nil { 115 c.Ui.Error(err.Error()) 116 return 1 117 } 118 } 119 120 err = client.Allocations().Signal(alloc, nil, taskName, signal) 121 if err != nil { 122 c.Ui.Error(fmt.Sprintf("Error signalling allocation: %s", err)) 123 return 1 124 } 125 126 return 0 127 } 128 129 func (a *AllocSignalCommand) Synopsis() string { 130 return "Signal a running allocation" 131 } 132 133 func (c *AllocSignalCommand) AutocompleteFlags() complete.Flags { 134 return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), 135 complete.Flags{ 136 "-s": complete.PredictNothing, 137 "-verbose": complete.PredictNothing, 138 }) 139 } 140 func (c *AllocSignalCommand) AutocompleteArgs() complete.Predictor { 141 // Here we only autocomplete allocation names. Eventually we may consider 142 // expanding this to also autocomplete task names. To do so, we'll need to 143 // either change the autocompletion api, or implement parsing such that we can 144 // easily compute the current arg position. 145 return complete.PredictFunc(func(a complete.Args) []string { 146 client, err := c.Meta.Client() 147 if err != nil { 148 return nil 149 } 150 151 resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Allocs, nil) 152 if err != nil { 153 return []string{} 154 } 155 return resp.Matches[contexts.Allocs] 156 }) 157 }