diff --git a/CHANGELOG.md b/CHANGELOG.md index 128674d6a066..9267f1e96519 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,7 +46,9 @@ BUG FIXES: * client: Improve auto-detection of network interface when interface name has a space in it on Windows [[GH-3855](https://github.com/hashicorp/nomad/issues/3855)] * client/vault: Recognize renewing non-renewable Vault lease as fatal [[GH-3727](https://github.com/hashicorp/nomad/issues/3727)] - * config: Revert minimum CPU limit back to 20 from 100. + * config: Revert minimum CPU limit back to 20 from 100 [[GH-3706](https://github.com/hashicorp/nomad/issues/3706)] + * config: Always add core scheduler to enabled schedulers and add invalid + EnabledScheduler detection [[GH-3978](https://github.com/hashicorp/nomad/issues/3978)] * driver/exec: Properly disable swapping [[GH-3958](https://github.com/hashicorp/nomad/issues/3958)] * driver/lxc: Cleanup LXC containers after errors on container startup. [[GH-3773](https://github.com/hashicorp/nomad/issues/3773)] * ui: Fix ui on non-leaders when ACLs are enabled [[GH-3722](https://github.com/hashicorp/nomad/issues/3722)] diff --git a/command/agent/agent.go b/command/agent/agent.go index eff225a3b116..e0066f32961a 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -149,7 +149,20 @@ func convertServerConfig(agentConfig *Config, logOutput io.Writer) (*nomad.Confi conf.NumSchedulers = agentConfig.Server.NumSchedulers } if len(agentConfig.Server.EnabledSchedulers) != 0 { - conf.EnabledSchedulers = agentConfig.Server.EnabledSchedulers + // Convert to a set and require the core scheduler + set := make(map[string]struct{}, 4) + set[structs.JobTypeCore] = struct{}{} + for _, sched := range agentConfig.Server.EnabledSchedulers { + set[sched] = struct{}{} + } + + schedulers := make([]string, 0, len(set)) + for k := range set { + schedulers = append(schedulers, k) + } + + conf.EnabledSchedulers = schedulers + } if agentConfig.ACL.Enabled { conf.ACLEnabled = true diff --git a/nomad/server.go b/nomad/server.go index fe72cbb34205..53c36ea328a0 100644 --- a/nomad/server.go +++ b/nomad/server.go @@ -30,6 +30,7 @@ import ( "github.com/hashicorp/nomad/nomad/state" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/nomad/structs/config" + "github.com/hashicorp/nomad/scheduler" "github.com/hashicorp/raft" raftboltdb "github.com/hashicorp/raft-boltdb" "github.com/hashicorp/serf/serf" @@ -1193,6 +1194,22 @@ func (s *Server) setupWorkers() error { return nil } + // Check if the core scheduler is not enabled + foundCore := false + for _, sched := range s.config.EnabledSchedulers { + if sched == structs.JobTypeCore { + foundCore = true + continue + } + + if _, ok := scheduler.BuiltinSchedulers[sched]; !ok { + return fmt.Errorf("invalid configuration: unknown scheduler %q in enabled schedulers", sched) + } + } + if !foundCore { + return fmt.Errorf("invalid configuration: %q scheduler not enabled", structs.JobTypeCore) + } + // Start the workers for i := 0; i < s.config.NumSchedulers; i++ { if w, err := NewWorker(s); err != nil { diff --git a/nomad/server_test.go b/nomad/server_test.go index 81b06197d990..ba5ccf22ca87 100644 --- a/nomad/server_test.go +++ b/nomad/server_test.go @@ -3,6 +3,7 @@ package nomad import ( "fmt" "io/ioutil" + "log" "os" "path" "strings" @@ -10,12 +11,15 @@ import ( "time" msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc" + "github.com/hashicorp/nomad/command/agent/consul" + "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/helper/uuid" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/nomad/structs/config" "github.com/hashicorp/nomad/testutil" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func tmpDir(t *testing.T) string { @@ -412,3 +416,26 @@ func TestServer_Reload_TLSConnections_Raft(t *testing.T) { testutil.WaitForLeader(t, s2.RPC) } + +func TestServer_InvalidSchedulers(t *testing.T) { + t.Parallel() + require := require.New(t) + + config := DefaultConfig() + config.DevMode = true + config.LogOutput = testlog.NewWriter(t) + logger := log.New(config.LogOutput, "", log.LstdFlags) + catalog := consul.NewMockCatalog(logger) + + // Set the config to not have the core scheduler + config.EnabledSchedulers = []string{"batch"} + _, err := NewServer(config, catalog, logger) + require.NotNil(err) + require.Contains(err.Error(), "scheduler not enabled") + + // Set the config to have an unknown scheduler + config.EnabledSchedulers = []string{"batch", structs.JobTypeCore, "foo"} + _, err = NewServer(config, catalog, logger) + require.NotNil(err) + require.Contains(err.Error(), "foo") +}