github.com/ryanslade/nomad@v0.2.4-0.20160128061903-fc95782f2089/nomad/state/schema.go (about) 1 package state 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/go-memdb" 7 "github.com/hashicorp/nomad/nomad/structs" 8 ) 9 10 // stateStoreSchema is used to return the schema for the state store 11 func stateStoreSchema() *memdb.DBSchema { 12 // Create the root DB schema 13 db := &memdb.DBSchema{ 14 Tables: make(map[string]*memdb.TableSchema), 15 } 16 17 // Collect all the schemas that are needed 18 schemas := []func() *memdb.TableSchema{ 19 indexTableSchema, 20 nodeTableSchema, 21 jobTableSchema, 22 periodicLaunchTableSchema, 23 evalTableSchema, 24 allocTableSchema, 25 } 26 27 // Add each of the tables 28 for _, schemaFn := range schemas { 29 schema := schemaFn() 30 if _, ok := db.Tables[schema.Name]; ok { 31 panic(fmt.Sprintf("duplicate table name: %s", schema.Name)) 32 } 33 db.Tables[schema.Name] = schema 34 } 35 return db 36 } 37 38 // indexTableSchema is used for 39 func indexTableSchema() *memdb.TableSchema { 40 return &memdb.TableSchema{ 41 Name: "index", 42 Indexes: map[string]*memdb.IndexSchema{ 43 "id": &memdb.IndexSchema{ 44 Name: "id", 45 AllowMissing: false, 46 Unique: true, 47 Indexer: &memdb.StringFieldIndex{ 48 Field: "Key", 49 Lowercase: true, 50 }, 51 }, 52 }, 53 } 54 } 55 56 // nodeTableSchema returns the MemDB schema for the nodes table. 57 // This table is used to store all the client nodes that are registered. 58 func nodeTableSchema() *memdb.TableSchema { 59 return &memdb.TableSchema{ 60 Name: "nodes", 61 Indexes: map[string]*memdb.IndexSchema{ 62 // Primary index is used for node management 63 // and simple direct lookup. ID is required to be 64 // unique. 65 "id": &memdb.IndexSchema{ 66 Name: "id", 67 AllowMissing: false, 68 Unique: true, 69 Indexer: &memdb.UUIDFieldIndex{ 70 Field: "ID", 71 }, 72 }, 73 }, 74 } 75 } 76 77 // jobTableSchema returns the MemDB schema for the jobs table. 78 // This table is used to store all the jobs that have been submitted. 79 func jobTableSchema() *memdb.TableSchema { 80 return &memdb.TableSchema{ 81 Name: "jobs", 82 Indexes: map[string]*memdb.IndexSchema{ 83 // Primary index is used for job management 84 // and simple direct lookup. ID is required to be 85 // unique. 86 "id": &memdb.IndexSchema{ 87 Name: "id", 88 AllowMissing: false, 89 Unique: true, 90 Indexer: &memdb.StringFieldIndex{ 91 Field: "ID", 92 Lowercase: true, 93 }, 94 }, 95 "type": &memdb.IndexSchema{ 96 Name: "type", 97 AllowMissing: false, 98 Unique: false, 99 Indexer: &memdb.StringFieldIndex{ 100 Field: "Type", 101 Lowercase: false, 102 }, 103 }, 104 "gc": &memdb.IndexSchema{ 105 Name: "gc", 106 AllowMissing: false, 107 Unique: false, 108 Indexer: &memdb.ConditionalIndex{ 109 Conditional: jobIsGCable, 110 }, 111 }, 112 "periodic": &memdb.IndexSchema{ 113 Name: "periodic", 114 AllowMissing: false, 115 Unique: false, 116 Indexer: &memdb.ConditionalIndex{ 117 Conditional: jobIsPeriodic, 118 }, 119 }, 120 }, 121 } 122 } 123 124 // jobIsGCable satisfies the ConditionalIndexFunc interface and creates an index 125 // on whether a job is eligible for garbage collection. 126 func jobIsGCable(obj interface{}) (bool, error) { 127 j, ok := obj.(*structs.Job) 128 if !ok { 129 return false, fmt.Errorf("Unexpected type: %v", obj) 130 } 131 132 return j.GC, nil 133 } 134 135 // jobIsPeriodic satisfies the ConditionalIndexFunc interface and creates an index 136 // on whether a job is periodic. 137 func jobIsPeriodic(obj interface{}) (bool, error) { 138 j, ok := obj.(*structs.Job) 139 if !ok { 140 return false, fmt.Errorf("Unexpected type: %v", obj) 141 } 142 143 if j.Periodic != nil && j.Periodic.Enabled == true { 144 return true, nil 145 } 146 147 return false, nil 148 } 149 150 // periodicLaunchTableSchema returns the MemDB schema tracking the most recent 151 // launch time for a perioidic job. 152 func periodicLaunchTableSchema() *memdb.TableSchema { 153 return &memdb.TableSchema{ 154 Name: "periodic_launch", 155 Indexes: map[string]*memdb.IndexSchema{ 156 // Primary index is used for job management 157 // and simple direct lookup. ID is required to be 158 // unique. 159 "id": &memdb.IndexSchema{ 160 Name: "id", 161 AllowMissing: false, 162 Unique: true, 163 Indexer: &memdb.StringFieldIndex{ 164 Field: "ID", 165 Lowercase: true, 166 }, 167 }, 168 }, 169 } 170 } 171 172 // evalTableSchema returns the MemDB schema for the eval table. 173 // This table is used to store all the evaluations that are pending 174 // or recently completed. 175 func evalTableSchema() *memdb.TableSchema { 176 return &memdb.TableSchema{ 177 Name: "evals", 178 Indexes: map[string]*memdb.IndexSchema{ 179 // Primary index is used for direct lookup. 180 "id": &memdb.IndexSchema{ 181 Name: "id", 182 AllowMissing: false, 183 Unique: true, 184 Indexer: &memdb.UUIDFieldIndex{ 185 Field: "ID", 186 }, 187 }, 188 189 // Job index is used to lookup allocations by job 190 "job": &memdb.IndexSchema{ 191 Name: "job", 192 AllowMissing: false, 193 Unique: false, 194 Indexer: &memdb.StringFieldIndex{ 195 Field: "JobID", 196 Lowercase: true, 197 }, 198 }, 199 }, 200 } 201 } 202 203 // allocTableSchema returns the MemDB schema for the allocation table. 204 // This table is used to store all the task allocations between task groups 205 // and nodes. 206 func allocTableSchema() *memdb.TableSchema { 207 return &memdb.TableSchema{ 208 Name: "allocs", 209 Indexes: map[string]*memdb.IndexSchema{ 210 // Primary index is a UUID 211 "id": &memdb.IndexSchema{ 212 Name: "id", 213 AllowMissing: false, 214 Unique: true, 215 Indexer: &memdb.UUIDFieldIndex{ 216 Field: "ID", 217 }, 218 }, 219 220 // Node index is used to lookup allocations by node 221 "node": &memdb.IndexSchema{ 222 Name: "node", 223 AllowMissing: true, // Missing is allow for failed allocations 224 Unique: false, 225 Indexer: &memdb.StringFieldIndex{ 226 Field: "NodeID", 227 Lowercase: true, 228 }, 229 }, 230 231 // Job index is used to lookup allocations by job 232 "job": &memdb.IndexSchema{ 233 Name: "job", 234 AllowMissing: false, 235 Unique: false, 236 Indexer: &memdb.StringFieldIndex{ 237 Field: "JobID", 238 Lowercase: true, 239 }, 240 }, 241 242 // Eval index is used to lookup allocations by eval 243 "eval": &memdb.IndexSchema{ 244 Name: "eval", 245 AllowMissing: false, 246 Unique: false, 247 Indexer: &memdb.UUIDFieldIndex{ 248 Field: "EvalID", 249 }, 250 }, 251 }, 252 } 253 }