lib/versioner: Use mtime for version cleanup (fixes #5765) (#5769)

This commit is contained in:
Audrius Butkevicius
2019-06-11 08:16:55 +01:00
committed by Jakob Borg
parent b7c70a9817
commit 21f50e2f8f
6 changed files with 99 additions and 87 deletions

View File

@@ -10,6 +10,7 @@ import (
"fmt"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
@@ -18,19 +19,10 @@ import (
"github.com/syncthing/syncthing/lib/osutil"
)
var locationLocal *time.Location
var errDirectory = fmt.Errorf("cannot restore on top of a directory")
var errNotFound = fmt.Errorf("version not found")
var errFileAlreadyExists = fmt.Errorf("file already exists")
func init() {
var err error
locationLocal, err = time.LoadLocation("Local")
if err != nil {
panic(err.Error())
}
}
// Inserts ~tag just before the extension of the filename.
func TagFilename(name, tag string) string {
dir, file := filepath.Dir(name), filepath.Base(name)
@@ -109,7 +101,7 @@ func retrieveVersions(fileSystem fs.Filesystem) (map[string][]FileVersion, error
return nil
}
versionTime, err := time.ParseInLocation(TimeFormat, tag, locationLocal)
versionTime, err := time.ParseInLocation(TimeFormat, tag, time.Local)
if err != nil {
// Can't parse it, welp, continue
return nil
@@ -117,8 +109,10 @@ func retrieveVersions(fileSystem fs.Filesystem) (map[string][]FileVersion, error
if err == nil {
files[name] = append(files[name], FileVersion{
VersionTime: versionTime.Truncate(time.Second),
ModTime: f.ModTime().Truncate(time.Second),
// This looks backwards, but mtime of the file is when we archived it, making that the version time
// The mod time of the file before archiving is embedded in the file name.
VersionTime: f.ModTime().Truncate(time.Second),
ModTime: versionTime.Truncate(time.Second),
Size: f.Size(),
})
}
@@ -209,7 +203,7 @@ func restoreFile(src, dst fs.Filesystem, filePath string, versionTime time.Time,
}
filePath = osutil.NativeFilename(filePath)
tag := versionTime.In(locationLocal).Truncate(time.Second).Format(TimeFormat)
tag := versionTime.In(time.Local).Truncate(time.Second).Format(TimeFormat)
taggedFilename := TagFilename(filePath, tag)
oldTaggedFilename := filePath + tag
@@ -269,3 +263,30 @@ func fsFromParams(folderFs fs.Filesystem, params map[string]string) (versionsFs
l.Debugln("%s (%s) folder using %s (%s) versioner dir", folderFs.URI(), folderFs.Type(), versionsFs.URI(), versionsFs.Type())
return
}
type versionWithMtime struct {
name string
mtime time.Time
}
func versionsToVersionsWithMtime(fs fs.Filesystem, versions []string) []versionWithMtime {
versionsWithMtimes := make([]versionWithMtime, 0, len(versions))
for _, version := range versions {
if stat, err := fs.Stat(version); err != nil {
// Welp, assume it's gone?
continue
} else {
versionsWithMtimes = append(versionsWithMtimes, versionWithMtime{
name: version,
mtime: stat.ModTime(),
})
}
}
sort.Slice(versionsWithMtimes, func(i, j int) bool {
return versionsWithMtimes[i].mtime.Before(versionsWithMtimes[j].mtime)
})
return versionsWithMtimes
}