github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/nomad/state/autopilot.go (about) 1 package state 2 3 import ( 4 "fmt" 5 6 memdb "github.com/hashicorp/go-memdb" 7 "github.com/hashicorp/nomad/nomad/structs" 8 ) 9 10 // autopilotConfigTableSchema returns a new table schema used for storing 11 // the autopilot configuration 12 func autopilotConfigTableSchema() *memdb.TableSchema { 13 return &memdb.TableSchema{ 14 Name: "autopilot-config", 15 Indexes: map[string]*memdb.IndexSchema{ 16 "id": { 17 Name: "id", 18 AllowMissing: true, 19 Unique: true, 20 Indexer: &memdb.ConditionalIndex{ 21 Conditional: func(obj interface{}) (bool, error) { return true, nil }, 22 }, 23 }, 24 }, 25 } 26 } 27 28 // AutopilotConfig is used to get the current Autopilot configuration. 29 func (s *StateStore) AutopilotConfig() (uint64, *structs.AutopilotConfig, error) { 30 tx := s.db.Txn(false) 31 defer tx.Abort() 32 33 // Get the autopilot config 34 c, err := tx.First("autopilot-config", "id") 35 if err != nil { 36 return 0, nil, fmt.Errorf("failed autopilot config lookup: %s", err) 37 } 38 39 config, ok := c.(*structs.AutopilotConfig) 40 if !ok { 41 return 0, nil, nil 42 } 43 44 return config.ModifyIndex, config, nil 45 } 46 47 // AutopilotSetConfig is used to set the current Autopilot configuration. 48 func (s *StateStore) AutopilotSetConfig(idx uint64, config *structs.AutopilotConfig) error { 49 tx := s.db.Txn(true) 50 defer tx.Abort() 51 52 s.autopilotSetConfigTxn(idx, tx, config) 53 54 tx.Commit() 55 return nil 56 } 57 58 // AutopilotCASConfig is used to try updating the Autopilot configuration with a 59 // given Raft index. If the CAS index specified is not equal to the last observed index 60 // for the config, then the call is a noop, 61 func (s *StateStore) AutopilotCASConfig(idx, cidx uint64, config *structs.AutopilotConfig) (bool, error) { 62 tx := s.db.Txn(true) 63 defer tx.Abort() 64 65 // Check for an existing config 66 existing, err := tx.First("autopilot-config", "id") 67 if err != nil { 68 return false, fmt.Errorf("failed autopilot config lookup: %s", err) 69 } 70 71 // If the existing index does not match the provided CAS 72 // index arg, then we shouldn't update anything and can safely 73 // return early here. 74 e, ok := existing.(*structs.AutopilotConfig) 75 if !ok || e.ModifyIndex != cidx { 76 return false, nil 77 } 78 79 s.autopilotSetConfigTxn(idx, tx, config) 80 81 tx.Commit() 82 return true, nil 83 } 84 85 func (s *StateStore) autopilotSetConfigTxn(idx uint64, tx *memdb.Txn, config *structs.AutopilotConfig) error { 86 // Check for an existing config 87 existing, err := tx.First("autopilot-config", "id") 88 if err != nil { 89 return fmt.Errorf("failed autopilot config lookup: %s", err) 90 } 91 92 // Set the indexes. 93 if existing != nil { 94 config.CreateIndex = existing.(*structs.AutopilotConfig).CreateIndex 95 } else { 96 config.CreateIndex = idx 97 } 98 config.ModifyIndex = idx 99 100 if err := tx.Insert("autopilot-config", config); err != nil { 101 return fmt.Errorf("failed updating autopilot config: %s", err) 102 } 103 return nil 104 }