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
|
/*
* 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"
"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"`
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) 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)
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
}
|