-
Notifications
You must be signed in to change notification settings - Fork 1
/
repository_file.go
127 lines (101 loc) · 2.58 KB
/
repository_file.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package config
import (
"fmt"
"os"
"sync"
"github.com/fsnotify/fsnotify"
config_api "github.com/safedep/gateway/services/gen"
"github.com/safedep/gateway/services/pkg/common/logger"
"github.com/safedep/gateway/services/pkg/common/utils"
)
type configFileRepository struct {
path string
gatewayConfiguration *config_api.GatewayConfiguration
m sync.RWMutex
}
func NewConfigFileRepository(path string, lazy bool, monitorForChange bool) (ConfigRepository, error) {
r := &configFileRepository{path: path}
var err error
if !lazy {
err = r.load()
}
if err == nil && monitorForChange {
err = r.monitorForChange()
}
return r, err
}
func (c *configFileRepository) LoadGatewayConfiguration() (*config_api.GatewayConfiguration, error) {
var err error = nil
if c.gatewayConfiguration == nil {
_ = c.load()
}
if c.gatewayConfiguration == nil {
err = fmt.Errorf("gateway configuration is not loaded")
}
c.m.RLock()
defer c.m.RUnlock()
return c.gatewayConfiguration, err
}
func (c *configFileRepository) SaveGatewayConfiguration(config *config_api.GatewayConfiguration) error {
return fmt.Errorf("persisting gateway configuration is not supported")
}
func (c *configFileRepository) load() error {
file, err := os.Open(c.path)
if err != nil {
return err
}
defer file.Close()
var gatewayConfiguration config_api.GatewayConfiguration
err = utils.FromPbJson(file, &gatewayConfiguration)
if err != nil {
return err
}
err = gatewayConfiguration.Validate()
if err != nil {
return err
}
c.m.Lock()
defer c.m.Unlock()
c.gatewayConfiguration = &gatewayConfiguration
return nil
}
func (c *configFileRepository) monitorForChange() error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return err
}
// We are OK to leak the goroutine as the watcher will
// never terminate
wcb := func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
logger.Errorf("Failed to read from events channel")
return
}
if event.Has(fsnotify.Write) {
logger.Debugf("Detected changes in configuration file")
err := c.load()
if err != nil {
logger.Errorf("Failed to reload config: %v", err)
} else {
logger.Debugf("Successfully reloaded gateway config")
}
}
case err, ok := <-watcher.Errors:
if !ok {
logger.Errorf("Failed to read from errors channel")
return
}
logger.Errorf("Watcher returned error: %v", err)
}
}
}
err = watcher.Add(c.path)
if err == nil {
go wcb()
}
logger.Debugf("Watcher initialized with error: %v", err)
return err
}