浏览代码

all: Fix versioning path handling (#7407)

Simon Frei 4 年之前
父节点
当前提交
fff8805ff6

+ 0 - 5
gui/default/syncthing/core/syncthingController.js

@@ -72,7 +72,6 @@ angular.module('syncthing.core')
             simpleKeep: 5,
             staggeredMaxAge: 365,
             staggeredCleanInterval: 3600,
-            versionsPath: "",
             externalCommand: "",
         };
 
@@ -1912,9 +1911,6 @@ angular.module('syncthing.core')
 
             $scope.currentFolder._guiVersioning.cleanupIntervalS = +currentVersioning.cleanupIntervalS;
             $scope.currentFolder._guiVersioning.selector = currentVersioning.type;
-            if (currentVersioning.type !== 'external') {
-                $scope.currentFolder._guiVersioning.versionsPath = currentVersioning.params.versionsPath;
-            }
 
             // Apply parameters currently in use
             switch (currentVersioning.type) {
@@ -2053,7 +2049,6 @@ angular.module('syncthing.core')
             folderCfg.versioning.type = folderCfg._guiVersioning.selector;
             if ($scope.internalVersioningEnabled()) {
                 folderCfg.versioning.cleanupIntervalS = folderCfg._guiVersioning.cleanupIntervalS;
-                folderCfg.versioning.versionsPath = folderCfg._guiVersioning.versionsPath;
             }
             switch (folderCfg._guiVersioning.selector) {
             case "trashcan":

+ 2 - 2
gui/default/syncthing/folder/editFolderModalView.html

@@ -133,8 +133,8 @@
             </p>
           </div>
           <div class="form-group" ng-if="internalVersioningEnabled()">
-            <label translate for="versionsPath">Versions Path</label>
-            <input name="versionsPath" id="versionsPath" class="form-control" type="text" ng-model="currentFolder._guiVersioning.versionsPath" />
+            <label translate for="fsPath">Versions Path</label>
+            <input name="fsPath" id="fsPath" class="form-control" type="text" ng-model="currentFolder.versioning.fsPath" />
             <p translate class="help-block">Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).</p>
           </div>
           <div class="form-group" ng-if="currentFolder._guiVersioning.selector=='external'" ng-class="{'has-error': folderEditor.externalCommand.$invalid && folderEditor.externalCommand.$dirty}">

+ 0 - 5
gui/default/untrusted/syncthing/core/syncthingController.js

@@ -72,7 +72,6 @@ angular.module('syncthing.core')
             simpleKeep: 5,
             staggeredMaxAge: 365,
             staggeredCleanInterval: 3600,
-            versionsPath: "",
             externalCommand: "",
         };
 
@@ -1943,9 +1942,6 @@ angular.module('syncthing.core')
 
             $scope.currentFolder._guiVersioning.cleanupIntervalS = +currentVersioning.cleanupIntervalS;
             $scope.currentFolder._guiVersioning.selector = currentVersioning.type;
