-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathdaemonconfig.go
192 lines (166 loc) · 6.05 KB
/
daemonconfig.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
* Copyright (c) 2020. Ant Group. All rights reserved.
* Copyright (c) 2022. Nydus Developers. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
package daemonconfig
import (
"encoding/json"
"os"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
"github.com/containerd/nydus-snapshotter/config"
"github.com/containerd/nydus-snapshotter/pkg/auth"
"github.com/containerd/nydus-snapshotter/pkg/utils/registry"
)
type StorageBackendType = string
const (
backendTypeLocalfs StorageBackendType = "localfs"
backendTypeOss StorageBackendType = "oss"
backendTypeRegistry StorageBackendType = "registry"
)
type DaemonConfig interface {
// Provide stuffs relevant to accessing registry apart from auth
Supplement(host, repo, snapshotID string, params map[string]string)
// Provide auth
FillAuth(kc *auth.PassKeyChain)
StorageBackend() (StorageBackendType, *BackendConfig)
UpdateMirrors(mirrorsConfigDir, registryHost string) error
DumpString() (string, error)
DumpFile(path string) error
}
// Daemon configurations factory
func NewDaemonConfig(fsDriver, path string) (DaemonConfig, error) {
switch fsDriver {
case config.FsDriverFscache:
cfg, err := LoadFscacheConfig(path)
if err != nil {
return nil, err
}
return cfg, nil
case config.FsDriverFusedev:
cfg, err := LoadFuseConfig(path)
if err != nil {
return nil, err
}
return cfg, nil
default:
return nil, errors.Errorf("unsupported, fs driver %q", fsDriver)
}
}
type MirrorConfig struct {
Host string `json:"host,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
AuthThrough bool `json:"auth_through,omitempty"`
HealthCheckInterval int `json:"health_check_interval,omitempty"`
FailureLimit uint8 `json:"failure_limit,omitempty"`
PingURL string `json:"ping_url,omitempty"`
}
type BackendConfig struct {
// Localfs backend configs
BlobFile string `json:"blob_file,omitempty"`
Dir string `json:"dir,omitempty"`
ReadAhead bool `json:"readahead"`
ReadAheadSec int `json:"readahead_sec,omitempty"`
// Registry backend configs
Host string `json:"host,omitempty"`
Repo string `json:"repo,omitempty"`
Auth string `json:"auth,omitempty"`
RegistryToken string `json:"registry_token,omitempty"`
BlobURLScheme string `json:"blob_url_scheme,omitempty"`
BlobRedirectedHost string `json:"blob_redirected_host,omitempty"`
Mirrors []MirrorConfig `json:"mirrors,omitempty"`
// OSS backend configs
EndPoint string `json:"endpoint,omitempty"`
AccessKeyID string `json:"access_key_id,omitempty"`
AccessKeySecret string `json:"access_key_secret,omitempty"`
BucketName string `json:"bucket_name,omitempty"`
ObjectPrefix string `json:"object_prefix,omitempty"`
// Shared by registry and oss backend
Scheme string `json:"scheme,omitempty"`
SkipVerify bool `json:"skip_verify,omitempty"`
// Below configs are common configs shared by all backends
Proxy struct {
URL string `json:"url,omitempty"`
Fallback bool `json:"fallback"`
PingURL string `json:"ping_url,omitempty"`
CheckInterval int `json:"check_interval,omitempty"`
UseHTTP bool `json:"use_http,omitempty"`
} `json:"proxy,omitempty"`
Timeout int `json:"timeout,omitempty"`
ConnectTimeout int `json:"connect_timeout,omitempty"`
RetryLimit int `json:"retry_limit,omitempty"`
}
type DeviceConfig struct {
Backend struct {
BackendType string `json:"type"`
Config BackendConfig `json:"config"`
} `json:"backend"`
Cache struct {
CacheType string `json:"type"`
Compressed bool `json:"compressed,omitempty"`
Config struct {
WorkDir string `json:"work_dir"`
DisableIndexedMap bool `json:"disable_indexed_map"`
} `json:"config"`
} `json:"cache"`
}
// For nydusd as FUSE daemon. Serialize Daemon info and persist to a json file
// We don't have to persist configuration file for fscache since its configuration
// is passed through HTTP API.
func DumpConfigFile(c interface{}, path string) error {
b, err := json.Marshal(c)
if err != nil {
return errors.Wrapf(err, "marshal config")
}
return os.WriteFile(path, b, 0600)
}
func DumpConfigString(c interface{}) (string, error) {
b, err := json.Marshal(c)
return string(b), err
}
// Achieve a daemon configuration from template or snapshotter's configuration
func SupplementDaemonConfig(c DaemonConfig, imageID, snapshotID string,
vpcRegistry bool, labels map[string]string, params map[string]string, fn func(string, *auth.PassKeyChain) error) error {
image, err := registry.ParseImage(imageID)
if err != nil {
return errors.Wrapf(err, "parse image %s", imageID)
}
backendType, _ := c.StorageBackend()
switch backendType {
case backendTypeRegistry:
registryHost := image.Host
if vpcRegistry {
registryHost = registry.ConvertToVPCHost(registryHost)
} else if registryHost == "docker.io" {
// For docker.io images, we should use index.docker.io
registryHost = "index.docker.io"
}
if err := c.UpdateMirrors(config.GetMirrorsConfigDir(), registryHost); err != nil {
return errors.Wrap(err, "update mirrors config")
}
// If no auth is provided, don't touch auth from provided nydusd configuration file.
// We don't validate the original nydusd auth from configuration file since it can be empty
// when repository is public.
keyChain := auth.GetRegistryKeyChain(registryHost, imageID, labels)
c.Supplement(registryHost, image.Repo, snapshotID, params)
if config.IsKeyringEnabled() && fn != nil {
if err := fn(registryHost, keyChain); err != nil {
if errors.Is(err, unix.EINVAL) {
c.FillAuth(keyChain)
}
return err
}
} else {
c.FillAuth(keyChain)
}
// Localfs and OSS backends don't need any update,
// just use the provided config in template
case backendTypeLocalfs:
case backendTypeOss:
default:
return errors.Errorf("unknown backend type %s", backendType)
}
return nil
}