1// Copyright (C) 2014 The Syncthing Authors. 2// 3// This Source Code Form is subject to the terms of the Mozilla Public 4// License, v. 2.0. If a copy of the MPL was not distributed with this file, 5// You can obtain one at https://mozilla.org/MPL/2.0/. 6 7package versioner 8 9import ( 10 "context" 11 "strconv" 12 "time" 13 14 "github.com/syncthing/syncthing/lib/config" 15 "github.com/syncthing/syncthing/lib/fs" 16) 17 18func init() { 19 // Register the constructor for this type of versioner with the name "simple" 20 factories["simple"] = newSimple 21} 22 23type simple struct { 24 keep int 25 cleanoutDays int 26 folderFs fs.Filesystem 27 versionsFs fs.Filesystem 28 copyRangeMethod fs.CopyRangeMethod 29} 30 31func newSimple(cfg config.FolderConfiguration) Versioner { 32 var keep, err = strconv.Atoi(cfg.Versioning.Params["keep"]) 33 cleanoutDays, _ := strconv.Atoi(cfg.Versioning.Params["cleanoutDays"]) 34 // On error we default to 0, "do not clean out the trash can" 35 36 if err != nil { 37 keep = 5 // A reasonable default 38 } 39 40 s := simple{ 41 keep: keep, 42 cleanoutDays: cleanoutDays, 43 folderFs: cfg.Filesystem(), 44 versionsFs: versionerFsFromFolderCfg(cfg), 45 copyRangeMethod: cfg.CopyRangeMethod, 46 } 47 48 l.Debugf("instantiated %#v", s) 49 return s 50} 51 52// Archive moves the named file away to a version archive. If this function 53// returns nil, the named file does not exist any more (has been archived). 54func (v simple) Archive(filePath string) error { 55 err := archiveFile(v.copyRangeMethod, v.folderFs, v.versionsFs, filePath, TagFilename) 56 if err != nil { 57 return err 58 } 59 60 // Versions are sorted by timestamp in the file name, oldest first. 61 versions := findAllVersions(v.versionsFs, filePath) 62 if len(versions) > v.keep { 63 for _, toRemove := range versions[:len(versions)-v.keep] { 64 l.Debugln("cleaning out", toRemove) 65 err = v.versionsFs.Remove(toRemove) 66 if err != nil { 67 l.Warnln("removing old version:", err) 68 } 69 } 70 } 71 72 return nil 73} 74 75func (v simple) GetVersions() (map[string][]FileVersion, error) { 76 return retrieveVersions(v.versionsFs) 77} 78 79func (v simple) Restore(filepath string, versionTime time.Time) error { 80 return restoreFile(v.copyRangeMethod, v.versionsFs, v.folderFs, filepath, versionTime, TagFilename) 81} 82 83func (v simple) Clean(ctx context.Context) error { 84 return cleanByDay(ctx, v.versionsFs, v.cleanoutDays) 85} 86