From 69782d2abedb28de576583c47f1fa565b3363f99 Mon Sep 17 00:00:00 2001 From: Jarek Kowalski Date: Thu, 13 Sep 2018 19:32:56 -0700 Subject: [PATCH] refactored cache commands --- cli/app.go | 1 + cli/command_cache_clear.go | 35 +++++++++++++++++++++++++++++++++++ cli/command_cache_info.go | 34 ++++++++++++++++++++++++++++++++++ cli/command_cache_set.go | 30 ++++++++++++++++++++++++++++++ repo/connect.go | 10 +++++++--- repo/open.go | 2 +- 6 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 cli/command_cache_clear.go create mode 100644 cli/command_cache_info.go create mode 100644 cli/command_cache_set.go diff --git a/cli/app.go b/cli/app.go index 4d86c2597..c71a9d592 100644 --- a/cli/app.go +++ b/cli/app.go @@ -25,6 +25,7 @@ _ = app.Flag("help-full", "Show help for all commands, including hidden").Action(helpFullAction).Bool() repositoryCommands = app.Command("repository", "Commands to manipulate repository.").Alias("repo") + cacheCommands = app.Command("cache", "Commands to manipulate local cache").Hidden() snapshotCommands = app.Command("snapshot", "Commands to manipulate snapshots.").Alias("snap") policyCommands = app.Command("policy", "Commands to manipulate snapshotting policies.").Alias("policies") serverCommands = app.Command("server", "Commands to control HTTP API server.") diff --git a/cli/command_cache_clear.go b/cli/command_cache_clear.go new file mode 100644 index 000000000..c543d4c08 --- /dev/null +++ b/cli/command_cache_clear.go @@ -0,0 +1,35 @@ +package cli + +import ( + "context" + "fmt" + "os" + + "github.com/kopia/kopia/repo" +) + +var ( + cacheClearCommand = cacheCommands.Command("clear", "Clears the cache").Hidden() +) + +func runCacheClearCommand(ctx context.Context, rep *repo.Repository) error { + if d := rep.CacheDirectory; d != "" { + err := os.RemoveAll(d) + if err != nil { + return err + } + + if err := os.MkdirAll(d, 0700); err != nil { + return err + } + + log.Noticef("cache cleared") + return nil + } + + return fmt.Errorf("caching not enabled") +} + +func init() { + cacheClearCommand.Action(repositoryAction(runCacheClearCommand)) +} diff --git a/cli/command_cache_info.go b/cli/command_cache_info.go new file mode 100644 index 000000000..bebe689f1 --- /dev/null +++ b/cli/command_cache_info.go @@ -0,0 +1,34 @@ +package cli + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/kopia/kopia/internal/units" + "github.com/kopia/kopia/repo" +) + +var ( + cacheInfoCommand = cacheCommands.Command("info", "Sets parameters local caching of repository data").Hidden() + cacheInfoPathOnly = cacheInfoCommand.Flag("path", "Only display cache path").Bool() +) + +func runCacheInfoCommand(ctx context.Context, rep *repo.Repository) error { + fmt.Println(rep.CacheDirectory) + if *cacheInfoPathOnly { + return nil + } + + log.Debugf("scanning cache...") + fileCount, totalFileSize, err := scanCacheDir(filepath.Join(rep.CacheDirectory, "blocks")) + if err != nil { + return err + } + fmt.Printf("Usage: %v files %v\n", fileCount, units.BytesStringBase2(totalFileSize)) + return nil +} + +func init() { + cacheInfoCommand.Action(repositoryAction(runCacheInfoCommand)) +} diff --git a/cli/command_cache_set.go b/cli/command_cache_set.go new file mode 100644 index 000000000..9491333a8 --- /dev/null +++ b/cli/command_cache_set.go @@ -0,0 +1,30 @@ +package cli + +import ( + "context" + + "github.com/kopia/kopia/repo" + "github.com/kopia/kopia/repo/block" +) + +var ( + cacheSetParamsCommand = cacheCommands.Command("set", "Sets parameters local caching of repository data").Hidden() + + cacheSetDirectory = cacheSetParamsCommand.Flag("cache-directory", "Directory where to store cache files").String() + cacheSetMaxCacheSizeMB = cacheSetParamsCommand.Flag("cache-size-mb", "Size of local cache (0 disables caching)").PlaceHolder("MB").Int64() + cacheSetMaxListCacheDuration = cacheSetParamsCommand.Flag("max-list-cache-duration", "Duration of index cache").Default("600s").Duration() +) + +func runCacheSetCommand(ctx context.Context, rep *repo.Repository) error { + opts := block.CachingOptions{ + CacheDirectory: *cacheSetDirectory, + MaxCacheSizeBytes: *cacheSetMaxCacheSizeMB << 20, + MaxListCacheDurationSec: int(cacheSetMaxListCacheDuration.Seconds()), + } + + return repo.SetCachingConfig(ctx, repositoryConfigFileName(), opts) +} + +func init() { + cacheSetParamsCommand.Action(repositoryAction(runCacheSetCommand)) +} diff --git a/repo/connect.go b/repo/connect.go index ab2c8b31a..e2990104a 100644 --- a/repo/connect.go +++ b/repo/connect.go @@ -2,6 +2,7 @@ import ( "context" + "crypto/sha256" "encoding/hex" "encoding/json" "fmt" @@ -36,7 +37,7 @@ func Connect(ctx context.Context, configFile string, st storage.Storage, passwor var lc config.LocalConfig lc.Storage = st.ConnectionInfo() - if err = setupCaching(&lc, opt.CachingOptions, f.UniqueID); err != nil { + if err = setupCaching(configFile, &lc, opt.CachingOptions, f.UniqueID); err != nil { return fmt.Errorf("unable to set up caching: %v", err) } @@ -62,14 +63,17 @@ func Connect(ctx context.Context, configFile string, st storage.Storage, passwor return r.Close(ctx) } -func setupCaching(lc *config.LocalConfig, opt block.CachingOptions, uniqueID []byte) error { +func setupCaching(configPath string, lc *config.LocalConfig, opt block.CachingOptions, uniqueID []byte) error { if opt.MaxCacheSizeBytes == 0 { lc.Caching = block.CachingOptions{} return nil } if opt.CacheDirectory == "" { - lc.Caching.CacheDirectory = filepath.Join(ospath.CacheDir(), hex.EncodeToString(uniqueID)) + h := sha256.New() + h.Write(uniqueID) + h.Write([]byte(configPath)) + lc.Caching.CacheDirectory = filepath.Join(ospath.CacheDir(), hex.EncodeToString(h.Sum(nil))[0:16]) } else { absCacheDir, err := filepath.Abs(opt.CacheDirectory) if err != nil { diff --git a/repo/open.go b/repo/open.go index 1f91016da..043013535 100644 --- a/repo/open.go +++ b/repo/open.go @@ -147,7 +147,7 @@ func SetCachingConfig(ctx context.Context, configFile string, opt block.CachingO return fmt.Errorf("can't read format block: %v", err) } - if err = setupCaching(lc, opt, f.UniqueID); err != nil { + if err = setupCaching(configFile, lc, opt, f.UniqueID); err != nil { return fmt.Errorf("unable to set up caching: %v", err) }