fix: dfpath creates redundant directories (#1446)

Signed-off-by: Gaius <gaius.qi@gmail.com>
This commit is contained in:
Gaius 2022-07-11 10:39:00 +08:00
parent 8cf344992f
commit f499d66598
No known key found for this signature in database
GPG Key ID: 8B4E5D1290FA2FFB
7 changed files with 100 additions and 43 deletions

View File

@ -104,17 +104,21 @@ func initDaemonDfpath(cfg *config.DaemonOption) (dfpath.Dfpath, error) {
options = append(options, dfpath.WithWorkHome(cfg.WorkHome)) options = append(options, dfpath.WithWorkHome(cfg.WorkHome))
} }
if cfg.CacheDir != "" {
options = append(options, dfpath.WithCacheDir(cfg.CacheDir))
}
if cfg.LogDir != "" { if cfg.LogDir != "" {
options = append(options, dfpath.WithLogDir(cfg.LogDir)) options = append(options, dfpath.WithLogDir(cfg.LogDir))
} }
if cfg.DataDir != "" { cacheDir := dfpath.DefaultCacheDir
options = append(options, dfpath.WithDataDir(cfg.DataDir)) if cfg.CacheDir != "" {
cacheDir = cfg.CacheDir
} }
options = append(options, dfpath.WithCacheDir(cacheDir))
dataDir := dfpath.DefaultDataDir
if cfg.DataDir != "" {
dataDir = cfg.DataDir
}
options = append(options, dfpath.WithDataDir(dataDir))
return dfpath.New(options...) return dfpath.New(options...)
} }

View File

@ -93,9 +93,11 @@ func initDfpath(cfg *config.ServerConfig) (dfpath.Dfpath, error) {
options = append(options, dfpath.WithLogDir(cfg.LogDir)) options = append(options, dfpath.WithLogDir(cfg.LogDir))
} }
cacheDir := dfpath.DefaultCacheDir
if cfg.CacheDir != "" { if cfg.CacheDir != "" {
options = append(options, dfpath.WithCacheDir(cfg.CacheDir)) cacheDir = cfg.CacheDir
} }
options = append(options, dfpath.WithCacheDir(cacheDir))
return dfpath.New(options...) return dfpath.New(options...)
} }

2
go.mod
View File

