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  }