-            if (currentVersioning.type !== 'external') {
-                $scope.currentFolder._guiVersioning.versionsPath = currentVersioning.params.versionsPath;
-            }
 
             // Apply parameters currently in use
             switch (currentVersioning.type) {
@@ -2093,7 +2089,6 @@ angular.module('syncthing.core')
             folderCfg.versioning.type = folderCfg._guiVersioning.selector;
             if ($scope.internalVersioningEnabled()) {
                 folderCfg.versioning.cleanupIntervalS = folderCfg._guiVersioning.cleanupIntervalS;
-                folderCfg.versioning.versionsPath = folderCfg._guiVersioning.versionsPath;
             }
             switch (folderCfg._guiVersioning.selector) {
             case "trashcan":

+ 2 - 2
gui/default/untrusted/syncthing/folder/editFolderModalView.html

@@ -121,8 +121,8 @@
             </p>
           </div>
           <div class="form-group" ng-if="internalVersioningEnabled()">
-            <label translate for="versionsPath">Versions Path</label>
-            <input name="versionsPath" id="versionsPath" class="form-control" type="text" ng-model="currentFolder._guiVersioning.versionsPath" />
+            <label translate for="fsPath">Versions Path</label>
+            <input name="fsPath" id="fsPath" class="form-control" type="text" ng-model="currentFolder.versioning.fsPath" />
             <p translate class="help-block">Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).</p>
           </div>
           <div class="form-group" ng-if="currentFolder._guiVersioning.selector=='external'" ng-class="{'has-error': folderEditor.externalCommand.$invalid && folderEditor.externalCommand.$dirty}">

+ 1 - 1
lib/config/config.go

@@ -30,7 +30,7 @@ import (
 
 const (
 	OldestHandledVersion = 10
-	CurrentVersion       = 34
+	CurrentVersion       = 35
 	MaxRescanIntervalS   = 365 * 24 * 60 * 60
 )
 

+ 19 - 0
lib/config/migrations.go

@@ -27,6 +27,7 @@ import (
 // put the newest on top for readability.
 var (
 	migrations = migrationSet{
+		{35, migrateToConfigV35},
 		{34, migrateToConfigV34},
 		{33, migrateToConfigV33},
 		{32, migrateToConfigV32},
@@ -93,6 +94,24 @@ func (m migration) apply(cfg *Configuration) {
 	cfg.Version = m.targetVersion
 }
 
+func migrateToConfigV35(cfg *Configuration) {
+	for i, fcfg := range cfg.Folders {
+		params := fcfg.Versioning.Params
+		if params["fsType"] != "" {
+			var fsType fs.FilesystemType
+			_ = fsType.UnmarshalText([]byte(params["fsType"]))
+			cfg.Folders[i].Versioning.FSType = fsType
+		}
+		if params["versionsPath"] != "" && params["fsPath"] == "" {
+			params["fsPath"] = params["versionsPath"]
+		}
+		cfg.Folders[i].Versioning.FSPath = params["fsPath"]
+		delete(cfg.Folders[i].Versioning.Params, "fsType")
+		delete(cfg.Folders[i].Versioning.Params, "fsPath")
+		delete(cfg.Folders[i].Versioning.Params, "versionsPath")
+	}
+}
+
 func migrateToConfigV34(cfg *Configuration) {
 	cfg.Defaults.Folder.Path = cfg.Options.DeprecatedDefaultFolderPath
 	cfg.Options.DeprecatedDefaultFolderPath = ""

+ 10 - 3
lib/config/versioningconfiguration.go

@@ -11,14 +11,17 @@ import (
 	"encoding/xml"
 	"sort"
 
+	"github.com/syncthing/syncthing/lib/fs"
 	"github.com/syncthing/syncthing/lib/util"
 )
 
 // internalVersioningConfiguration is used in XML serialization
 type internalVersioningConfiguration struct {
-	Type             string          `xml:"type,attr,omitempty"`
-	Params           []internalParam `xml:"param"`
-	CleanupIntervalS int             `xml:"cleanupIntervalS" default:"3600"`
+	Type             string            `xml:"type,attr,omitempty"`
+	Params           []internalParam   `xml:"param"`
+	CleanupIntervalS int               `xml:"cleanupIntervalS" default:"3600"`
+	FSPath           string            `xml:"fsPath"`
+	FSType           fs.FilesystemType `xml:"fsType"`
 }
 
 type internalParam struct {
@@ -64,6 +67,8 @@ func (c *VersioningConfiguration) toInternal() internalVersioningConfiguration {
 	var tmp internalVersioningConfiguration
 	tmp.Type = c.Type
 	tmp.CleanupIntervalS = c.CleanupIntervalS
+	tmp.FSPath = c.FSPath
+	tmp.FSType = c.FSType
 	for k, v := range c.Params {
 		tmp.Params = append(tmp.Params, internalParam{k, v})
 	}
@@ -76,6 +81,8 @@ func (c *VersioningConfiguration) toInternal() internalVersioningConfiguration {
 func (c *VersioningConfiguration) fromInternal(intCfg internalVersioningConfiguration) {
 	c.Type = intCfg.Type
 	c.CleanupIntervalS = intCfg.CleanupIntervalS
+	c.FSPath = intCfg.FSPath
+	c.FSType = intCfg.FSType
 	c.Params = make(map[string]string, len(intCfg.Params))
 	for _, p := range intCfg.Params {
 		c.Params[p.Key] = p.Val

+ 110 - 29
lib/config/versioningconfiguration.pb.go

@@ -6,6 +6,7 @@ package config
 import (
 	fmt "fmt"
 	proto "github.com/gogo/protobuf/proto"
+	fs "github.com/syncthing/syncthing/lib/fs"
 	_ "github.com/syncthing/syncthing/proto/ext"
 	io "io"
 	math "math"
@@ -25,9 +26,11 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 // VersioningConfiguration is used in the code and for JSON serialization
 type VersioningConfiguration struct {
-	Type             string            `protobuf:"bytes,1,opt,name=type,proto3" json:"type" `
-	Params           map[string]string `protobuf:"bytes,2,rep,name=parameters,proto3" json:"params"  protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	CleanupIntervalS int               `protobuf:"varint,3,opt,name=cleanup_interval_s,json=cleanupIntervalS,proto3,casttype=int" json:"cleanupIntervalS" default:"3600"`
+	Type             string            `protobuf:"bytes,1,opt,name=type,proto3" json:"type" xml:"type,attr"`
+	Params           map[string]string `protobuf:"bytes,2,rep,name=parameters,proto3" json:"params" xml:"parameter" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	CleanupIntervalS int               `protobuf:"varint,3,opt,name=cleanup_interval_s,json=cleanupIntervalS,proto3,casttype=int" json:"cleanupIntervalS" xml:"cleanupIntervalS" default:"3600"`
+	FSPath           string            `protobuf:"bytes,4,opt,name=fs_path,json=fsPath,proto3" json:"fsPath" xml:"fsPath"`
+	FSType           fs.FilesystemType `protobuf:"varint,5,opt,name=fs_type,json=fsType,proto3,enum=fs.FilesystemType" json:"fsType" xml:"fsType"`
 }
 
 func (m *VersioningConfiguration) Reset()         { *m = VersioningConfiguration{} }
@@ -73,32 +76,40 @@ func init() {
 }
 
 var fileDescriptor_95ba6bdb22ffea81 = []byte{
-	// 385 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0xbf, 0xcb, 0xd3, 0x40,
-	0x18, 0xbe, 0x6b, 0xfa, 0x05, 0xbe, 0xfb, 0xfc, 0x45, 0x16, 0xc3, 0x07, 0xde, 0x85, 0x9a, 0x21,
-	0x2e, 0x49, 0xf1, 0x43, 0x91, 0x8e, 0x11, 0x07, 0x71, 0x91, 0x0a, 0x82, 0x2e, 0x25, 0x8d, 0xd7,
-	0xf4, 0x30, 0xbd, 0x84, 0xe4, 0x52, 0xcc, 0xe8, 0x20, 0x38, 0xaa, 0x7f, 0x81, 0x7f, 0x4e, 0xb7,
-	0x66, 0x74, 0x3a, 0x68, 0xb3, 0x65, 0xec, 0xd8, 0x49, 0x72, 0x09, 0xb5, 0x28, 0x6e, 0xcf, 0xf3,
-	0xbc, 0xcf, 0xf3, 0x3e, 0xe1, 0xcd, 0x21, 0x27, 0x66, 0x73, 0x2f, 0x4c, 0xf8, 0x82, 0x45, 0xde,
-	0x9a, 0x66, 0x39, 0x4b, 0x38, 0xe3, 0x51, 0x27, 0x14, 0x59, 0x20, 0x58, 0xc2, 0xdd, 0x34, 0x4b,
-	0x44, 0x62, 0xe8, 0x9d, 0x78, 0x7d, 0x49, 0x3f, 0x89, 0x4e, 0x1a, 0x7d, 0xd1, 0xd0, 0xfd, 0xb7,
-	0xa7, 0xd0, 0xf3, 0xf3, 0x90, 0x61, 0xa1, 0xa1, 0x28, 0x53, 0x6a, 0x42, 0x0b, 0x3a, 0x97, 0xfe,
-	0xad, 0x46, 0x12, 0xc5, 0x0f, 0x92, 0x80, 0xa9, 0x42, 0xc6, 0x67, 0x88, 0x50, 0x1a, 0x64, 0xc1,
-	0x8a, 0x0a, 0x9a, 0xe5, 0xe6, 0xc0, 0xd2, 0x9c, 0xab, 0xc7, 0x9e, 0xdb, 0xd5, 0xb8, 0xff, 0xd9,
-	0xeb, 0xbe, 0x3e, 0x25, 0x5e, 0x70, 0x91, 0x95, 0xfe, 0x78, 0x23, 0x09, 0xd8, 0x4b, 0xa2, 0xab,
-	0x41, 0xde, 0x48, 0xa2, 0xab, 0xa5, 0x79, 0xdb, 0x74, 0xd8, 0xda, 0x3d, 0xfb, 0x51, 0xd9, 0xbd,
-	0x63, 0x7a, 0x56, 0x6a, 0x84, 0xc8, 0x08, 0x63, 0x1a, 0xf0, 0x22, 0x9d, 0x31, 0x2e, 0x68, 0xb6,
-	0x0e, 0xe2, 0x59, 0x6e, 0x6a, 0x16, 0x74, 0x2e, 0xfc, 0x27, 0x8d, 0x24, 0xf7, 0xfa, 0xe9, 0xcb,
-	0x7e, 0xf8, 0xe6, 0x20, 0xc9, 0x9d, 0x0f, 0x74, 0x11, 0x14, 0xb1, 0x98, 0x8c, 0x6e, 0x9e, 0x8e,
-	0xc7, 0xa3, 0xa3, 0x24, 0x1a, 0xe3, 0xe2, 0xb8, 0xb5, 0x87, 0x2d, 0x9f, 0xfe, 0x13, 0xb9, 0x7e,
-	0x87, 0xee, 0xfe, 0xf5, 0xd5, 0xc6, 0x03, 0xa4, 0x7d, 0xa4, 0x65, 0x7f, 0x9c, 0xab, 0x46, 0x92,
-	0x96, 0xaa, 0xdb, 0xb4, 0xc0, 0x78, 0x88, 0x2e, 0xd6, 0x41, 0x5c, 0x50, 0x73, 0xa0, 0x0c, 0xb7,
-	0x1b, 0x49, 0x3a, 0x41, 0x59, 0x3a, 0x38, 0x19, 0x3c, 0x83, 0x93, 0xe1, 0xd7, 0xef, 0x36, 0xf0,
-	0x5f, 0x6d, 0x76, 0x18, 0x54, 0x3b, 0x0c, 0x36, 0x7b, 0x0c, 0xab, 0x3d, 0x86, 0xdf, 0x6a, 0x0c,
-	0x7e, 0xd6, 0x18, 0x56, 0x35, 0x06, 0xbf, 0x6a, 0x0c, 0xde, 0x3f, 0x8a, 0x98, 0x58, 0x16, 0x73,
-	0x37, 0x4c, 0x56, 0x5e, 0x5e, 0xf2, 0x50, 0x2c, 0x19, 0x8f, 0xce, 0xd0, 0x9f, 0x57, 0x30, 0xd7,
-	0xd5, 0xbf, 0xbd, 0xf9, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x0d, 0x6f, 0xcc, 0x1a, 0x02, 0x00,
-	0x00,
+	// 514 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x53, 0x4f, 0x6b, 0xdb, 0x4e,
+	0x10, 0x95, 0xfc, 0xef, 0x87, 0x95, 0x1f, 0x4d, 0x59, 0x0a, 0x15, 0x3e, 0x68, 0x8d, 0x70, 0x8b,
+	0x0a, 0x45, 0x0e, 0x09, 0x94, 0x62, 0x0a, 0x05, 0x97, 0xa6, 0x94, 0xf6, 0x10, 0x94, 0xd0, 0x43,
+	0x7b, 0x30, 0x6b, 0x77, 0x65, 0x2f, 0x91, 0x57, 0x42, 0xbb, 0x36, 0x51, 0x3f, 0x45, 0xe8, 0x27,
+	0xe8, 0xc7, 0xf1, 0xcd, 0x3e, 0xf6, 0xb4, 0x10, 0xfb, 0xa6, 0xa3, 0x8e, 0xe9, 0xa5, 0xec, 0xae,
+	0xa2, 0x9a, 0x94, 0xde, 0xe6, 0xcd, 0x7b, 0xf3, 0x66, 0x46, 0xb3, 0xb2, 0xbc, 0x88, 0x8c, 0xfb,
+	0x93, 0x98, 0x86, 0x64, 0xda, 0x5f, 0xe2, 0x94, 0x91, 0x98, 0x12, 0x3a, 0xd5, 0x89, 0x45, 0x8a,
+	0x38, 0x89, 0xa9, 0x9f, 0xa4, 0x31, 0x8f, 0x41, 0x4b, 0x27, 0x3b, 0x40, 0x56, 0x84, 0xac, 0xcf,
+	0xb3, 0x04, 0x33, 0xcd, 0x75, 0xda, 0xf8, 0x8a, 0xeb, 0xd0, 0xfd, 0xd5, 0xb0, 0x1e, 0x7f, 0xaa,
+	0x8c, 0xde, 0xec, 0x1b, 0x81, 0x57, 0x56, 0x43, 0x56, 0xd9, 0x66, 0xd7, 0xf4, 0xda, 0x43, 0x2f,
+	0x17, 0x50, 0xe1, 0x42, 0xc0, 0xc3, 0xab, 0x79, 0x34, 0x70, 0x25, 0x78, 0x8e, 0x38, 0x4f, 0xdd,
+	0x7c, 0xdd, 0x6b, 0x57, 0x28, 0x50, 0x2a, 0x70, 0x6d, 0x5a, 0x56, 0x82, 0x52, 0x34, 0xc7, 0x1c,
+	0xa7, 0xcc, 0xae, 0x75, 0xeb, 0xde, 0xc1, 0x71, 0xdf, 0xd7, 0x63, 0xf9, 0xff, 0xe8, 0xe9, 0x9f,
+	0x55, 0x15, 0x6f, 0x29, 0x4f, 0xb3, 0xe1, 0xeb, 0x95, 0x80, 0xc6, 0x56, 0xc0, 0x96, 0x22, 0x58,
+	0x2e, 0x60, 0x4b, 0x99, 0xb2, 0x6a, 0x8a, 0xaa, 0x87, 0x5b, 0xac, 0x7b, 0x25, 0xf9, 0x7d, 0xd3,
+	0x2b, 0x0b, 0x82, 0xbd, 0x19, 0xc0, 0x37, 0x0b, 0x4c, 0x22, 0x8c, 0xe8, 0x22, 0x19, 0x11, 0xca,
+	0x71, 0xba, 0x44, 0xd1, 0x88, 0xd9, 0xf5, 0xae, 0xe9, 0x35, 0x87, 0x1f, 0x73, 0x01, 0x1f, 0x96,
+	0xec, 0xfb, 0x92, 0x3c, 0x2f, 0x04, 0x7c, 0xa2, 0x9a, 0xdc, 0x27, 0xdc, 0xee, 0x57, 0x1c, 0xa2,
+	0x45, 0xc4, 0x07, 0xee, 0xc9, 0x8b, 0xa3, 0x23, 0xf7, 0x56, 0xc0, 0x3a, 0xa1, 0xfc, 0x76, 0xdd,
+	0x6b, 0x48, 0x1c, 0xfc, 0xe5, 0x04, 0xde, 0x59, 0xff, 0x85, 0x6c, 0x94, 0x20, 0x3e, 0xb3, 0x1b,
+	0xea, 0x7b, 0xfa, 0x72, 0xab, 0xd3, 0xf3, 0x33, 0xc4, 0x67, 0x72, 0xab, 0x90, 0xc9, 0xa8, 0x10,
+	0xf0, 0x7f, 0xd5, 0x50, 0x43, 0x57, 0x2e, 0xa2, 0x35, 0x41, 0xa9, 0x00, 0x5f, 0x94, 0x91, 0x3a,
+	0x4c, 0xb3, 0x6b, 0x7a, 0x0f, 0x8e, 0x81, 0x1f, 0x32, 0xff, 0x94, 0x44, 0x98, 0x65, 0x8c, 0xe3,
+	0xf9, 0x45, 0x96, 0xe0, 0x3b, 0x73, 0x19, 0x6b, 0xf3, 0x0b, 0x7d, 0xb8, 0x3b, 0x73, 0x09, 0x4b,
+	0x73, 0x19, 0x06, 0xa5, 0xa2, 0x33, 0xb7, 0x0e, 0xef, 0x5d, 0x00, 0x3c, 0xb5, 0xea, 0x97, 0x38,
+	0x2b, 0x1f, 0xc1, 0xa3, 0x5c, 0x40, 0x09, 0x0b, 0x01, 0xdb, 0xca, 0xea, 0x12, 0x67, 0x6e, 0x20,
+	0x33, 0xc0, 0xb7, 0x9a, 0x4b, 0x14, 0x2d, 0xb0, 0x5d, 0x53, 0x4a, 0x3b, 0x17, 0x50, 0x27, 0x0a,
+	0x01, 0x0f, 0x94, 0x56, 0x21, 0x37, 0xd0, 0xd9, 0x41, 0xed, 0xa5, 0x39, 0xfc, 0xb0, 0xba, 0x71,
+	0x8c, 0xcd, 0x8d, 0x63, 0xac, 0xb6, 0x8e, 0xb9, 0xd9, 0x3a, 0xe6, 0xf5, 0xce, 0x31, 0x7e, 0xec,
+	0x1c, 0x73, 0xb3, 0x73, 0x8c, 0x9f, 0x3b, 0xc7, 0xf8, 0xfc, 0x6c, 0x4a, 0xf8, 0x6c, 0x31, 0xf6,
+	0x27, 0xf1, 0xbc, 0xcf, 0x32, 0x3a, 0xe1, 0x33, 0x42, 0xa7, 0x7b, 0xd1, 0x9f, 0xff, 0x61, 0xdc,
+	0x52, 0x2f, 0xfa, 0xe4, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd1, 0x04, 0xd0, 0xd5, 0x24, 0x03,
+	0x00, 0x00,
 }
 
 func (m *VersioningConfiguration) Marshal() (dAtA []byte, err error) {
@@ -121,6 +132,18 @@ func (m *VersioningConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error)
 	_ = i
 	var l int
 	_ = l
+	if m.FSType != 0 {
+		i = encodeVarintVersioningconfiguration(dAtA, i, uint64(m.FSType))
+		i--
+		dAtA[i] = 0x28
+	}
+	if len(m.FSPath) > 0 {
+		i -= len(m.FSPath)
+		copy(dAtA[i:], m.FSPath)
+		i = encodeVarintVersioningconfiguration(dAtA, i, uint64(len(m.FSPath)))
+		i--
+		dAtA[i] = 0x22
+	}
 	if m.CleanupIntervalS != 0 {
 		i = encodeVarintVersioningconfiguration(dAtA, i, uint64(m.CleanupIntervalS))
 		i--
@@ -187,6 +210,13 @@ func (m *VersioningConfiguration) ProtoSize() (n int) {
 	if m.CleanupIntervalS != 0 {
 		n += 1 + sovVersioningconfiguration(uint64(m.CleanupIntervalS))
 	}
+	l = len(m.FSPath)
+	if l > 0 {
+		n += 1 + l + sovVersioningconfiguration(uint64(l))
+	}
+	if m.FSType != 0 {
+		n += 1 + sovVersioningconfiguration(uint64(m.FSType))
+	}
 	return n
 }
 
@@ -403,6 +433,57 @@ func (m *VersioningConfiguration) Unmarshal(dAtA []byte) error {
 					break
 				}
 			}
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field FSPath", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowVersioningconfiguration
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthVersioningconfiguration
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthVersioningconfiguration
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.FSPath = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field FSType", wireType)
+			}
+			m.FSType = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowVersioningconfiguration
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.FSType |= fs.FilesystemType(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 			iNdEx = preIndex
 			skippy, err := skipVersioningconfiguration(dAtA[iNdEx:])

+ 0 - 2
lib/versioner/staggered.go

@@ -41,8 +41,6 @@ func newStaggered(cfg config.FolderConfiguration) Versioner {
 		maxAge = 31536000 // Default: ~1 year
 	}
 
-	// Backwards compatibility
-	params["fsPath"] = params["versionsPath"]
 	versionsFs := versionerFsFromFolderCfg(cfg)
 
 	s := &staggered{

+ 2 - 4
lib/versioner/staggered_test.go

@@ -145,10 +145,8 @@ func TestCreateVersionPath(t *testing.T) {
 		ID:   "default",
 		Path: tmpDir,
 		Versioning: config.VersioningConfiguration{
-			Type: "staggered",
-			Params: map[string]string{
-				"versionsPath": versionsDir,
-			},
+			Type:   "staggered",
+			FSPath: versionsDir,
 		},
 	}
 

+ 3 - 4
lib/versioner/trashcan_test.go

@@ -33,10 +33,8 @@ func TestTrashcanArchiveRestoreSwitcharoo(t *testing.T) {
 		FilesystemType: fs.FilesystemTypeBasic,
 		Path:           tmpDir1,
 		Versioning: config.VersioningConfiguration{
-			Params: map[string]string{
-				"fsType": "basic",
-				"fsPath": tmpDir2,
-			},
+			FSType: fs.FilesystemTypeBasic,
+			FSPath: tmpDir2,
 		},
 	}
 	folderFs := cfg.Filesystem()
@@ -101,6 +99,7 @@ func TestTrashcanArchiveRestoreSwitcharoo(t *testing.T) {
 }
 
 func readFile(t *testing.T, filesystem fs.Filesystem, name string) string {
+	t.Helper()
 	fd, err := filesystem.Open(name)
 	if err != nil {
 		t.Fatal(err)

+ 4 - 12
lib/versioner/util.go

@@ -256,23 +256,15 @@ func restoreFile(method fs.CopyRangeMethod, src, dst fs.Filesystem, filePath str
 }
 
 func versionerFsFromFolderCfg(cfg config.FolderConfiguration) (versionsFs fs.Filesystem) {
-	params := cfg.Versioning.Params
 	folderFs := cfg.Filesystem()
-	if params["fsType"] == "" && params["fsPath"] == "" {
+	if cfg.Versioning.FSPath == "" {
 		versionsFs = fs.NewFilesystem(folderFs.Type(), filepath.Join(folderFs.URI(), ".stversions"))
-
-	} else if params["fsType"] == "" {
-		uri := params["fsPath"]
+	} else if cfg.Versioning.FSType == fs.FilesystemTypeBasic && !filepath.IsAbs(cfg.Versioning.FSPath) {
 		// We only know how to deal with relative folders for basic filesystems, as that's the only one we know
 		// how to check if it's absolute or relative.
-		if folderFs.Type() == fs.FilesystemTypeBasic && !filepath.IsAbs(params["fsPath"]) {
-			uri = filepath.Join(folderFs.URI(), params["fsPath"])
-		}
-		versionsFs = fs.NewFilesystem(folderFs.Type(), uri)
+		versionsFs = fs.NewFilesystem(cfg.Versioning.FSType, filepath.Join(folderFs.URI(), cfg.Versioning.FSPath))
 	} else {
-		var fsType fs.FilesystemType
-		_ = fsType.UnmarshalText([]byte(params["fsType"]))
-		versionsFs = fs.NewFilesystem(fsType, params["fsPath"])
+		versionsFs = fs.NewFilesystem(cfg.Versioning.FSType, cfg.Versioning.FSPath)
 	}
 	l.Debugf("%s (%s) folder using %s (%s) versioner dir", folderFs.URI(), folderFs.Type(), versionsFs.URI(), versionsFs.Type())
 	return

+ 5 - 3
proto/lib/config/versioningconfiguration.proto

@@ -2,13 +2,15 @@ syntax = "proto3";
 
 package config;
 
+import "lib/fs/types.proto";
+
 import "ext.proto";
 
 // VersioningConfiguration is used in the code and for JSON serialization
 message VersioningConfiguration {
-    option (ext.xml_tags) = false;
-
-    string              type               = 1;
+    string              type               = 1[(ext.xml) = "type,attr"];
     map<string, string> parameters         = 2 [(ext.goname) = "Params", (ext.json) = "params"];
     int32               cleanup_interval_s = 3 [(ext.default) = "3600"];
+    string              fs_path            = 4 [(ext.goname) = "FSPath"];
+    fs.FilesystemType   fs_type            = 5 [(ext.goname) = "FSType"];
 }