diff --git a/nomad/config.go b/nomad/config.go index 18748b699..c3d134b76 100644 --- a/nomad/config.go +++ b/nomad/config.go @@ -8,6 +8,7 @@ import ( "time" "github.com/hashicorp/memberlist" + "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/scheduler" "github.com/hashicorp/raft" "github.com/hashicorp/serf/serf" @@ -164,6 +165,7 @@ func DefaultConfig() *Config { for name := range scheduler.BuiltinSchedulers { c.EnabledSchedulers = append(c.EnabledSchedulers, name) } + c.EnabledSchedulers = append(c.EnabledSchedulers, structs.JobTypeSystem) // Increase our reap interval to 3 days instead of 24h. c.SerfConfig.ReconnectTimeout = 3 * 24 * time.Hour diff --git a/nomad/job_endpoint.go b/nomad/job_endpoint.go index 5e84c7c68..58bf67003 100644 --- a/nomad/job_endpoint.go +++ b/nomad/job_endpoint.go @@ -33,6 +33,9 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis if args.Job.Type == "" { return fmt.Errorf("missing job type for registration") } + if args.Job.Type == structs.JobTypeSystem { + return fmt.Errorf("job type cannot be system") + } // Ensure priorities are bounded if args.Job.Priority < structs.JobMinPriority { diff --git a/nomad/server.go b/nomad/server.go index 1b4501f97..e91c79315 100644 --- a/nomad/server.go +++ b/nomad/server.go @@ -99,6 +99,10 @@ type Server struct { // plans that are waiting to be assessed by the leader planQueue *PlanQueue + // systemSched is the special system scheduler used for + // various maintanence and book keeping. + systemSched *SystemScheduler + left bool shutdown bool shutdownCh chan struct{} @@ -157,6 +161,9 @@ func NewServer(config *Config) (*Server, error) { shutdownCh: make(chan struct{}), } + // Create the system scheduler + s.systemSched = &SystemScheduler{srv: s} + // Initialize the RPC layer // TODO: TLS... if err := s.setupRPC(nil); err != nil { diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index d1bb8c91f..21ff6fb38 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -440,6 +440,9 @@ func (n *NetworkResource) Add(delta *NetworkResource) { } const ( + // JobTypeSystem is reserved for internal system tasks and is + // always handled by the SystemScheduler. + JobTypeSystem = "system" JobTypeService = "service" JobTypeBatch = "batch" ) diff --git a/nomad/worker.go b/nomad/worker.go index 350489e0f..c44f008c6 100644 --- a/nomad/worker.go +++ b/nomad/worker.go @@ -190,10 +190,15 @@ func (w *Worker) invokeScheduler(eval *structs.Evaluation) error { return fmt.Errorf("failed to snapshot state: %v", err) } - // Create the scheduler - sched, err := scheduler.NewScheduler(eval.Type, snap, w) - if err != nil { - return fmt.Errorf("failed to instantiate scheduler: %v", err) + // Create the scheduler, or use the special system scheduler + var sched scheduler.Scheduler + if eval.Type == structs.JobTypeSystem { + sched = w.srv.systemSched + } else { + sched, err = scheduler.NewScheduler(eval.Type, snap, w) + if err != nil { + return fmt.Errorf("failed to instantiate scheduler: %v", err) + } } // Process the evaluation