store.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package ipam
  2. import (
  3. "encoding/json"
  4. "github.com/Sirupsen/logrus"
  5. "github.com/docker/libnetwork/datastore"
  6. "github.com/docker/libnetwork/types"
  7. )
  8. // Key provides the Key to be used in KV Store
  9. func (aSpace *addrSpace) Key() []string {
  10. aSpace.Lock()
  11. defer aSpace.Unlock()
  12. return []string{aSpace.id}
  13. }
  14. // KeyPrefix returns the immediate parent key that can be used for tree walk
  15. func (aSpace *addrSpace) KeyPrefix() []string {
  16. aSpace.Lock()
  17. defer aSpace.Unlock()
  18. return []string{dsConfigKey}
  19. }
  20. // Value marshals the data to be stored in the KV store
  21. func (aSpace *addrSpace) Value() []byte {
  22. b, err := json.Marshal(aSpace)
  23. if err != nil {
  24. logrus.Warnf("Failed to marshal ipam configured pools: %v", err)
  25. return nil
  26. }
  27. return b
  28. }
  29. // SetValue unmarshalls the data from the KV store.
  30. func (aSpace *addrSpace) SetValue(value []byte) error {
  31. rc := &addrSpace{subnets: make(map[SubnetKey]*PoolData)}
  32. if err := json.Unmarshal(value, rc); err != nil {
  33. return err
  34. }
  35. aSpace.subnets = rc.subnets
  36. return nil
  37. }
  38. // Index returns the latest DB Index as seen by this object
  39. func (aSpace *addrSpace) Index() uint64 {
  40. aSpace.Lock()
  41. defer aSpace.Unlock()
  42. return aSpace.dbIndex
  43. }
  44. // SetIndex method allows the datastore to store the latest DB Index into this object
  45. func (aSpace *addrSpace) SetIndex(index uint64) {
  46. aSpace.Lock()
  47. aSpace.dbIndex = index
  48. aSpace.dbExists = true
  49. aSpace.Unlock()
  50. }
  51. // Exists method is true if this object has been stored in the DB.
  52. func (aSpace *addrSpace) Exists() bool {
  53. aSpace.Lock()
  54. defer aSpace.Unlock()
  55. return aSpace.dbExists
  56. }
  57. // Skip provides a way for a KV Object to avoid persisting it in the KV Store
  58. func (aSpace *addrSpace) Skip() bool {
  59. return false
  60. }
  61. func (a *Allocator) getStore(as string) datastore.DataStore {
  62. a.Lock()
  63. defer a.Unlock()
  64. if aSpace, ok := a.addrSpaces[as]; ok {
  65. return aSpace.ds
  66. }
  67. return nil
  68. }
  69. func (a *Allocator) getAddressSpaceFromStore(as string) (*addrSpace, error) {
  70. store := a.getStore(as)
  71. // IPAM may not have a valid store. In such cases it is just in-memory state.
  72. if store == nil {
  73. return nil, nil
  74. }
  75. pc := &addrSpace{id: dsConfigKey + "/" + as, ds: store, alloc: a}
  76. if err := store.GetObject(datastore.Key(pc.Key()...), pc); err != nil {
  77. if err == datastore.ErrKeyNotFound {
  78. return nil, nil
  79. }
  80. return nil, types.InternalErrorf("could not get pools config from store: %v", err)
  81. }
  82. return pc, nil
  83. }
  84. func (a *Allocator) writeToStore(aSpace *addrSpace) error {
  85. store := aSpace.store()
  86. // IPAM may not have a valid store. In such cases it is just in-memory state.
  87. if store == nil {
  88. return nil
  89. }
  90. err := store.PutObjectAtomic(aSpace)
  91. if err == datastore.ErrKeyModified {
  92. return types.RetryErrorf("failed to perform atomic write (%v). retry might fix the error", err)
  93. }
  94. return err
  95. }
  96. func (a *Allocator) deleteFromStore(aSpace *addrSpace) error {
  97. store := aSpace.store()
  98. // IPAM may not have a valid store. In such cases it is just in-memory state.
  99. if store == nil {
  100. return nil
  101. }
  102. return store.DeleteObjectAtomic(aSpace)
  103. }
  104. // DataScope method returns the storage scope of the datastore
  105. func (aSpace *addrSpace) DataScope() string {
  106. aSpace.Lock()
  107. defer aSpace.Unlock()
  108. return aSpace.scope
  109. }