github.com/hernad/nomad@v1.6.112/command/operator_scheduler_set_config.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package command 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/hernad/nomad/api" 11 flagHelper "github.com/hernad/nomad/helper/flags" 12 "github.com/mitchellh/cli" 13 "github.com/posener/complete" 14 ) 15 16 // Ensure OperatorSchedulerSetConfig satisfies the cli.Command interface. 17 var _ cli.Command = &OperatorSchedulerSetConfig{} 18 19 type OperatorSchedulerSetConfig struct { 20 Meta 21 22 // The scheduler configuration flags allow us to tell whether the user set 23 // a value or not. This means we can safely merge the current configuration 24 // with user supplied, selective updates. 25 checkIndex string 26 schedulerAlgorithm string 27 memoryOversubscription flagHelper.BoolValue 28 rejectJobRegistration flagHelper.BoolValue 29 pauseEvalBroker flagHelper.BoolValue 30 preemptBatchScheduler flagHelper.BoolValue 31 preemptServiceScheduler flagHelper.BoolValue 32 preemptSysBatchScheduler flagHelper.BoolValue 33 preemptSystemScheduler flagHelper.BoolValue 34 } 35 36 func (o *OperatorSchedulerSetConfig) AutocompleteFlags() complete.Flags { 37 return mergeAutocompleteFlags(o.Meta.AutocompleteFlags(FlagSetClient), 38 complete.Flags{ 39 "-check-index": complete.PredictAnything, 40 "-scheduler-algorithm": complete.PredictSet( 41 string(api.SchedulerAlgorithmBinpack), 42 string(api.SchedulerAlgorithmSpread), 43 ), 44 "-memory-oversubscription": complete.PredictSet("true", "false"), 45 "-reject-job-registration": complete.PredictSet("true", "false"), 46 "-pause-eval-broker": complete.PredictSet("true", "false"), 47 "-preempt-batch-scheduler": complete.PredictSet("true", "false"), 48 "-preempt-service-scheduler": complete.PredictSet("true", "false"), 49 "-preempt-sysbatch-scheduler": complete.PredictSet("true", "false"), 50 "-preempt-system-scheduler": complete.PredictSet("true", "false"), 51 }, 52 ) 53 } 54 55 func (o *OperatorSchedulerSetConfig) AutocompleteArgs() complete.Predictor { 56 return complete.PredictNothing 57 } 58 59 func (o *OperatorSchedulerSetConfig) Name() string { return "operator scheduler set-config" } 60 61 func (o *OperatorSchedulerSetConfig) Run(args []string) int { 62 63 flags := o.Meta.FlagSet("set-config", FlagSetClient) 64 flags.Usage = func() { o.Ui.Output(o.Help()) } 65 66 flags.StringVar(&o.checkIndex, "check-index", "", "") 67 flags.StringVar(&o.schedulerAlgorithm, "scheduler-algorithm", "", "") 68 flags.Var(&o.memoryOversubscription, "memory-oversubscription", "") 69 flags.Var(&o.rejectJobRegistration, "reject-job-registration", "") 70 flags.Var(&o.pauseEvalBroker, "pause-eval-broker", "") 71 flags.Var(&o.preemptBatchScheduler, "preempt-batch-scheduler", "") 72 flags.Var(&o.preemptServiceScheduler, "preempt-service-scheduler", "") 73 flags.Var(&o.preemptSysBatchScheduler, "preempt-sysbatch-scheduler", "") 74 flags.Var(&o.preemptSystemScheduler, "preempt-system-scheduler", "") 75 76 if err := flags.Parse(args); err != nil { 77 return 1 78 } 79 80 // Set up a client. 81 client, err := o.Meta.Client() 82 if err != nil { 83 o.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 84 return 1 85 } 86 87 // Check that we got no arguments. 88 args = flags.Args() 89 if l := len(args); l != 0 { 90 o.Ui.Error("This command takes no arguments") 91 o.Ui.Error(commandErrorText(o)) 92 return 1 93 } 94 95 // Convert the check index string and handle any errors before adding this 96 // to our request. This parsing handles empty values correctly. 97 checkIndex, _, err := parseCheckIndex(o.checkIndex) 98 if err != nil { 99 o.Ui.Error(fmt.Sprintf("Error parsing check-index value %q: %v", o.checkIndex, err)) 100 return 1 101 } 102 103 // Fetch the current configuration. This will be used as a base to merge 104 // user configuration onto. 105 resp, _, err := client.Operator().SchedulerGetConfiguration(nil) 106 if err != nil { 107 o.Ui.Error(fmt.Sprintf("Error querying for scheduler configuration: %s", err)) 108 return 1 109 } 110 111 if checkIndex > 0 && resp.SchedulerConfig.ModifyIndex != checkIndex { 112 errMsg := fmt.Sprintf("check-index %v does not match does not match current state value %v", 113 checkIndex, resp.SchedulerConfig.ModifyIndex) 114 o.Ui.Error(fmt.Sprintf("Error performing check index set: %s", errMsg)) 115 return 1 116 } 117 118 schedulerConfig := resp.SchedulerConfig 119 120 // Overwrite the modification index if the user supplied one, otherwise we 121 // use what was included within the read response. 122 if checkIndex > 0 { 123 schedulerConfig.ModifyIndex = checkIndex 124 } 125 126 // Merge the current configuration with any values set by the operator. 127 if o.schedulerAlgorithm != "" { 128 schedulerConfig.SchedulerAlgorithm = api.SchedulerAlgorithm(o.schedulerAlgorithm) 129 } 130 o.memoryOversubscription.Merge(&schedulerConfig.MemoryOversubscriptionEnabled) 131 o.rejectJobRegistration.Merge(&schedulerConfig.RejectJobRegistration) 132 o.pauseEvalBroker.Merge(&schedulerConfig.PauseEvalBroker) 133 o.preemptBatchScheduler.Merge(&schedulerConfig.PreemptionConfig.BatchSchedulerEnabled) 134 o.preemptServiceScheduler.Merge(&schedulerConfig.PreemptionConfig.ServiceSchedulerEnabled) 135 o.preemptSysBatchScheduler.Merge(&schedulerConfig.PreemptionConfig.SysBatchSchedulerEnabled) 136 o.preemptSystemScheduler.Merge(&schedulerConfig.PreemptionConfig.SystemSchedulerEnabled) 137 138 // Check-and-set the new configuration. 139 result, _, err := client.Operator().SchedulerCASConfiguration(schedulerConfig, nil) 140 if err != nil { 141 o.Ui.Error(fmt.Sprintf("Error setting scheduler configuration: %s", err)) 142 return 1 143 } 144 if result.Updated { 145 o.Ui.Output("Scheduler configuration updated!") 146 return 0 147 } 148 o.Ui.Output("Scheduler configuration could not be atomically updated, please try again") 149 return 1 150 } 151 152 func (o *OperatorSchedulerSetConfig) Synopsis() string { 153 return "Modify the current scheduler configuration" 154 } 155 156 func (o *OperatorSchedulerSetConfig) Help() string { 157 helpText := ` 158 Usage: nomad operator scheduler set-config [options] 159 160 Modifies the current scheduler configuration. 161 162 If ACLs are enabled, this command requires a token with the 'operator:write' 163 capability. 164 165 General Options: 166 167 ` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace) + ` 168 169 Scheduler Set Config Options: 170 171 -check-index 172 If set, the scheduler config is only updated if the passed modify index 173 matches the current server side version. If a non-zero value is passed, it 174 ensures that the scheduler config is being updated from a known state. 175 176 -scheduler-algorithm=["binpack"|"spread"] 177 Specifies whether scheduler binpacks or spreads allocations on available 178 nodes. 179 180 -memory-oversubscription=[true|false] 181 When true, tasks may exceed their reserved memory limit, if the client has 182 excess memory capacity. Tasks must specify memory_max to take advantage of 183 memory oversubscription. 184 185 -reject-job-registration=[true|false] 186 When true, the server will return permission denied errors for job registration, 187 job dispatch, and job scale APIs, unless the ACL token for the request is a 188 management token. If ACLs are disabled, no user will be able to register jobs. 189 This allows operators to shed load from automated processes during incident 190 response. 191 192 -pause-eval-broker=[true|false] 193 When set to true, the eval broker which usually runs on the leader will be 194 disabled. This will prevent the scheduler workers from receiving new work. 195 196 -preempt-batch-scheduler=[true|false] 197 Specifies whether preemption for batch jobs is enabled. Note that if this 198 is set to true, then batch jobs can preempt any other jobs. 199 200 -preempt-service-scheduler=[true|false] 201 Specifies whether preemption for service jobs is enabled. Note that if this 202 is set to true, then service jobs can preempt any other jobs. 203 204 -preempt-sysbatch-scheduler=[true|false] 205 Specifies whether preemption for system batch jobs is enabled. Note that if 206 this is set to true, then system batch jobs can preempt any other jobs. 207 208 -preempt-system-scheduler=[true|false] 209 Specifies whether preemption for system jobs is enabled. Note that if this 210 is set to true, then system jobs can preempt any other jobs. 211 ` 212 return strings.TrimSpace(helpText) 213 }