@ -35,6 +35,7 @@ require (
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/go-multierror v1.1.1
github.com/jarcoal/httpmock v1.0.8 github.com/jarcoal/httpmock v1.0.8
github.com/looplab/fsm v0.3.0 github.com/looplab/fsm v0.3.0
github.com/mcuadros/go-gin-prometheus v0.1.0 github.com/mcuadros/go-gin-prometheus v0.1.0
@ -122,7 +123,6 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect

View File

@ -19,14 +19,15 @@
package dfpath package dfpath
import ( import (
"fmt"
"io/fs" "io/fs"
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
"github.com/hashicorp/go-multierror"
) )
// Dfpath is the interface used for init project path // Dfpath is the interface used for init project path.
type Dfpath interface { type Dfpath interface {
WorkHome() string WorkHome() string
CacheDir() string CacheDir() string
@ -38,7 +39,7 @@ type Dfpath interface {
DfgetLockPath() string DfgetLockPath() string
} }
// Dfpath provides init project path function // Dfpath provides init project path function.
type dfpath struct { type dfpath struct {
workHome string workHome string
cacheDir string cacheDir string
@ -50,76 +51,103 @@ type dfpath struct {
dfgetLockPath string dfgetLockPath string
} }
// Cache of the dfpath // Cache of the dfpath.
var cache struct { var cache struct {
sync.Once sync.Once
d *dfpath d *dfpath
errs []error err *multierror.Error
} }
// Option is a functional option for configuring the dfpath // Option is a functional option for configuring the dfpath.
type Option func(d *dfpath) type Option func(d *dfpath)
// WithWorkHome set the workhome directory // WithWorkHome set the workhome directory.
func WithWorkHome(dir string) Option { func WithWorkHome(dir string) Option {
return func(d *dfpath) { return func(d *dfpath) {
d.workHome = dir d.workHome = dir
} }
} }
// WithCacheDir set the cache directory // WithCacheDir set the cache directory.
func WithCacheDir(dir string) Option { func WithCacheDir(dir string) Option {
return func(d *dfpath) { return func(d *dfpath) {
d.cacheDir = dir d.cacheDir = dir
} }
} }
// WithLogDir set the log directory // WithLogDir set the log directory.
func WithLogDir(dir string) Option { func WithLogDir(dir string) Option {
return func(d *dfpath) { return func(d *dfpath) {
d.logDir = dir d.logDir = dir
} }
} }
// WithDataDir set download data directory // WithDataDir set download data directory.
func WithDataDir(dir string) Option { func WithDataDir(dir string) Option {
return func(d *dfpath) { return func(d *dfpath) {
d.dataDir = dir d.dataDir = dir
} }
} }
// New returns a new dfpath interface // WithPluginDir set plugin directory.
func WithPluginDir(dir string) Option {
return func(d *dfpath) {
d.pluginDir = dir
}
}
// New returns a new dfpath interface.
func New(options ...Option) (Dfpath, error) { func New(options ...Option) (Dfpath, error) {
cache.Do(func() { cache.Do(func() {
d := &dfpath{ d := &dfpath{
workHome: DefaultWorkHome, workHome: DefaultWorkHome,
cacheDir: DefaultCacheDir,
logDir: DefaultLogDir, logDir: DefaultLogDir,
dataDir: DefaultDataDir, pluginDir: DefaultPluginDir,
} }
for _, opt := range options { for _, opt := range options {
opt(d) opt(d)
} }
d.pluginDir = filepath.Join(d.workHome, "plugins") // Initialize dfdaemon path.
d.daemonSockPath = filepath.Join(d.workHome, "daemon.sock") d.daemonSockPath = filepath.Join(d.workHome, "daemon.sock")
d.daemonLockPath = filepath.Join(d.workHome, "daemon.lock") d.daemonLockPath = filepath.Join(d.workHome, "daemon.lock")
d.dfgetLockPath = filepath.Join(d.workHome, "dfget.lock") d.dfgetLockPath = filepath.Join(d.workHome, "dfget.lock")
// Create directories // Create workhome directory.
for name, dir := range map[string]string{"workHome": d.workHome, "cacheDir": d.cacheDir, "logDir": d.logDir, "dataDir": d.dataDir, if err := os.MkdirAll(d.workHome, fs.FileMode(0755)); err != nil {
"pluginDir": d.pluginDir} { cache.err = multierror.Append(cache.err, err)
if err := os.MkdirAll(dir, fs.FileMode(0755)); err != nil { }
cache.errs = append(cache.errs, fmt.Errorf("create %s dir %s failed: %v", name, dir, err))
// Create log directory.
if err := os.MkdirAll(d.logDir, fs.FileMode(0755)); err != nil {
cache.err = multierror.Append(cache.err, err)
}
// Create plugin directory.
if err := os.MkdirAll(d.pluginDir, fs.FileMode(0755)); err != nil {
cache.err = multierror.Append(cache.err, err)
}
// Create cache directory.
if d.cacheDir != "" {
if err := os.MkdirAll(d.cacheDir, fs.FileMode(0755)); err != nil {
cache.err = multierror.Append(cache.err, err)
}
}
// Create data directory.
if d.dataDir != "" {
if err := os.MkdirAll(d.dataDir, fs.FileMode(0755)); err != nil {
cache.err = multierror.Append(cache.err, err)
} }
} }
cache.d = d cache.d = d
}) })
if len(cache.errs) > 0 { if cache.err.ErrorOrNil() != nil {
return nil, fmt.Errorf("create dfpath failed: %s", cache.errs) return nil, cache.err
} }
d := *cache.d d := *cache.d

View File

@ -30,3 +30,4 @@ var DefaultCacheDir = filepath.Join(DefaultWorkHome, "cache")
var DefaultConfigDir = filepath.Join(DefaultWorkHome, "config") var DefaultConfigDir = filepath.Join(DefaultWorkHome, "config")
var DefaultLogDir = filepath.Join(DefaultWorkHome, "logs") var DefaultLogDir = filepath.Join(DefaultWorkHome, "logs")
var DefaultDataDir = filepath.Join(DefaultWorkHome, "data") var DefaultDataDir = filepath.Join(DefaultWorkHome, "data")
var DefaultPluginDir = filepath.Join(DefaultWorkHome, "plugins")

View File

@ -24,3 +24,4 @@ var DefaultCacheDir = "/var/cache/dragonfly"
var DefaultConfigDir = "/etc/dragonfly" var DefaultConfigDir = "/etc/dragonfly"
var DefaultLogDir = "/var/log/dragonfly" var DefaultLogDir = "/var/log/dragonfly"
var DefaultDataDir = "/var/lib/dragonfly" var DefaultDataDir = "/var/lib/dragonfly"
var DefaultPluginDir = "/usr/local/dragonfly/plugins"

View File

@ -20,6 +20,7 @@ import (
"sync" "sync"
"testing" "testing"
"github.com/hashicorp/go-multierror"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -43,13 +44,14 @@ func TestNew(t *testing.T) {
expect: func(t *testing.T, options []Option) { expect: func(t *testing.T, options []Option) {
assert := assert.New(t) assert := assert.New(t)
cache.Once = sync.Once{} cache.Once = sync.Once{}
cache.errs = []error{} cache.err = &multierror.Error{}
d, err := New(options...) d, err := New(options...)
assert.NoError(err) assert.NoError(err)
assert.Equal(d.WorkHome(), DefaultWorkHome) assert.Equal(d.WorkHome(), DefaultWorkHome)
assert.Equal(d.CacheDir(), DefaultCacheDir) assert.Equal(d.CacheDir(), "")
assert.Equal(d.LogDir(), DefaultLogDir) assert.Equal(d.LogDir(), DefaultLogDir)
assert.Equal(d.DataDir(), DefaultDataDir) assert.Equal(d.DataDir(), "")
assert.Equal(d.PluginDir(), DefaultPluginDir)
}, },
}, },
{ {
@ -58,13 +60,14 @@ func TestNew(t *testing.T) {
expect: func(t *testing.T, options []Option) { expect: func(t *testing.T, options []Option) {
assert := assert.New(t) assert := assert.New(t)
cache.Once = sync.Once{} cache.Once = sync.Once{}
cache.errs = []error{} cache.err = &multierror.Error{}
d, err := New(options...) d, err := New(options...)
assert.NoError(err) assert.NoError(err)
assert.Equal(d.WorkHome(), "foo") assert.Equal(d.WorkHome(), "foo")
assert.Equal(d.CacheDir(), DefaultCacheDir) assert.Equal(d.CacheDir(), "")
assert.Equal(d.LogDir(), DefaultLogDir) assert.Equal(d.LogDir(), DefaultLogDir)
assert.Equal(d.DataDir(), DefaultDataDir) assert.Equal(d.DataDir(), "")
assert.Equal(d.PluginDir(), DefaultPluginDir)
}, },
}, },
{ {
@ -73,13 +76,14 @@ func TestNew(t *testing.T) {
expect: func(t *testing.T, options []Option) { expect: func(t *testing.T, options []Option) {
assert := assert.New(t) assert := assert.New(t)
cache.Once = sync.Once{} cache.Once = sync.Once{}
cache.errs = []error{} cache.err = &multierror.Error{}
d, err := New(options...) d, err := New(options...)
assert.NoError(err) assert.NoError(err)
assert.Equal(d.WorkHome(), DefaultWorkHome) assert.Equal(d.WorkHome(), DefaultWorkHome)
assert.Equal(d.CacheDir(), "foo") assert.Equal(d.CacheDir(), "foo")
assert.Equal(d.LogDir(), DefaultLogDir) assert.Equal(d.LogDir(), DefaultLogDir)
assert.Equal(d.DataDir(), DefaultDataDir) assert.Equal(d.DataDir(), "")
assert.Equal(d.PluginDir(), DefaultPluginDir)
}, },
}, },
{ {
@ -88,13 +92,30 @@ func TestNew(t *testing.T) {
expect: func(t *testing.T, options []Option) { expect: func(t *testing.T, options []Option) {
assert := assert.New(t) assert := assert.New(t)
cache.Once = sync.Once{} cache.Once = sync.Once{}
cache.errs = []error{} cache.err = &multierror.Error{}
d, err := New(options...) d, err := New(options...)
assert.NoError(err) assert.NoError(err)
assert.Equal(d.WorkHome(), DefaultWorkHome) assert.Equal(d.WorkHome(), DefaultWorkHome)
assert.Equal(d.CacheDir(), DefaultCacheDir) assert.Equal(d.CacheDir(), "")
assert.Equal(d.LogDir(), "foo") assert.Equal(d.LogDir(), "foo")
assert.Equal(d.DataDir(), DefaultDataDir) assert.Equal(d.DataDir(), "")
assert.Equal(d.PluginDir(), DefaultPluginDir)
},
},
{
name: "new dfpath by pluginDir",
options: []Option{WithPluginDir("foo")},
expect: func(t *testing.T, options []Option) {
assert := assert.New(t)
cache.Once = sync.Once{}
cache.err = &multierror.Error{}
d, err := New(options...)
assert.NoError(err)
assert.Equal(d.WorkHome(), DefaultWorkHome)
assert.Equal(d.CacheDir(), "")
assert.Equal(d.LogDir(), DefaultLogDir)
assert.Equal(d.DataDir(), "")
assert.Equal(d.PluginDir(), "foo")
}, },
}, },
} }