restic/cmd/restic/cmd_cache.go

123 lines
2.6 KiB
Go

package main
import (
"fmt"
"path/filepath"
"sort"
"time"
"github.com/restic/restic/internal/cache"
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/fs"
"github.com/spf13/cobra"
)
var cmdCache = &cobra.Command{
Use: "cache",
Short: "Operate on local cache directories",
Long: `
The "cache" command allows listing and cleaning local cache directories.
`,
DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runCache(cacheOptions, globalOptions, args)
},
}
// CacheOptions bundles all options for the snapshots command.
type CacheOptions struct {
Cleanup bool
MaxAge uint
}
var cacheOptions CacheOptions
func init() {
cmdRoot.AddCommand(cmdCache)
f := cmdCache.Flags()
f.BoolVar(&cacheOptions.Cleanup, "cleanup", false, "remove old cache directories")
f.UintVar(&cacheOptions.MaxAge, "max-age", 30, "max age in `days` for cache directories to be considered old")
}
func runCache(opts CacheOptions, gopts GlobalOptions, args []string) error {
if len(args) > 0 {
return errors.Fatal("the cache command has no arguments")
}
if gopts.NoCache {
return errors.Fatal("Refusing to do anything, the cache is disabled")
}
var (
cachedir = gopts.CacheDir
err error
)
if cachedir == "" {
cachedir, err = cache.DefaultDir()
if err != nil {
return err
}
}
if opts.Cleanup || gopts.CleanupCache {
oldDirs, err := cache.OlderThan(cachedir, time.Duration(opts.MaxAge)*24*time.Hour)
if err != nil {
return err
}
if len(oldDirs) == 0 {
Verbosef("no old cache dirs found\n")
return nil
}
Verbosef("remove %d old cache directories\n", len(oldDirs))
for _, item := range oldDirs {
dir := filepath.Join(cachedir, item.Name())
err = fs.RemoveAll(dir)
if err != nil {
Warnf("unable to remove %v: %v\n", dir, err)
}
}
return nil
}
tab := NewTable()
tab.Header = fmt.Sprintf("%-14s %-16s %s", "Repository ID", "Last Used", "Old")
tab.RowFormat = "%-14s %-16s %s"
dirs, err := cache.All(cachedir)
if err != nil {
return err
}
if len(dirs) == 0 {
Printf("no cache dirs found, basedir is %v\n", cachedir)
return nil
}
sort.Slice(dirs, func(i, j int) bool {
return dirs[i].ModTime().Before(dirs[j].ModTime())
})
for _, entry := range dirs {
var old string
if cache.IsOld(entry.ModTime(), time.Duration(opts.MaxAge)*24*time.Hour) {
old = "yes"
}
tab.Rows = append(tab.Rows, []interface{}{
entry.Name()[:10],
fmt.Sprintf("%d days ago", uint(time.Since(entry.ModTime()).Hours()/24)),
old,
})
}
tab.Write(gopts.stdout)
return nil
}