1 package cache
2
3 import (
4 "context"
5 "time"
6
7 "github.com/LINBIT/golinstor/client"
8 )
9
10
11 type NodeCache struct {
12
13 Timeout time.Duration
14
15 nodeCache cache
16 storagePoolCache cache
17 physicalStorageCache cache
18 }
19
20 func (n *NodeCache) apply(c *client.Client) {
21 c.Nodes = &nodeCacheProvider{
22 cl: c.Nodes,
23 cache: n,
24 }
25 }
26
27 type nodeCacheProvider struct {
28 cl client.NodeProvider
29 cache *NodeCache
30 }
31
32 var _ client.NodeProvider = &nodeCacheProvider{}
33
34 func (n *nodeCacheProvider) GetAll(ctx context.Context, opts ...*client.ListOpts) ([]client.Node, error) {
35 c, err := n.cache.nodeCache.Get(n.cache.Timeout, func() (any, error) {
36 return n.cl.GetAll(ctx, cacheOpt)
37 })
38 if err != nil {
39 return nil, err
40 }
41
42 return filterNodeAndPoolOpts(c.([]client.Node), func(node *client.Node) ([]string, []string) {
43 return []string{node.Name}, nil
44 }, opts...), nil
45 }
46
47 func (n *nodeCacheProvider) Get(ctx context.Context, nodeName string, opts ...*client.ListOpts) (client.Node, error) {
48 nodes, err := n.GetAll(ctx, opts...)
49 if err != nil {
50 return client.Node{}, err
51 }
52
53 for i := range nodes {
54 if nodes[i].Name == nodeName {
55 return nodes[i], nil
56 }
57 }
58
59 return client.Node{}, client.NotFoundError
60 }
61
62 func (n *nodeCacheProvider) Create(ctx context.Context, node client.Node) error {
63 n.cache.nodeCache.Invalidate()
64 return n.cl.Create(ctx, node)
65 }
66
67 func (n *nodeCacheProvider) CreateEbsNode(ctx context.Context, name string, remoteName string) error {
68 n.cache.nodeCache.Invalidate()
69 return n.cl.CreateEbsNode(ctx, name, remoteName)
70 }
71
72 func (n *nodeCacheProvider) Modify(ctx context.Context, nodeName string, props client.NodeModify) error {
73 n.cache.nodeCache.Invalidate()
74 return n.cl.Modify(ctx, nodeName, props)
75 }
76
77 func (n *nodeCacheProvider) Delete(ctx context.Context, nodeName string) error {
78 n.cache.nodeCache.Invalidate()
79 return n.cl.Delete(ctx, nodeName)
80 }
81
82 func (n *nodeCacheProvider) Lost(ctx context.Context, nodeName string) error {
83 n.cache.nodeCache.Invalidate()
84 return n.cl.Lost(ctx, nodeName)
85 }
86
87 func (n *nodeCacheProvider) Reconnect(ctx context.Context, nodeName string) error {
88 n.cache.nodeCache.Invalidate()
89 return n.cl.Reconnect(ctx, nodeName)
90 }
91
92 func (n *nodeCacheProvider) GetNetInterfaces(ctx context.Context, nodeName string, opts ...*client.ListOpts) ([]client.NetInterface, error) {
93 node, err := n.Get(ctx, nodeName, opts...)
94 if err != nil {
95 return nil, err
96 }
97
98 return node.NetInterfaces, nil
99 }
100
101 func (n *nodeCacheProvider) GetNetInterface(ctx context.Context, nodeName, nifName string, opts ...*client.ListOpts) (client.NetInterface, error) {
102 interfaces, err := n.GetNetInterfaces(ctx, nodeName, opts...)
103 if err != nil {
104 return client.NetInterface{}, err
105 }
106
107 for i := range interfaces {
108 if interfaces[i].Name == nifName {
109 return interfaces[i], nil
110 }
111 }
112
113 return client.NetInterface{}, client.NotFoundError
114 }
115
116 func (n *nodeCacheProvider) CreateNetInterface(ctx context.Context, nodeName string, nif client.NetInterface) error {
117 n.cache.nodeCache.Invalidate()
118 return n.cl.CreateNetInterface(ctx, nodeName, nif)
119 }
120
121 func (n *nodeCacheProvider) ModifyNetInterface(ctx context.Context, nodeName, nifName string, nif client.NetInterface) error {
122 n.cache.nodeCache.Invalidate()
123 return n.cl.ModifyNetInterface(ctx, nodeName, nifName, nif)
124 }
125
126 func (n *nodeCacheProvider) DeleteNetinterface(ctx context.Context, nodeName, nifName string) error {
127 n.cache.nodeCache.Invalidate()
128 return n.cl.DeleteNetinterface(ctx, nodeName, nifName)
129 }
130
131 func (n *nodeCacheProvider) Evict(ctx context.Context, nodeName string) error {
132 n.cache.nodeCache.Invalidate()
133 return n.cl.Evict(ctx, nodeName)
134 }
135
136 func (n *nodeCacheProvider) Restore(ctx context.Context, nodeName string, restore client.NodeRestore) error {
137 n.cache.nodeCache.Invalidate()
138 return n.cl.Restore(ctx, nodeName, restore)
139 }
140
141 func (n *nodeCacheProvider) Evacuate(ctx context.Context, nodeName string) error {
142 n.cache.nodeCache.Invalidate()
143 return n.cl.Evacuate(ctx, nodeName)
144 }
145
146 func (n *nodeCacheProvider) GetStoragePoolView(ctx context.Context, opts ...*client.ListOpts) ([]client.StoragePool, error) {
147 result, err := n.cache.storagePoolCache.Get(n.cache.Timeout, func() (any, error) {
148 return n.cl.GetStoragePoolView(ctx, cacheOpt)
149 })
150 if err != nil {
151 return nil, err
152 }
153
154 return filterNodeAndPoolOpts(result.([]client.StoragePool), func(pool *client.StoragePool) ([]string, []string) {
155 return []string{pool.NodeName}, []string{pool.StoragePoolName}
156 }, opts...), nil
157 }
158
159 func (n *nodeCacheProvider) GetStoragePools(ctx context.Context, nodeName string, opts ...*client.ListOpts) ([]client.StoragePool, error) {
160 allPools, err := n.GetStoragePoolView(ctx, opts...)
161 if err != nil {
162 return nil, err
163 }
164
165 var pools []client.StoragePool
166
167 for i := range allPools {
168 if allPools[i].NodeName == nodeName {
169 pools = append(pools, allPools[i])
170 }
171 }
172
173 return pools, nil
174 }
175
176 func (n *nodeCacheProvider) GetStoragePool(ctx context.Context, nodeName, spName string, opts ...*client.ListOpts) (client.StoragePool, error) {
177 pools, err := n.GetStoragePools(ctx, nodeName, opts...)
178 if err != nil {
179 return client.StoragePool{}, err
180 }
181
182 for i := range pools {
183 if pools[i].StoragePoolName == spName {
184 return pools[i], nil
185 }
186 }
187
188 return client.StoragePool{}, client.NotFoundError
189 }
190
191 func (n *nodeCacheProvider) CreateStoragePool(ctx context.Context, nodeName string, sp client.StoragePool) error {
192 n.cache.storagePoolCache.Invalidate()
193 return n.cl.CreateStoragePool(ctx, nodeName, sp)
194 }
195
196 func (n *nodeCacheProvider) ModifyStoragePool(ctx context.Context, nodeName, spName string, genericProps client.GenericPropsModify) error {
197 n.cache.storagePoolCache.Invalidate()
198 return n.cl.ModifyStoragePool(ctx, nodeName, spName, genericProps)
199 }
200
201 func (n *nodeCacheProvider) DeleteStoragePool(ctx context.Context, nodeName, spName string) error {
202 n.cache.storagePoolCache.Invalidate()
203 return n.cl.DeleteStoragePool(ctx, nodeName, spName)
204 }
205
206 func (n *nodeCacheProvider) GetPhysicalStorageView(ctx context.Context, opts ...*client.ListOpts) ([]client.PhysicalStorageViewItem, error) {
207 result, err := n.cache.physicalStorageCache.Get(n.cache.Timeout, func() (any, error) {
208 return n.cl.GetPhysicalStorageView(ctx, cacheOpt)
209 })
210 if err != nil {
211 return nil, err
212 }
213
214 return filterNodeAndPoolOpts(result.([]client.PhysicalStorageViewItem), func(item *client.PhysicalStorageViewItem) ([]string, []string) {
215 var nodes []string
216 for k := range item.Nodes {
217 nodes = append(nodes, k)
218 }
219 return nodes, nil
220 }, opts...), nil
221 }
222
223 func (n *nodeCacheProvider) GetPhysicalStorage(ctx context.Context, nodeName string) ([]client.PhysicalStorageNode, error) {
224 view, err := n.GetPhysicalStorageView(ctx)
225 if err != nil {
226 return nil, err
227 }
228
229 var result []client.PhysicalStorageNode
230 for i := range view {
231 for j := range view[i].Nodes[nodeName] {
232 result = append(result, client.PhysicalStorageNode{
233 Rotational: view[i].Rotational,
234 Size: view[i].Size,
235 PhysicalStorageDevice: view[i].Nodes[nodeName][j],
236 })
237 }
238 }
239
240 return result, nil
241 }
242
243 func (n *nodeCacheProvider) CreateDevicePool(ctx context.Context, nodeName string, psc client.PhysicalStorageCreate) error {
244 n.cache.physicalStorageCache.Invalidate()
245 return n.cl.CreateDevicePool(ctx, nodeName, psc)
246 }
247
248 func (n *nodeCacheProvider) GetStoragePoolPropsInfos(ctx context.Context, nodeName string, opts ...*client.ListOpts) ([]client.PropsInfo, error) {
249 return n.cl.GetStoragePoolPropsInfos(ctx, nodeName, opts...)
250 }
251
252 func (n *nodeCacheProvider) GetPropsInfos(ctx context.Context, opts ...*client.ListOpts) ([]client.PropsInfo, error) {
253 return n.cl.GetPropsInfos(ctx, opts...)
254 }
255
View as plain text