Skip to content

Commit

Permalink
Merge pull request #504 from DarkMountain-wyz/main
Browse files Browse the repository at this point in the history
Adding an interface to the system socket to help nydusd obtain config
  • Loading branch information
changweige authored Oct 31, 2023
2 parents 3ffbe8f + 402b9e4 commit f894d55
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 4 deletions.
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ type Experimental struct {
EnableStargz bool `toml:"enable_stargz"`
EnableReferrerDetect bool `toml:"enable_referrer_detect"`
TarfsConfig TarfsConfig `toml:"tarfs"`
EnableBackendSource bool `toml:"enable_backend_source"`
}

type TarfsConfig struct {
Expand Down
63 changes: 59 additions & 4 deletions config/daemonconfig/daemonconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ package daemonconfig
import (
"encoding/json"
"os"
"reflect"
"strings"

"github.com/pkg/errors"

Expand Down Expand Up @@ -75,16 +77,16 @@ type BackendConfig struct {
// Registry backend configs
Host string `json:"host,omitempty"`
Repo string `json:"repo,omitempty"`
Auth string `json:"auth,omitempty"`
RegistryToken string `json:"registry_token,omitempty"`
Auth string `json:"auth,omitempty" secret:"true"`
RegistryToken string `json:"registry_token,omitempty" secret:"true"`
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"`
AccessKeyID string `json:"access_key_id,omitempty" secret:"true"`
AccessKeySecret string `json:"access_key_secret,omitempty" secret:"true"`
BucketName string `json:"bucket_name,omitempty"`
ObjectPrefix string `json:"object_prefix,omitempty"`

Expand Down Expand Up @@ -124,6 +126,9 @@ type DeviceConfig struct {
// 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 {
if config.IsBackendSourceEnabled() {
c = serializeWithSecretFilter(c)
}
b, err := json.Marshal(c)
if err != nil {
return errors.Wrapf(err, "marshal config")
Expand Down Expand Up @@ -179,3 +184,53 @@ func SupplementDaemonConfig(c DaemonConfig, imageID, snapshotID string,

return nil
}

func serializeWithSecretFilter(obj interface{}) map[string]interface{} {
result := make(map[string]interface{})
value := reflect.ValueOf(obj)
typeOfObj := reflect.TypeOf(obj)

if value.Kind() == reflect.Ptr {
value = value.Elem()
typeOfObj = typeOfObj.Elem()
}

for i := 0; i < value.NumField(); i++ {
field := value.Field(i)
fieldType := typeOfObj.Field(i)
secretTag := fieldType.Tag.Get("secret")
jsonTags := strings.Split(fieldType.Tag.Get("json"), ",")
omitemptyTag := false

for _, tag := range jsonTags {
if tag == "omitempty" {
omitemptyTag = true
break
}
}

if secretTag == "true" {
continue
}

if field.Kind() == reflect.Ptr && field.IsNil() {
continue
}

if omitemptyTag && reflect.DeepEqual(reflect.Zero(field.Type()).Interface(), field.Interface()) {
continue
}

//nolint:exhaustive
switch fieldType.Type.Kind() {
case reflect.Struct:
result[jsonTags[0]] = serializeWithSecretFilter(field.Interface())
case reflect.Ptr:
result[jsonTags[0]] = serializeWithSecretFilter(field.Elem().Interface())
default:
result[jsonTags[0]] = field.Interface()
}
}

return result
}
61 changes: 61 additions & 0 deletions config/daemonconfig/daemonconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,64 @@ func TestLoadConfig(t *testing.T) {
require.Equal(t, cfg.Device.Backend.Config.SkipVerify, true)
require.Equal(t, cfg.Device.Backend.Config.Proxy.CheckInterval, 5)
}

func TestSerializeWithSecretFilter(t *testing.T) {
buf := []byte(`{
"device": {
"backend": {
"type": "registry",
"config": {
"skip_verify": true,
"host": "acr-nydus-registry-vpc.cn-hangzhou.cr.aliyuncs.com",
"repo": "test/myserver",
"auth": "token_token",
"blob_url_scheme": "http",
"proxy": {
"url": "http://p2p-proxy:65001",
"fallback": true,
"ping_url": "http://p2p-proxy:40901/server/ping",
"check_interval": 5
},
"timeout": 5,
"connect_timeout": 5,
"retry_limit": 0
}
},
"cache": {
"type": "blobcache",
"config": {
"work_dir": "/cache"
}
}
},
"mode": "direct",
"digest_validate": true,
"iostats_files": true,
"enable_xattr": true,
"fs_prefetch": {
"enable": true,
"threads_count": 10,
"merging_size": 131072
}
}`)
var cfg FuseDaemonConfig
_ = json.Unmarshal(buf, &cfg)
filter := serializeWithSecretFilter(&cfg)
jsonData, err := json.Marshal(filter)
require.Nil(t, err)
var newCfg FuseDaemonConfig
err = json.Unmarshal(jsonData, &newCfg)
require.Nil(t, err)
require.Equal(t, newCfg.FSPrefetch, cfg.FSPrefetch)
require.Equal(t, newCfg.Device.Cache.CacheType, cfg.Device.Cache.CacheType)
require.Equal(t, newCfg.Device.Cache.Config, cfg.Device.Cache.Config)
require.Equal(t, newCfg.Mode, cfg.Mode)
require.Equal(t, newCfg.DigestValidate, cfg.DigestValidate)
require.Equal(t, newCfg.IOStatsFiles, cfg.IOStatsFiles)
require.Equal(t, newCfg.Device.Backend.Config.Host, cfg.Device.Backend.Config.Host)
require.Equal(t, newCfg.Device.Backend.Config.Repo, cfg.Device.Backend.Config.Repo)
require.Equal(t, newCfg.Device.Backend.Config.Proxy, cfg.Device.Backend.Config.Proxy)
require.Equal(t, newCfg.Device.Backend.Config.BlobURLScheme, cfg.Device.Backend.Config.BlobURLScheme)
require.Equal(t, newCfg.Device.Backend.Config.Auth, "")
require.NotEqual(t, newCfg.Device.Backend.Config.Auth, cfg.Device.Backend.Config.Auth)
}
4 changes: 4 additions & 0 deletions config/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ func GetLogToStdout() bool {
return globalConfig.origin.LoggingConfig.LogToStdout
}

func IsBackendSourceEnabled() bool {
return globalConfig.origin.Experimental.EnableBackendSource && globalConfig.origin.SystemControllerConfig.Enable
}

func IsSystemControllerEnabled() bool {
return globalConfig.origin.SystemControllerConfig.Enable
}
Expand Down
3 changes: 3 additions & 0 deletions misc/snapshotter/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ enable_stargz = false
# The option enables trying to fetch the Nydus image associated with the OCI image and run it.
# Also see https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers
enable_referrer_detect = false
# Whether to enable authentication support
# The option enables nydus snapshot to provide backend information to nydusd.
enable_backend_source = false
[experimental.tarfs]
# Whether to enable nydus tarfs mode. Tarfs is supported by:
# - The EROFS filesystem driver since Linux 6.4
Expand Down
7 changes: 7 additions & 0 deletions pkg/daemon/command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type DaemonCommand struct {
Supervisor string `type:"param" name:"supervisor"`
LogFile string `type:"param" name:"log-file"`
PrefetchFiles string `type:"param" name:"prefetch-files"`
BackendSource string `type:"param" name:"backend-source"`
}

// Build exec style command line
Expand Down Expand Up @@ -189,3 +190,9 @@ func WithUpgrade() Opt {
cmd.Upgrade = true
}
}

func WithBackendSource(source string) Opt {
return func(cmd *DaemonCommand) {
cmd.BackendSource = source
}
}
9 changes: 9 additions & 0 deletions pkg/manager/daemon_adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package manager

import (
"fmt"
"os"
"os/exec"
"strings"
Expand All @@ -25,6 +26,8 @@ import (
"github.com/containerd/nydus-snapshotter/pkg/prefetch"
)

const endpointGetBackend string = "/api/v1/daemons/%s/backend"

// Spawn a nydusd daemon to serve the daemon instance.
//
// When returning from `StartDaemon()` with out error:
Expand Down Expand Up @@ -156,6 +159,12 @@ func (m *Manager) BuildDaemonCommand(d *daemon.Daemon, bin string, upgrade bool)
command.WithConfig(d.ConfigFile("")),
command.WithBootstrap(bootstrap),
)
if config.IsBackendSourceEnabled() {
configAPIPath := fmt.Sprintf(endpointGetBackend, d.States.ID)
cmdOpts = append(cmdOpts,
command.WithBackendSource(config.SystemControllerAddress()+configAPIPath),
)
}
default:
return nil, errors.Errorf("invalid daemon mode %s ", d.States.DaemonMode)
}
Expand Down
43 changes: 43 additions & 0 deletions pkg/system/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const (
endpointDaemonRecords string = "/api/v1/daemons/records"
endpointDaemonsUpgrade string = "/api/v1/daemons/upgrade"
endpointPrefetch string = "/api/v1/prefetch"
// Provide backend information
endpointGetBackend string = "/api/v1/daemons/{id}/backend"
)

const defaultErrorCode string = "Unknown"
Expand Down Expand Up @@ -171,6 +173,47 @@ func (sc *Controller) registerRouter() {
sc.router.HandleFunc(endpointDaemonsUpgrade, sc.upgradeDaemons()).Methods(http.MethodPut)
sc.router.HandleFunc(endpointDaemonRecords, sc.getDaemonRecords()).Methods(http.MethodGet)
sc.router.HandleFunc(endpointPrefetch, sc.setPrefetchConfiguration()).Methods(http.MethodPut)
sc.router.HandleFunc(endpointGetBackend, sc.getBackend()).Methods(http.MethodGet)
}

func (sc *Controller) getBackend() func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
var err error
var statusCode int

defer func() {
if err != nil {
m := newErrorMessage(err.Error())
http.Error(w, m.encode(), statusCode)
}
}()

vars := mux.Vars(r)
id := vars["id"]

for _, ma := range sc.managers {
ma.Lock()
d := ma.GetByDaemonID(id)

if d != nil {
backendType, backendConfig := d.Config.StorageBackend()
backend := struct {
BackendType string `json:"type"`
Config interface{} `json:"config"`
}{
backendType,
backendConfig,
}
jsonResponse(w, backend)
ma.Unlock()
return
}
ma.Unlock()
}

err = errdefs.ErrNotFound
statusCode = http.StatusNotFound
}
}

func (sc *Controller) setPrefetchConfiguration() func(w http.ResponseWriter, r *http.Request) {
Expand Down

0 comments on commit f894d55

Please sign in to comment.