nomad: working on job struct and schema

This commit is contained in:
Armon Dadgar
2015-07-03 16:57:48 -07:00
parent 1ea2f6fb54
commit cccc925f24
2 changed files with 263 additions and 26 deletions

View File

@@ -1,6 +1,10 @@
package nomad
import "github.com/hashicorp/go-memdb"
import (
"fmt"
"github.com/hashicorp/go-memdb"
)
// stateStoreSchema is used to return the schema for the state store
func stateStoreSchema() *memdb.DBSchema {
@@ -9,17 +13,29 @@ func stateStoreSchema() *memdb.DBSchema {
Tables: make(map[string]*memdb.TableSchema),
}
// Add each of the tables
nodeSchema := nodeTableSchema()
db.Tables[nodeSchema.Name] = nodeSchema
// Collect all the schemas that are needed
schemas := []func() *memdb.TableSchema{
nodeTableSchema,
jobTableSchema,
taskGroupTableSchema,
taskTableSchema,
}
// Add each of the tables
for _, schemaFn := range schemas {
schema := schemaFn()
if _, ok := db.Tables[schema.Name]; ok {
panic(fmt.Sprintf("duplicate table name: %s", schema.Name))
}
db.Tables[schema.Name] = schema
}
return db
}
// nodeTableSchema returns the MemDB schema for the nodes table.
// This table is used to store all the client nodes that are registered.
func nodeTableSchema() *memdb.TableSchema {
table := &memdb.TableSchema{
return &memdb.TableSchema{
Name: "nodes",
Indexes: map[string]*memdb.IndexSchema{
// Primary index is used for node management
@@ -51,7 +67,101 @@ func nodeTableSchema() *memdb.TableSchema {
Lowercase: true,
},
&memdb.StringFieldIndex{
Field: "Status",
Field: "Status",
},
},
},
},
},
}
}
// jobTableSchema returns the MemDB schema for the jobs table.
// This table is used to store all the jobs that have been submitted.
func jobTableSchema() *memdb.TableSchema {
return &memdb.TableSchema{
Name: "jobs",
Indexes: map[string]*memdb.IndexSchema{
// Primary index is used for job management
// and simple direct lookup. ID is required to be
// unique.
"id": &memdb.IndexSchema{
Name: "id",
AllowMissing: false,
Unique: true,
Indexer: &memdb.StringFieldIndex{
Field: "Name",
Lowercase: true,
},
},
// Status is used to scan for jobs that are in need
// of scheduling attention.
"status": &memdb.IndexSchema{
Name: "status",
AllowMissing: false,
Unique: false,
Indexer: &memdb.StringFieldIndex{
Field: "Status",
},
},
},
}
}
// taskGroupTableSchema returns the MemDB schema for the task group table.
// This table is used to store all the task groups belonging to a job.
func taskGroupTableSchema() *memdb.TableSchema {
return &memdb.TableSchema{
Name: "taskGroups",
Indexes: map[string]*memdb.IndexSchema{
// Primary index is compount of {Job, Name}
"id": &memdb.IndexSchema{
Name: "id",
AllowMissing: false,
Unique: true,
Indexer: &memdb.CompoundIndex{
AllowMissing: false,
Indexes: []memdb.Indexer{
&memdb.StringFieldIndex{
Field: "Job",
Lowercase: true,
},
&memdb.StringFieldIndex{
Field: "Name",
Lowercase: true,
},
},
},
},
},
}
}
// taskTableSchema returns the MemDB schema for the tasks table.
// This table is used to store all the task groups belonging to a job.
func taskTableSchema() *memdb.TableSchema {
return &memdb.TableSchema{
Name: "tasks",
Indexes: map[string]*memdb.IndexSchema{
// Primary index is compount of {Job, TaskGroup, Name}
"id": &memdb.IndexSchema{
Name: "id",
AllowMissing: false,
Unique: true,
Indexer: &memdb.CompoundIndex{
AllowMissing: false,
Indexes: []memdb.Indexer{
&memdb.StringFieldIndex{
Field: "Job",
Lowercase: true,
},
&memdb.StringFieldIndex{
Field: "TaskGroup",
Lowercase: true,
},
&memdb.StringFieldIndex{
Field: "Name",
Lowercase: true,
},
},
@@ -59,5 +169,4 @@ func nodeTableSchema() *memdb.TableSchema {
},
},
}
return table
}

View File

@@ -106,13 +106,6 @@ type WriteMeta struct {
Index uint64
}
const (
StatusInit = "initializing"
StatusReady = "ready"
StatusMaint = "maintenance"
StatusDown = "down"
)
// RegisterRequest is used for Client.Register endpoint
// to register a node as being a schedulable entity.
type RegisterRequest struct {
@@ -125,6 +118,13 @@ type RegisterResponse struct {
WriteMeta
}
const (
NodeStatusInit = "initializing"
NodeStatusReady = "ready"
NodeStatusMaint = "maintenance"
NodeStatusDown = "down"
)
// Node is a representation of a schedulable client node
type Node struct {
// ID is a unique identifier for the node. It can be constructed
@@ -148,6 +148,18 @@ type Node struct {
// For example 'cpu=2' 'memory=2048'
Resouces *Resources
// Reserved is the set of resources that are reserved,
// and should be subtracted from the total resources for
// the purposes of scheduling. This may be provide certain
// high-watermark tolerances or because of external schedulers
// consuming resources.
Reserved *Resources
// Allocated is the set of resources that have been allocated
// as part of scheduling. They should also be excluded for the
// purposes of additional scheduling allocations.
Allocated *Resources
// Links are used to 'link' this client to external
// systems. For example 'consul=foo.dc1' 'aws=i-83212'
// 'ami=ami-123'
@@ -164,26 +176,142 @@ type Node struct {
// Resources is used to define the resources available
// on a client
type Resources struct {
CPU float64
CPUReserved float64
MemoryMB int
MemoryMBReserved int
DiskMB int
DiskMBReservered int
IOPS int
IOPSReserved int
Networks []*NetworkResource
Other map[string]interface{}
CPU float64
MemoryMB int
DiskMB int
IOPS int
Networks []*NetworkResource
Other map[string]interface{}
}
// NetworkResource is used to represesent available network
// resources>
// resources
type NetworkResource struct {
Public bool // Is this a public address?
CIDR string // CIDR block of addresses
ReservedPorts []int // Reserved ports
MBits int // Throughput
MBitsReserved int
}
const (
JobTypeService = "service"
JobTypeBatch = "batch"
)
const (
JobStatusPending = "pending" // Pending means the job is waiting on scheduling
JobStatusRunning = "running" // Running means the entire job is running
JobStatusComplete = "complete" // Complete means there was a clean termination
JobStatusDead = "dead" // Dead means there was abnormal termination
)
// Job is the scope of a scheduling request to Nomad. It is the largest
// scoped object, and is a named collection of task groups. Each task group
// is further composed of tasks. A task group (TG) is the unit of scheduling
// however.
type Job struct {
// Name is the logical name of the job used to refer to it. This is unique
// per region, but not unique globally.
Name string
// Type is used to control various behaviors about the job. Most jobs
// are service jobs, meaning they are expected to be long lived.
// Some jobs are batch oriented meaning they run and then terminate.
// This can be extended in the future to support custom schedulers.
Type string
// Priority is used to control scheduling importance and if this job
// can preempt other jobs.
Priority int
// AllAtOnce is used to control if incremental scheduling of task groups
// is allowed or if we must do a gang scheduling of the entire job. This
// can slow down larger jobs if resources are not available.
AllAtOnce bool
// Constraints can be specified at a job level and apply to
// all the task groups and tasks.
Constraints []*Constraint
// TaskGroups are the collections of task groups that this job needs
// to run. Each task group is an atomic unit of scheduling and placement.
TaskGroups []*TaskGroup
// Meta is used to associate arbitrary metadata with this
// job. This is opaque to Nomad.
Meta map[string]string
// Job status
Status string
}
// TaskGroup is an atomic unit of placement. Each task group belongs to
// a job and may contain any number of tasks. A task group support running
// in many replicas using the same configuration..
type TaskGroup struct {
// Name of the parent job
Job string
// Name of the task group
Name string
// Count is the number of replicas of this task group that should
// be scheduled.
Count int
// Constraints can be specified at a task group level and apply to
// all the tasks contained.
Constraints []*Constraint
// Tasks are the collection of tasks that this task group needs to run
Tasks []*Task
// Meta is used to associate arbitrary metadata with this
// task group. This is opaque to Nomad.
Meta map[string]string
// Task group status
Status string
}
// Task is a single process typically that is executed as part of a task group.
type Task struct {
// Name of the parent job
Job string
// Name of the partent task group
TaskGroup string
// Name of the task
Name string
// Driver is used to control which driver is used
Driver string
// Config is provided to the driver to initialize
Config map[string]string
// Constraints can be specified at a task level and apply only to
// the particular task.
Constraints []*Constraint
// Resources is the resources needed by this task
Resources *Resources
// Meta is used to associate arbitrary metadata with this
// task. This is opaque to Nomad.
Meta map[string]string
}
// Constraints are used to restrict placement options in the case of
// a hard constraint, and used to prefer a placement in the case of
// a soft constraint.
type Constraint struct {
Hard bool // Hard or soft constraint
LTarget string // Left-hand target
RTarget string // Right-hand target
Operand string // Constraint operand (<=, <, =, !=, >, >=), contains, near
Weight int // Soft constraints can vary the weight
}
// msgpackHandle is a shared handle for encoding/decoding of structs