/
allregistries.go
155 lines (137 loc) · 4.52 KB
/
allregistries.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package manager
import (
"net/url"
"path"
"path/filepath"
"runtime"
"sync"
"time"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
// AllRegistries contains a list of added registries using their hostnames
// access granted via mutex locks/unlocks
var AllRegistries Registries
func init() {
AllRegistries.Registries = map[string]*Registry{}
go func() {
for {
AllRegistries.Lock()
for _, r := range AllRegistries.Registries {
if time.Now().UTC().Sub(r.LastRefresh) >= r.TTL {
ur := r.Update()
AllRegistries.Registries[r.Name] = &ur
}
}
AllRegistries.Unlock()
time.Sleep(1 * time.Second)
}
}()
}
// Registries contains a map of all active registries identified by their name, locked when necessary
type Registries struct {
Registries map[string]*Registry
*viper.Viper
sync.RWMutex
}
// Add adds a created registry to the map of AllRegistries using the corresponding locks
func (rs *Registries) Add(r *Registry) {
AllRegistries.Lock()
AllRegistries.Registries[r.Name] = r
AllRegistries.Unlock()
logrus.Infof("Added new registry: %s", r.Name)
}
// Remove removes a created registry from the map of AllRegistries using the corresponding locks
func (rs *Registries) Remove(r *Registry) {
AllRegistries.Lock()
delete(AllRegistries.Registries, r.Name)
AllRegistries.Unlock()
logrus.Infof("Removed registry: %s", r.Name)
}
// Edit updates the old registry with the new data
func (rs *Registries) Edit(new, old *Registry) {
AllRegistries.Lock()
delete(AllRegistries.Registries, old.Name)
// copy the history
new.History = old.History
AllRegistries.Registries[new.Name] = new
AllRegistries.Unlock()
logrus.Infof("Edited registry: %s", old.Name)
}
type registriesConfig struct {
URL string
Port int
Username string
Password string
SkipTLS bool `mapstructure:"skip-tls-validation" yaml:"skip-tls-validation"`
RefreshRate string `mapstructure:"refresh-rate" yaml:"refresh-rate"`
DockerhubIntegration bool `mapstructure:"dockerhub-integration" yaml:"dockerhub-integration"`
}
// LoadConfig adds the registries parsed from the passed yaml file
func (rs *Registries) LoadConfig(registriesFile string) {
if rs.Viper == nil {
rs.Viper = viper.New()
}
// If the registries path is not passed use the default project dir
if registriesFile != "" {
rs.AddConfigPath(path.Dir(registriesFile))
base := path.Base(registriesFile)
ext := path.Ext(registriesFile)
rs.SetConfigName(base[0 : len(base)-len(ext)])
logrus.Infof("Using registries located in %s with file name %s", path.Dir(registriesFile), base[0:len(base)-len(ext)])
} else {
rs.SetConfigName("registries")
var root string
_, run, _, ok := runtime.Caller(0)
if ok {
root = filepath.Dir(run)
rs.AddConfigPath(root)
} else {
logrus.Fatalf("Failed to get runtime caller for parser")
}
logrus.Infof("Using registries located in %s with file name %s", root, "registries.yml")
}
config := make(map[string]map[string]registriesConfig)
if err := rs.ReadInConfig(); err != nil {
logrus.Fatalf("Failed to read in registries file: %s", err)
}
if err := rs.Unmarshal(&config); err != nil {
logrus.Fatalf("Unable to unmarshal registries file: %s", err)
}
// overwrite the entries with the updated information
for name, r := range config["registries"] {
if r.URL != "" {
url, err := url.Parse(r.URL)
if err != nil {
logrus.Fatalf("Failed to parse registry from the passed url (%s): %s", r.URL, err)
}
duration, err := time.ParseDuration(r.RefreshRate)
if err != nil {
logrus.Fatalf("Failed to add registry (%s), invalid duration: %s", r.URL, err)
}
new, err := NewRegistry(url.Scheme, url.Hostname(), name, r.Username, r.Password, r.Port, duration, r.SkipTLS, r.DockerhubIntegration)
if err != nil {
logrus.Fatalf("Failed to create registry (%s): %s", r.URL, err)
}
AllRegistries.Add(new)
}
}
}
// WriteConfig builds the config and writes from the map of registries
func (rs *Registries) WriteConfig() error {
config := make(map[string]registriesConfig)
for name, r := range AllRegistries.Registries {
config[name] = registriesConfig{
URL: r.URL,
Port: r.Port,
Username: r.Username,
Password: r.Password,
SkipTLS: r.SkipTLS,
RefreshRate: r.TTL.String(),
DockerhubIntegration: r.DockerhubIntegration,
}
}
rs.Set("registries", config)
logrus.Info("Writing config with new/removed registries")
return rs.Viper.WriteConfig()
}