Skip to content
This repository was archived by the owner on Jun 23, 2020. It is now read-only.

Commit a2fe516

Browse files
Merge pull request #46 from oracle/gb-nodename-cache
Add a cache to the nodename to instance lookup and also filter on VCN
2 parents 1d8e8ff + eb05a93 commit a2fe516

File tree

5 files changed

+319
-8
lines changed

5 files changed

+319
-8
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ auth:
8989
<snip>
9090
-----END RSA PRIVATE KEY-----
9191
fingerprint: d4:1d:8c:d9:8f:00:b2:04:e9:80:09:98:ec:f8:42:7e
92+
vcn: ocid1.vcn.oc1.phx.aaaaaaaaqiqmei4yen2fuyqaiqfcejpguqs6tuaf2n2iaxiwf5cfji2s636a
9293
```
9394
9495
If `"region"` and/or `"compartment"` are not specified in the config file

pkg/oci/client/cache/ocicache.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2017 Oracle and/or its affiliates. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cache
16+
17+
import (
18+
"encoding/json"
19+
"log"
20+
"os"
21+
"syscall"
22+
23+
baremetal "github.com/oracle/bmcs-go-sdk"
24+
)
25+
26+
type OCICache struct {
27+
vnics map[string]baremetal.Vnic
28+
file *os.File
29+
filename string
30+
}
31+
32+
// Open opens the cache and returns the cache handle
33+
func Open(filename string) (*OCICache, error) {
34+
file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0644)
35+
if err != nil {
36+
log.Printf("Failed to open cache: %v", err)
37+
return nil, err
38+
}
39+
40+
if err := syscall.Flock(int(file.Fd()), syscall.LOCK_EX); err != nil {
41+
log.Printf("Failed to lock cache: %v", err)
42+
return nil, err
43+
}
44+
var vnicCache = map[string]baremetal.Vnic{}
45+
decoder := json.NewDecoder(file)
46+
err = decoder.Decode(&vnicCache)
47+
if err != nil {
48+
log.Printf("Failed to decode cache: %v", err)
49+
}
50+
return &OCICache{file: file, vnics: vnicCache, filename: filename}, nil
51+
}
52+
53+
// GetVnic looks up the vnic id in the cache
54+
func (nc *OCICache) GetVnic(id string) (*baremetal.Vnic, bool) {
55+
value, ok := nc.vnics[id]
56+
return &value, ok
57+
}
58+
59+
// SetVnic adds a vnic to the cache
60+
func (nc *OCICache) SetVnic(id string, value *baremetal.Vnic) {
61+
nc.vnics[id] = *value
62+
}
63+
64+
// Close closes the vnic cache saving to disk and unlocking the file
65+
func (nc *OCICache) Close() error {
66+
if nc.file != nil {
67+
defer func() {
68+
nc.file.Close()
69+
nc.file = nil
70+
71+
}()
72+
_, err := nc.file.Seek(0, 0)
73+
if err != nil {
74+
log.Printf("Error marshalling OCICache to JSON: %v", err)
75+
return err
76+
}
77+
78+
encoder := json.NewEncoder(nc.file)
79+
err = encoder.Encode(&nc.vnics)
80+
if err != nil {
81+
log.Printf("Error marshalling OCICache to JSON: %v", err)
82+
return err
83+
}
84+
85+
if err := syscall.Flock(int(nc.file.Fd()), syscall.LOCK_UN); err != nil {
86+
log.Printf("Error marshalling OCICache to JSON: %v", err)
87+
return err
88+
}
89+
}
90+
return nil
91+
}

pkg/oci/client/cache/ocicache_test.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright 2017 Oracle and/or its affiliates. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cache
16+
17+
import (
18+
"encoding/hex"
19+
"math/rand"
20+
"os"
21+
"path/filepath"
22+
"testing"
23+
24+
baremetal "github.com/oracle/bmcs-go-sdk"
25+
)
26+
27+
func TempFileName(prefix, suffix string) string {
28+
randBytes := make([]byte, 16)
29+
rand.Read(randBytes)
30+
return filepath.Join(os.TempDir(), prefix+hex.EncodeToString(randBytes)+suffix)
31+
}
32+
33+
func TestCache(t *testing.T) {
34+
cacheName := TempFileName("/tmp", "TestCache.json")
35+
t.Logf("Testcache: %s", cacheName)
36+
cache, err := Open(cacheName)
37+
if err != nil {
38+
t.Error(err)
39+
}
40+
defer cache.Close()
41+
42+
var testVnic = baremetal.Vnic{ID: "test"}
43+
cache.SetVnic("test", &testVnic)
44+
value, ok := cache.GetVnic("test")
45+
if !ok {
46+
t.Error("test not found")
47+
}
48+
if *value != testVnic {
49+
t.Error("Key not equal to test")
50+
}
51+
err = cache.Close()
52+
if err != nil {
53+
t.Error(err)
54+
}
55+
}
56+
57+
func TestCacheMultipleClose(t *testing.T) {
58+
cacheName := TempFileName("/tmp", "TestCache.json")
59+
t.Logf("Testcache: %s", cacheName)
60+
cache, err := Open(cacheName)
61+
if err != nil {
62+
t.Error(err)
63+
}
64+
65+
err = cache.Close()
66+
if err != nil {
67+
t.Error(err)
68+
}
69+
err = cache.Close()
70+
if err != nil {
71+
t.Error(err)
72+
}
73+
}
74+
75+
func TestCacheLoadSave(t *testing.T) {
76+
cacheName := TempFileName("/tmp", "TestCache.json")
77+
t.Logf("Testcache: %s", cacheName)
78+
firstCache, err := Open(cacheName)
79+
if err != nil {
80+
t.Error(err)
81+
}
82+
defer firstCache.Close()
83+
var testVnic = baremetal.Vnic{ID: "test"}
84+
firstCache.SetVnic("test", &testVnic)
85+
value, ok := firstCache.GetVnic("test")
86+
if !ok {
87+
t.Error("test not found")
88+
}
89+
if *value != testVnic {
90+
t.Error("Key not equal to test")
91+
}
92+
err = firstCache.Close()
93+
if err != nil {
94+
t.Error(err)
95+
}
96+
otherCache, err := Open(cacheName)
97+
if err != nil {
98+
t.Error(err)
99+
}
100+
value, ok = otherCache.GetVnic("test")
101+
if !ok {
102+
t.Error("test not found")
103+
}
104+
if *value != testVnic {
105+
t.Error("Key not equal to test")
106+
}
107+
err = otherCache.Close()
108+
if err != nil {
109+
t.Error(err)
110+
}
111+
}
112+
113+
func TestCacheParallel(t *testing.T) {
114+
cacheName := TempFileName("/tmp", "TestCache.json")
115+
t.Logf("Testcache: %s", cacheName)
116+
use := func() {
117+
cache, err := Open(cacheName)
118+
if err != nil {
119+
t.Error(err)
120+
}
121+
defer cache.Close()
122+
var testVnic = baremetal.Vnic{ID: "test"}
123+
cache.SetVnic("test", &testVnic)
124+
value, ok := cache.GetVnic("test")
125+
if !ok {
126+
t.Error("test not found")
127+
}
128+
if *value != testVnic {
129+
t.Error("Key not equal to test")
130+
}
131+
err = cache.Close()
132+
if err != nil {
133+
t.Error(err)
134+
}
135+
}
136+
137+
for i := 0; i < 4000; i++ {
138+
go use()
139+
}
140+
}

pkg/oci/client/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ type AuthConfig struct {
4444
UserOCID string `yaml:"user"`
4545
PrivateKey string `yaml:"key"`
4646
Fingerprint string `yaml:"fingerprint"`
47+
VcnOCID string `yaml:"vcn"`
4748
}
4849

4950
// Config holds the configuration for the OCI flexvolume driver.

0 commit comments

Comments
 (0)