Skip to content

Commit

Permalink
refactor: replace global cache directory with parameter passing (#6986)
Browse files Browse the repository at this point in the history
Signed-off-by: knqyf263 <[email protected]>
  • Loading branch information
knqyf263 authored Jun 21, 2024
1 parent 7eabb92 commit 648ead9
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 58 deletions.
33 changes: 14 additions & 19 deletions pkg/cache/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (
)

type Client struct {
dir string
Cache
}

Expand Down Expand Up @@ -115,7 +116,8 @@ func NewType(backend string) (Type, error) {
}

// NewClient returns a new cache client
func NewClient(opts Options) (*Client, error) {
func NewClient(dir string, opts Options) (*Client, error) {
client := &Client{dir: dir}
if opts.Type == TypeRedis {
log.Info("Redis cache", log.String("url", opts.Redis.BackendMasked()))
options, err := redis.ParseURL(opts.Redis.Backend)
Expand All @@ -140,34 +142,27 @@ func NewClient(opts Options) (*Client, error) {
}
}

redisCache := NewRedisCache(options, opts.TTL)
return &Client{Cache: redisCache}, nil
client.Cache = NewRedisCache(options, opts.TTL)
return client, nil
}

// standalone mode
fsCache, err := NewFSCache(Dir())
var err error
client.Cache, err = NewFSCache(dir)
if err != nil {
return nil, xerrors.Errorf("unable to initialize fs cache: %w", err)
}
return &Client{Cache: fsCache}, nil
return client, nil
}

// Reset resets the cache
func (c *Client) Reset() (err error) {
if err := c.ClearDB(); err != nil {
return xerrors.Errorf("failed to clear the database: %w", err)
}
if err := c.ClearArtifacts(); err != nil {
return xerrors.Errorf("failed to clear the artifact cache: %w", err)
func (c *Client) Reset() error {
log.Info("Removing all caches...")
if err := c.Clear(); err != nil {
return xerrors.Errorf("failed to remove the cache: %w", err)
}
return nil
}

// ClearDB clears the DB cache
func (c *Client) ClearDB() (err error) {
log.Info("Removing DB file...")
if err = os.RemoveAll(Dir()); err != nil {
return xerrors.Errorf("failed to remove the directory (%s) : %w", Dir(), err)
if err := os.RemoveAll(c.dir); err != nil {
return xerrors.Errorf("failed to remove the directory (%s) : %w", c.dir, err)
}
return nil
}
Expand Down
50 changes: 50 additions & 0 deletions pkg/cache/client_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cache_test

import (
"os"
"path/filepath"
"testing"
"time"

Expand Down Expand Up @@ -127,3 +129,51 @@ func TestRedisOptions_BackendMasked(t *testing.T) {
})
}
}

func TestClient_Reset(t *testing.T) {
// Create a temporary directory for testing
tempDir := t.TempDir()

// Create test files and subdirectories
subDir := filepath.Join(tempDir, "subdir")
err := os.MkdirAll(subDir, 0755)
require.NoError(t, err)

testFile := filepath.Join(tempDir, "testfile.txt")
err = os.WriteFile(testFile, []byte("test content"), 0644)
require.NoError(t, err)

// Create a cache client
client, err := cache.NewClient(tempDir, cache.Options{Type: cache.TypeFS})
require.NoError(t, err)

// Call Reset method
err = client.Reset()
require.NoError(t, err)

// Verify that the subdirectory no longer exists
require.NoDirExists(t, subDir, "Subdirectory should not exist after Reset")

// Verify that the test file no longer exists
require.NoFileExists(t, testFile, "Test file should not exist after Reset")

// Verify that the cache directory no longer exists
require.NoDirExists(t, tempDir, "Cache directory should not exist after Reset")
}

func TestClient_ClearArtifacts(t *testing.T) {
// Create a temporary directory for testing
tempDir := t.TempDir()

// Create a client
client, err := cache.NewClient(tempDir, cache.Options{Type: cache.TypeFS})
require.NoError(t, err)

require.FileExists(t, filepath.Join(tempDir, "fanal", "fanal.db"), "Database file should exist")

// Call ClearArtifacts method
err = client.ClearArtifacts()
require.NoError(t, err)

require.NoDirExists(t, filepath.Join(tempDir, "fanal"), "Artifact cache should not exist after ClearArtifacts")
}
19 changes: 2 additions & 17 deletions pkg/cache/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,11 @@ import (
"path/filepath"
)

var cacheDir string

// defaultDir returns/creates the cache-dir to be used for trivy operations
func defaultDir() string {
// DefaultDir returns/creates the cache-dir to be used for trivy operations
func DefaultDir() string {
tmpDir, err := os.UserCacheDir()
if err != nil {
tmpDir = os.TempDir()
}
return filepath.Join(tmpDir, "trivy")
}

// Dir returns the directory used for caching
func Dir() string {
if cacheDir == "" {
return defaultDir()
}
return cacheDir
}

// SetDir sets the trivy cache dir
func SetDir(dir string) {
cacheDir = dir
}
3 changes: 1 addition & 2 deletions pkg/commands/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,9 @@ func NewApp() *cobra.Command {

func loadPluginCommands() []*cobra.Command {
ctx := context.Background()
manager := plugin.NewManager()

var commands []*cobra.Command
plugins, err := manager.LoadAll(ctx)
plugins, err := plugin.NewManager().LoadAll(ctx)
if err != nil {
log.DebugContext(ctx, "No plugins loaded")
return nil
Expand Down
7 changes: 3 additions & 4 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,11 @@ func (r *runner) initCache(opts flag.Options) error {
}

// standalone mode
cache.SetDir(opts.CacheDir)
cacheClient, err := cache.NewClient(opts.CacheOptions.CacheBackendOptions)
cacheClient, err := cache.NewClient(opts.CacheDir, opts.CacheOptions.CacheBackendOptions)
if err != nil {
return xerrors.Errorf("unable to initialize the cache: %w", err)
}
log.Debug("Cache dir", log.String("dir", cache.Dir()))
log.Debug("Cache dir", log.String("dir", opts.CacheDir))

if opts.Reset {
defer cacheClient.Close()
Expand All @@ -366,7 +365,7 @@ func (r *runner) initCache(opts flag.Options) error {
}

if opts.ResetChecksBundle {
c, err := policy.NewClient(cache.Dir(), true, opts.MisconfOptions.ChecksBundleRepository)
c, err := policy.NewClient(opts.CacheDir, true, opts.MisconfOptions.ChecksBundleRepository)
if err != nil {
return xerrors.Errorf("failed to instantiate check client: %w", err)
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/commands/server/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ func Run(ctx context.Context, opts flag.Options) (err error) {
log.InitLogger(opts.Debug, opts.Quiet)

// configure cache dir
cache.SetDir(opts.CacheDir)
cacheClient, err := cache.NewClient(opts.CacheOptions.CacheBackendOptions)
cacheClient, err := cache.NewClient(opts.CacheDir, opts.CacheOptions.CacheBackendOptions)
if err != nil {
return xerrors.Errorf("server cache error: %w", err)
}
defer cacheClient.Close()
log.Debug("Cache", log.String("dir", cache.Dir()))
log.Debug("Cache", log.String("dir", opts.CacheDir))

if opts.Reset {
return cacheClient.ClearDB()
return cacheClient.Reset()
}

// download the database file
Expand Down
2 changes: 1 addition & 1 deletion pkg/flag/global_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ var (
CacheDirFlag = Flag[string]{
Name: "cache-dir",
ConfigName: "cache.dir",
Default: cache.Dir(),
Default: cache.DefaultDir(),
Usage: "cache directory",
Persistent: true,
}
Expand Down
2 changes: 0 additions & 2 deletions pkg/oci/artifact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/aquasecurity/trivy/pkg/cache"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/oci"
)
Expand Down Expand Up @@ -97,7 +96,6 @@ func TestArtifact_Download(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tempDir := t.TempDir()
cache.SetDir(tempDir)

// Mock image
img := new(fakei.FakeImage)
Expand Down
7 changes: 3 additions & 4 deletions pkg/plugin/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/aquasecurity/trivy/pkg/cache"
"github.com/aquasecurity/trivy/pkg/plugin"
)

func TestManager_Update(t *testing.T) {
tempDir := t.TempDir()
cache.SetDir(tempDir)
t.Setenv("XDG_DATA_HOME", tempDir)

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte(`this is index`))
Expand All @@ -30,7 +29,7 @@ func TestManager_Update(t *testing.T) {
err := manager.Update(context.Background())
require.NoError(t, err)

indexPath := filepath.Join(tempDir, "plugin", "index.yaml")
indexPath := filepath.Join(tempDir, ".trivy", "plugins", "index.yaml")
assert.FileExists(t, indexPath)

b, err := os.ReadFile(indexPath)
Expand Down Expand Up @@ -73,7 +72,7 @@ bar A bar plugin
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cache.SetDir(tt.dir)
t.Setenv("XDG_DATA_HOME", tt.dir)

var got bytes.Buffer
m := plugin.NewManager(plugin.WithWriter(&got))
Expand Down
6 changes: 3 additions & 3 deletions pkg/plugin/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"gopkg.in/yaml.v3"

"github.com/aquasecurity/go-version/pkg/semver"
"github.com/aquasecurity/trivy/pkg/cache"
"github.com/aquasecurity/trivy/pkg/downloader"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/log"
Expand Down Expand Up @@ -59,12 +58,13 @@ type Manager struct {
}

func NewManager(opts ...ManagerOption) *Manager {
root := filepath.Join(fsutils.HomeDir(), pluginsRelativeDir)
m := &Manager{
w: os.Stdout,
indexURL: indexURL,
logger: log.WithPrefix("plugin"),
pluginRoot: filepath.Join(fsutils.HomeDir(), pluginsRelativeDir),
indexPath: filepath.Join(cache.Dir(), "plugin", "index.yaml"),
pluginRoot: root,
indexPath: filepath.Join(root, "index.yaml"),
}
for _, opt := range opts {
opt(m)
Expand Down
8 changes: 6 additions & 2 deletions pkg/plugin/manager_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import (
"github.com/stretchr/testify/require"

"github.com/aquasecurity/trivy/internal/gittest"
"github.com/aquasecurity/trivy/pkg/cache"
"github.com/aquasecurity/trivy/pkg/clock"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/plugin"
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
)

func setupGitRepository(t *testing.T, repo, dir string) *httptest.Server {
Expand Down Expand Up @@ -200,7 +200,11 @@ func TestManager_Install(t *testing.T) {
t.Setenv("XDG_DATA_HOME", dst)

// For plugin index
cache.SetDir("testdata")
pluginDir := filepath.Join(dst, ".trivy", "plugins")
err := os.MkdirAll(pluginDir, 0755)
require.NoError(t, err)
_, err = fsutils.CopyFile("testdata/.trivy/plugins/index.yaml", filepath.Join(pluginDir, "index.yaml"))
require.NoError(t, err)

if tt.installed != nil {
setupInstalledPlugin(t, dst, *tt.installed)
Expand Down
File renamed without changes.

0 comments on commit 648ead9

Please sign in to comment.