123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- package store
- import (
- "strconv"
- "strings"
- "github.com/docker/swarmkit/api"
- memdb "github.com/hashicorp/go-memdb"
- )
- const tableNode = "node"
- func init() {
- register(ObjectStoreConfig{
- Table: &memdb.TableSchema{
- Name: tableNode,
- Indexes: map[string]*memdb.IndexSchema{
- indexID: {
- Name: indexID,
- Unique: true,
- Indexer: api.NodeIndexerByID{},
- },
- // TODO(aluzzardi): Use `indexHostname` instead.
- indexName: {
- Name: indexName,
- AllowMissing: true,
- Indexer: nodeIndexerByHostname{},
- },
- indexRole: {
- Name: indexRole,
- Indexer: nodeIndexerByRole{},
- },
- indexMembership: {
- Name: indexMembership,
- Indexer: nodeIndexerByMembership{},
- },
- indexCustom: {
- Name: indexCustom,
- Indexer: api.NodeCustomIndexer{},
- AllowMissing: true,
- },
- },
- },
- Save: func(tx ReadTx, snapshot *api.StoreSnapshot) error {
- var err error
- snapshot.Nodes, err = FindNodes(tx, All)
- return err
- },
- Restore: func(tx Tx, snapshot *api.StoreSnapshot) error {
- nodes, err := FindNodes(tx, All)
- if err != nil {
- return err
- }
- for _, n := range nodes {
- if err := DeleteNode(tx, n.ID); err != nil {
- return err
- }
- }
- for _, n := range snapshot.Nodes {
- if err := CreateNode(tx, n); err != nil {
- return err
- }
- }
- return nil
- },
- ApplyStoreAction: func(tx Tx, sa api.StoreAction) error {
- switch v := sa.Target.(type) {
- case *api.StoreAction_Node:
- obj := v.Node
- switch sa.Action {
- case api.StoreActionKindCreate:
- return CreateNode(tx, obj)
- case api.StoreActionKindUpdate:
- return UpdateNode(tx, obj)
- case api.StoreActionKindRemove:
- return DeleteNode(tx, obj.ID)
- }
- }
- return errUnknownStoreAction
- },
- })
- }
- // CreateNode adds a new node to the store.
- // Returns ErrExist if the ID is already taken.
- func CreateNode(tx Tx, n *api.Node) error {
- return tx.create(tableNode, n)
- }
- // UpdateNode updates an existing node in the store.
- // Returns ErrNotExist if the node doesn't exist.
- func UpdateNode(tx Tx, n *api.Node) error {
- return tx.update(tableNode, n)
- }
- // DeleteNode removes a node from the store.
- // Returns ErrNotExist if the node doesn't exist.
- func DeleteNode(tx Tx, id string) error {
- return tx.delete(tableNode, id)
- }
- // GetNode looks up a node by ID.
- // Returns nil if the node doesn't exist.
- func GetNode(tx ReadTx, id string) *api.Node {
- n := tx.get(tableNode, id)
- if n == nil {
- return nil
- }
- return n.(*api.Node)
- }
- // FindNodes selects a set of nodes and returns them.
- func FindNodes(tx ReadTx, by By) ([]*api.Node, error) {
- checkType := func(by By) error {
- switch by.(type) {
- case byName, byNamePrefix, byIDPrefix, byRole, byMembership, byCustom, byCustomPrefix:
- return nil
- default:
- return ErrInvalidFindBy
- }
- }
- nodeList := []*api.Node{}
- appendResult := func(o api.StoreObject) {
- nodeList = append(nodeList, o.(*api.Node))
- }
- err := tx.find(tableNode, by, checkType, appendResult)
- return nodeList, err
- }
- type nodeIndexerByHostname struct{}
- func (ni nodeIndexerByHostname) FromArgs(args ...interface{}) ([]byte, error) {
- return fromArgs(args...)
- }
- func (ni nodeIndexerByHostname) FromObject(obj interface{}) (bool, []byte, error) {
- n := obj.(*api.Node)
- if n.Description == nil {
- return false, nil, nil
- }
- // Add the null character as a terminator
- return true, []byte(strings.ToLower(n.Description.Hostname) + "\x00"), nil
- }
- func (ni nodeIndexerByHostname) PrefixFromArgs(args ...interface{}) ([]byte, error) {
- return prefixFromArgs(args...)
- }
- type nodeIndexerByRole struct{}
- func (ni nodeIndexerByRole) FromArgs(args ...interface{}) ([]byte, error) {
- return fromArgs(args...)
- }
- func (ni nodeIndexerByRole) FromObject(obj interface{}) (bool, []byte, error) {
- n := obj.(*api.Node)
- // Add the null character as a terminator
- return true, []byte(strconv.FormatInt(int64(n.Role), 10) + "\x00"), nil
- }
- type nodeIndexerByMembership struct{}
- func (ni nodeIndexerByMembership) FromArgs(args ...interface{}) ([]byte, error) {
- return fromArgs(args...)
- }
- func (ni nodeIndexerByMembership) FromObject(obj interface{}) (bool, []byte, error) {
- n := obj.(*api.Node)
- // Add the null character as a terminator
- return true, []byte(strconv.FormatInt(int64(n.Spec.Membership), 10) + "\x00"), nil
- }
|