mirror of
https://github.com/octoleo/syncthing.git
synced 2025-02-02 11:58:28 +00:00
lib/config, lib/model: Include paused folders in cluster config (fixes #4897)
This commit is contained in:
parent
56cf2db68b
commit
f6458d1b8f
@ -325,13 +325,18 @@ func (cfg *Configuration) clean() error {
|
|||||||
existingDevices[device.DeviceID] = true
|
existingDevices[device.DeviceID] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the device list is free from duplicates
|
// Ensure that the device list is
|
||||||
|
// - free from duplicates
|
||||||
|
// - sorted by ID
|
||||||
cfg.Devices = ensureNoDuplicateDevices(cfg.Devices)
|
cfg.Devices = ensureNoDuplicateDevices(cfg.Devices)
|
||||||
|
|
||||||
sort.Sort(DeviceConfigurationList(cfg.Devices))
|
sort.Sort(DeviceConfigurationList(cfg.Devices))
|
||||||
// Ensure that any loose devices are not present in the wrong places
|
|
||||||
// Ensure that there are no duplicate devices
|
// Ensure that the folder list is sorted by ID
|
||||||
// Ensure that the versioning configuration parameter map is not nil
|
sort.Sort(FolderConfigurationList(cfg.Folders))
|
||||||
|
// Ensure that in all folder configs
|
||||||
|
// - any loose devices are not present in the wrong places
|
||||||
|
// - there are no duplicate devices
|
||||||
|
// - the versioning configuration parameter map is not nil
|
||||||
for i := range cfg.Folders {
|
for i := range cfg.Folders {
|
||||||
cfg.Folders[i].Devices = ensureExistingDevices(cfg.Folders[i].Devices, existingDevices)
|
cfg.Folders[i].Devices = ensureExistingDevices(cfg.Folders[i].Devices, existingDevices)
|
||||||
cfg.Folders[i].Devices = ensureNoDuplicateFolderDevices(cfg.Folders[i].Devices)
|
cfg.Folders[i].Devices = ensureNoDuplicateFolderDevices(cfg.Folders[i].Devices)
|
||||||
|
@ -278,3 +278,17 @@ func (l FolderDeviceConfigurationList) Len() int {
|
|||||||
func (f *FolderConfiguration) CheckFreeSpace() (err error) {
|
func (f *FolderConfiguration) CheckFreeSpace() (err error) {
|
||||||
return checkFreeSpace(f.MinDiskFree, f.Filesystem())
|
return checkFreeSpace(f.MinDiskFree, f.Filesystem())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FolderConfigurationList []FolderConfiguration
|
||||||
|
|
||||||
|
func (l FolderConfigurationList) Len() int {
|
||||||
|
return len(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l FolderConfigurationList) Less(a, b int) bool {
|
||||||
|
return l[a].ID < l[b].ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l FolderConfigurationList) Swap(a, b int) {
|
||||||
|
l[a], l[b] = l[b], l[a]
|
||||||
|
}
|
||||||
|
@ -267,6 +267,13 @@ func (w *Wrapper) Folders() map[string]FolderConfiguration {
|
|||||||
return w.folderMap
|
return w.folderMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FolderList returns a slice of folders.
|
||||||
|
func (w *Wrapper) FolderList() []FolderConfiguration {
|
||||||
|
w.mut.Lock()
|
||||||
|
defer w.mut.Unlock()
|
||||||
|
return append([]FolderConfiguration(nil), w.cfg.Folders...)
|
||||||
|
}
|
||||||
|
|
||||||
// SetFolder adds a new folder to the configuration, or overwrites an existing
|
// SetFolder adds a new folder to the configuration, or overwrites an existing
|
||||||
// folder with the same ID.
|
// folder with the same ID.
|
||||||
func (w *Wrapper) SetFolder(fld FolderConfiguration) (Waiter, error) {
|
func (w *Wrapper) SetFolder(fld FolderConfiguration) (Waiter, error) {
|
||||||
|
@ -2154,17 +2154,14 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
|
|||||||
var message protocol.ClusterConfig
|
var message protocol.ClusterConfig
|
||||||
|
|
||||||
m.fmut.RLock()
|
m.fmut.RLock()
|
||||||
// The list of folders in the message is sorted, so we always get the
|
folderFiles := m.folderFiles
|
||||||
// same order.
|
m.fmut.RUnlock()
|
||||||
folders := m.deviceFolders[device]
|
|
||||||
sort.Strings(folders)
|
|
||||||
|
|
||||||
for _, folder := range folders {
|
var fs *db.FileSet
|
||||||
folderCfg := m.cfg.Folders()[folder]
|
|
||||||
fs := m.folderFiles[folder]
|
|
||||||
|
|
||||||
|
for _, folderCfg := range m.cfg.FolderList() {
|
||||||
protocolFolder := protocol.Folder{
|
protocolFolder := protocol.Folder{
|
||||||
ID: folder,
|
ID: folderCfg.ID,
|
||||||
Label: folderCfg.Label,
|
Label: folderCfg.Label,
|
||||||
ReadOnly: folderCfg.Type == config.FolderTypeSendOnly,
|
ReadOnly: folderCfg.Type == config.FolderTypeSendOnly,
|
||||||
IgnorePermissions: folderCfg.IgnorePerms,
|
IgnorePermissions: folderCfg.IgnorePerms,
|
||||||
@ -2173,36 +2170,37 @@ func (m *Model) generateClusterConfig(device protocol.DeviceID) protocol.Cluster
|
|||||||
Paused: folderCfg.Paused,
|
Paused: folderCfg.Paused,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Devices are sorted, so we always get the same order.
|
if !folderCfg.Paused {
|
||||||
for _, device := range m.folderDevices.sortedDevices(folder) {
|
fs = folderFiles[folderCfg.ID]
|
||||||
deviceCfg := m.cfg.Devices()[device]
|
|
||||||
|
|
||||||
var indexID protocol.IndexID
|
|
||||||
var maxSequence int64
|
|
||||||
if device == m.id {
|
|
||||||
indexID = fs.IndexID(protocol.LocalDeviceID)
|
|
||||||
maxSequence = fs.Sequence(protocol.LocalDeviceID)
|
|
||||||
} else {
|
|
||||||
indexID = fs.IndexID(device)
|
|
||||||
maxSequence = fs.Sequence(device)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, device := range folderCfg.Devices {
|
||||||
|
deviceCfg, _ := m.cfg.Device(device.DeviceID)
|
||||||
|
|
||||||
protocolDevice := protocol.Device{
|
protocolDevice := protocol.Device{
|
||||||
ID: device,
|
ID: deviceCfg.DeviceID,
|
||||||
Name: deviceCfg.Name,
|
Name: deviceCfg.Name,
|
||||||
Addresses: deviceCfg.Addresses,
|
Addresses: deviceCfg.Addresses,
|
||||||
Compression: deviceCfg.Compression,
|
Compression: deviceCfg.Compression,
|
||||||
CertName: deviceCfg.CertName,
|
CertName: deviceCfg.CertName,
|
||||||
Introducer: deviceCfg.Introducer,
|
Introducer: deviceCfg.Introducer,
|
||||||
IndexID: indexID,
|
}
|
||||||
MaxSequence: maxSequence,
|
|
||||||
|
if !folderCfg.Paused {
|
||||||
|
if deviceCfg.DeviceID == m.id {
|
||||||
|
protocolDevice.IndexID = fs.IndexID(protocol.LocalDeviceID)
|
||||||
|
protocolDevice.MaxSequence = fs.Sequence(protocol.LocalDeviceID)
|
||||||
|
} else {
|
||||||
|
protocolDevice.IndexID = fs.IndexID(deviceCfg.DeviceID)
|
||||||
|
protocolDevice.MaxSequence = fs.Sequence(deviceCfg.DeviceID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protocolFolder.Devices = append(protocolFolder.Devices, protocolDevice)
|
protocolFolder.Devices = append(protocolFolder.Devices, protocolDevice)
|
||||||
}
|
}
|
||||||
|
|
||||||
message.Folders = append(message.Folders, protocolFolder)
|
message.Folders = append(message.Folders, protocolFolder)
|
||||||
}
|
}
|
||||||
m.fmut.RUnlock()
|
|
||||||
|
|
||||||
return message
|
return message
|
||||||
}
|
}
|
||||||
|
@ -1043,6 +1043,32 @@ func TestIntroducer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIssue4897(t *testing.T) {
|
||||||
|
_, m := newState(config.Configuration{
|
||||||
|
Devices: []config.DeviceConfiguration{
|
||||||
|
{
|
||||||
|
DeviceID: device1,
|
||||||
|
Introducer: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Folders: []config.FolderConfiguration{
|
||||||
|
{
|
||||||
|
ID: "folder1",
|
||||||
|
Path: "testdata",
|
||||||
|
Devices: []config.FolderDeviceConfiguration{
|
||||||
|
{DeviceID: device1},
|
||||||
|
},
|
||||||
|
Paused: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
cm := m.generateClusterConfig(device1)
|
||||||
|
if l := len(cm.Folders); l != 1 {
|
||||||
|
t.Errorf("Cluster config contains %v folders, expected 1", l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAutoAcceptRejected(t *testing.T) {
|
func TestAutoAcceptRejected(t *testing.T) {
|
||||||
// Nothing happens if AutoAcceptFolders not set
|
// Nothing happens if AutoAcceptFolders not set
|
||||||
tcfg := defaultAutoAcceptCfg.Copy()
|
tcfg := defaultAutoAcceptCfg.Copy()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user