github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/manager/state/store/nodes.go (about) 1 package store 2 3 import ( 4 "strconv" 5 "strings" 6 7 "github.com/docker/swarmkit/api" 8 memdb "github.com/hashicorp/go-memdb" 9 ) 10 11 const tableNode = "node" 12 13 func init() { 14 register(ObjectStoreConfig{ 15 Table: &memdb.TableSchema{ 16 Name: tableNode, 17 Indexes: map[string]*memdb.IndexSchema{ 18 indexID: { 19 Name: indexID, 20 Unique: true, 21 Indexer: api.NodeIndexerByID{}, 22 }, 23 // TODO(aluzzardi): Use `indexHostname` instead. 24 indexName: { 25 Name: indexName, 26 AllowMissing: true, 27 Indexer: nodeIndexerByHostname{}, 28 }, 29 indexRole: { 30 Name: indexRole, 31 Indexer: nodeIndexerByRole{}, 32 }, 33 indexMembership: { 34 Name: indexMembership, 35 Indexer: nodeIndexerByMembership{}, 36 }, 37 indexCustom: { 38 Name: indexCustom, 39 Indexer: api.NodeCustomIndexer{}, 40 AllowMissing: true, 41 }, 42 }, 43 }, 44 Save: func(tx ReadTx, snapshot *api.StoreSnapshot) error { 45 var err error 46 snapshot.Nodes, err = FindNodes(tx, All) 47 return err 48 }, 49 Restore: func(tx Tx, snapshot *api.StoreSnapshot) error { 50 toStoreObj := make([]api.StoreObject, len(snapshot.Nodes)) 51 for i, x := range snapshot.Nodes { 52 toStoreObj[i] = x 53 } 54 return RestoreTable(tx, tableNode, toStoreObj) 55 }, 56 ApplyStoreAction: func(tx Tx, sa api.StoreAction) error { 57 switch v := sa.Target.(type) { 58 case *api.StoreAction_Node: 59 obj := v.Node 60 switch sa.Action { 61 case api.StoreActionKindCreate: 62 return CreateNode(tx, obj) 63 case api.StoreActionKindUpdate: 64 return UpdateNode(tx, obj) 65 case api.StoreActionKindRemove: 66 return DeleteNode(tx, obj.ID) 67 } 68 } 69 return errUnknownStoreAction 70 }, 71 }) 72 } 73 74 // CreateNode adds a new node to the store. 75 // Returns ErrExist if the ID is already taken. 76 func CreateNode(tx Tx, n *api.Node) error { 77 return tx.create(tableNode, n) 78 } 79 80 // UpdateNode updates an existing node in the store. 81 // Returns ErrNotExist if the node doesn't exist. 82 func UpdateNode(tx Tx, n *api.Node) error { 83 return tx.update(tableNode, n) 84 } 85 86 // DeleteNode removes a node from the store. 87 // Returns ErrNotExist if the node doesn't exist. 88 func DeleteNode(tx Tx, id string) error { 89 return tx.delete(tableNode, id) 90 } 91 92 // GetNode looks up a node by ID. 93 // Returns nil if the node doesn't exist. 94 func GetNode(tx ReadTx, id string) *api.Node { 95 n := tx.get(tableNode, id) 96 if n == nil { 97 return nil 98 } 99 return n.(*api.Node) 100 } 101 102 // FindNodes selects a set of nodes and returns them. 103 func FindNodes(tx ReadTx, by By) ([]*api.Node, error) { 104 checkType := func(by By) error { 105 switch by.(type) { 106 case byName, byNamePrefix, byIDPrefix, byRole, byMembership, byCustom, byCustomPrefix: 107 return nil 108 default: 109 return ErrInvalidFindBy 110 } 111 } 112 113 nodeList := []*api.Node{} 114 appendResult := func(o api.StoreObject) { 115 nodeList = append(nodeList, o.(*api.Node)) 116 } 117 118 err := tx.find(tableNode, by, checkType, appendResult) 119 return nodeList, err 120 } 121 122 type nodeIndexerByHostname struct{} 123 124 func (ni nodeIndexerByHostname) FromArgs(args ...interface{}) ([]byte, error) { 125 return fromArgs(args...) 126 } 127 128 func (ni nodeIndexerByHostname) FromObject(obj interface{}) (bool, []byte, error) { 129 n := obj.(*api.Node) 130 131 if n.Description == nil { 132 return false, nil, nil 133 } 134 // Add the null character as a terminator 135 return true, []byte(strings.ToLower(n.Description.Hostname) + "\x00"), nil 136 } 137 138 func (ni nodeIndexerByHostname) PrefixFromArgs(args ...interface{}) ([]byte, error) { 139 return prefixFromArgs(args...) 140 } 141 142 type nodeIndexerByRole struct{} 143 144 func (ni nodeIndexerByRole) FromArgs(args ...interface{}) ([]byte, error) { 145 return fromArgs(args...) 146 } 147 148 func (ni nodeIndexerByRole) FromObject(obj interface{}) (bool, []byte, error) { 149 n := obj.(*api.Node) 150 151 // Add the null character as a terminator 152 return true, []byte(strconv.FormatInt(int64(n.Role), 10) + "\x00"), nil 153 } 154 155 type nodeIndexerByMembership struct{} 156 157 func (ni nodeIndexerByMembership) FromArgs(args ...interface{}) ([]byte, error) { 158 return fromArgs(args...) 159 } 160 161 func (ni nodeIndexerByMembership) FromObject(obj interface{}) (bool, []byte, error) { 162 n := obj.(*api.Node) 163 164 // Add the null character as a terminator 165 return true, []byte(strconv.FormatInt(int64(n.Spec.Membership), 10) + "\x00"), nil 166 }