mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-23 11:28:59 +00:00
lib/config: Do introductions in a single config change (#6162)
This commit is contained in:
parent
90d85fd0a2
commit
57d668ed1d
@ -1252,14 +1252,20 @@ func (m *model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
if deviceCfg.Introducer {
|
if deviceCfg.Introducer {
|
||||||
foldersDevices, introduced := m.handleIntroductions(deviceCfg, cm)
|
folders, devices, foldersDevices, introduced := m.handleIntroductions(deviceCfg, cm)
|
||||||
if introduced {
|
folders, devices, deintroduced := m.handleDeintroductions(deviceCfg, foldersDevices, folders, devices)
|
||||||
|
if introduced || deintroduced {
|
||||||
changed = true
|
changed = true
|
||||||
|
cfg := m.cfg.RawCopy()
|
||||||
|
cfg.Folders = make([]config.FolderConfiguration, 0, len(folders))
|
||||||
|
for _, fcfg := range folders {
|
||||||
|
cfg.Folders = append(cfg.Folders, fcfg)
|
||||||
}
|
}
|
||||||
// If permitted, check if the introducer has unshare devices/folders with
|
cfg.Devices = make([]config.DeviceConfiguration, len(devices))
|
||||||
// some of the devices/folders that we know were introduced to us by him.
|
for _, dcfg := range devices {
|
||||||
if !deviceCfg.SkipIntroductionRemovals && m.handleDeintroductions(deviceCfg, cm, foldersDevices) {
|
cfg.Devices = append(cfg.Devices, dcfg)
|
||||||
changed = true
|
}
|
||||||
|
m.cfg.Replace(cfg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1270,12 +1276,11 @@ func (m *model) ClusterConfig(deviceID protocol.DeviceID, cm protocol.ClusterCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleIntroductions handles adding devices/shares that are shared by an introducer device
|
// handleIntroductions handles adding devices/folders that are shared by an introducer device
|
||||||
func (m *model) handleIntroductions(introducerCfg config.DeviceConfiguration, cm protocol.ClusterConfig) (folderDeviceSet, bool) {
|
func (m *model) handleIntroductions(introducerCfg config.DeviceConfiguration, cm protocol.ClusterConfig) (map[string]config.FolderConfiguration, map[protocol.DeviceID]config.DeviceConfiguration, folderDeviceSet, bool) {
|
||||||
// This device is an introducer. Go through the announced lists of folders
|
|
||||||
// and devices and add what we are missing, remove what we have extra that
|
|
||||||
// has been introducer by the introducer.
|
|
||||||
changed := false
|
changed := false
|
||||||
|
folders := m.cfg.Folders()
|
||||||
|
devices := m.cfg.Devices()
|
||||||
|
|
||||||
foldersDevices := make(folderDeviceSet)
|
foldersDevices := make(folderDeviceSet)
|
||||||
|
|
||||||
@ -1285,12 +1290,14 @@ func (m *model) handleIntroductions(introducerCfg config.DeviceConfiguration, cm
|
|||||||
// with devices that we have in common, yet are currently not sharing
|
// with devices that we have in common, yet are currently not sharing
|
||||||
// the folder.
|
// the folder.
|
||||||
|
|
||||||
fcfg, ok := m.cfg.Folder(folder.ID)
|
fcfg, ok := folders[folder.ID]
|
||||||
if !ok {
|
if !ok {
|
||||||
// Don't have this folder, carry on.
|
// Don't have this folder, carry on.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
folderChanged := false
|
||||||
|
|
||||||
for _, device := range folder.Devices {
|
for _, device := range folder.Devices {
|
||||||
// No need to share with self.
|
// No need to share with self.
|
||||||
if device.ID == m.id {
|
if device.ID == m.id {
|
||||||
@ -1301,7 +1308,7 @@ func (m *model) handleIntroductions(introducerCfg config.DeviceConfiguration, cm
|
|||||||
|
|
||||||
if _, ok := m.cfg.Devices()[device.ID]; !ok {
|
if _, ok := m.cfg.Devices()[device.ID]; !ok {
|
||||||
// The device is currently unknown. Add it to the config.
|
// The device is currently unknown. Add it to the config.
|
||||||
m.introduceDevice(device, introducerCfg)
|
devices[device.ID] = m.introduceDevice(device, introducerCfg)
|
||||||
} else if fcfg.SharedWith(device.ID) {
|
} else if fcfg.SharedWith(device.ID) {
|
||||||
// We already share the folder with this device, so
|
// We already share the folder with this device, so
|
||||||
// nothing to do.
|
// nothing to do.
|
||||||
@ -1315,36 +1322,41 @@ func (m *model) handleIntroductions(introducerCfg config.DeviceConfiguration, cm
|
|||||||
DeviceID: device.ID,
|
DeviceID: device.ID,
|
||||||
IntroducedBy: introducerCfg.DeviceID,
|
IntroducedBy: introducerCfg.DeviceID,
|
||||||
})
|
})
|
||||||
|
folderChanged = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if folderChanged {
|
||||||
|
folders[fcfg.ID] = fcfg
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if changed {
|
|
||||||
m.cfg.SetFolder(fcfg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return foldersDevices, changed
|
return folders, devices, foldersDevices, changed
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleDeintroductions handles removals of devices/shares that are removed by an introducer device
|
// handleDeintroductions handles removals of devices/shares that are removed by an introducer device
|
||||||
func (m *model) handleDeintroductions(introducerCfg config.DeviceConfiguration, cm protocol.ClusterConfig, foldersDevices folderDeviceSet) bool {
|
func (m *model) handleDeintroductions(introducerCfg config.DeviceConfiguration, foldersDevices folderDeviceSet, folders map[string]config.FolderConfiguration, devices map[protocol.DeviceID]config.DeviceConfiguration) (map[string]config.FolderConfiguration, map[protocol.DeviceID]config.DeviceConfiguration, bool) {
|
||||||
|
if introducerCfg.SkipIntroductionRemovals {
|
||||||
|
return folders, devices, false
|
||||||
|
}
|
||||||
|
|
||||||
changed := false
|
changed := false
|
||||||
devicesNotIntroduced := make(map[protocol.DeviceID]struct{})
|
devicesNotIntroduced := make(map[protocol.DeviceID]struct{})
|
||||||
|
|
||||||
folders := m.cfg.FolderList()
|
|
||||||
// Check if we should unshare some folders, if the introducer has unshared them.
|
// Check if we should unshare some folders, if the introducer has unshared them.
|
||||||
for i := range folders {
|
for folderID, folderCfg := range folders {
|
||||||
for k := 0; k < len(folders[i].Devices); k++ {
|
for k := 0; k < len(folderCfg.Devices); k++ {
|
||||||
if folders[i].Devices[k].IntroducedBy != introducerCfg.DeviceID {
|
if folderCfg.Devices[k].IntroducedBy != introducerCfg.DeviceID {
|
||||||
devicesNotIntroduced[folders[i].Devices[k].DeviceID] = struct{}{}
|
devicesNotIntroduced[folderCfg.Devices[k].DeviceID] = struct{}{}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !foldersDevices.has(folders[i].Devices[k].DeviceID, folders[i].ID) {
|
if !foldersDevices.has(folderCfg.Devices[k].DeviceID, folderCfg.ID) {
|
||||||
// We could not find that folder shared on the
|
// We could not find that folder shared on the
|
||||||
// introducer with the device that was introduced to us.
|
// introducer with the device that was introduced to us.
|
||||||
// We should follow and unshare as well.
|
// We should follow and unshare as well.
|
||||||
l.Infof("Unsharing folder %s with %v as introducer %v no longer shares the folder with that device", folders[i].Description(), folders[i].Devices[k].DeviceID, folders[i].Devices[k].IntroducedBy)
|
l.Infof("Unsharing folder %s with %v as introducer %v no longer shares the folder with that device", folderCfg.Description(), folderCfg.Devices[k].DeviceID, folderCfg.Devices[k].IntroducedBy)
|
||||||
folders[i].Devices = append(folders[i].Devices[:k], folders[i].Devices[k+1:]...)
|
folderCfg.Devices = append(folderCfg.Devices[:k], folderCfg.Devices[k+1:]...)
|
||||||
|
folders[folderID] = folderCfg
|
||||||
k--
|
k--
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
@ -1354,9 +1366,7 @@ func (m *model) handleDeintroductions(introducerCfg config.DeviceConfiguration,
|
|||||||
// Check if we should remove some devices, if the introducer no longer
|
// Check if we should remove some devices, if the introducer no longer
|
||||||
// shares any folder with them. Yet do not remove if we share other
|
// shares any folder with them. Yet do not remove if we share other
|
||||||
// folders that haven't been introduced by the introducer.
|
// folders that haven't been introduced by the introducer.
|
||||||
devMap := m.cfg.Devices()
|
for deviceID, device := range devices {
|
||||||
devices := make([]config.DeviceConfiguration, 0, len(devMap))
|
|
||||||
for deviceID, device := range devMap {
|
|
||||||
if device.IntroducedBy == introducerCfg.DeviceID {
|
if device.IntroducedBy == introducerCfg.DeviceID {
|
||||||
if !foldersDevices.hasDevice(deviceID) {
|
if !foldersDevices.hasDevice(deviceID) {
|
||||||
if _, ok := devicesNotIntroduced[deviceID]; !ok {
|
if _, ok := devicesNotIntroduced[deviceID]; !ok {
|
||||||
@ -1364,22 +1374,15 @@ func (m *model) handleDeintroductions(introducerCfg config.DeviceConfiguration,
|
|||||||
// device, remove the device.
|
// device, remove the device.
|
||||||
l.Infof("Removing device %v as introducer %v no longer shares any folders with that device", deviceID, device.IntroducedBy)
|
l.Infof("Removing device %v as introducer %v no longer shares any folders with that device", deviceID, device.IntroducedBy)
|
||||||
changed = true
|
changed = true
|
||||||
|
delete(devices, deviceID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
l.Infof("Would have removed %v as %v no longer shares any folders, yet there are other folders that are shared with this device that haven't been introduced by this introducer.", deviceID, device.IntroducedBy)
|
l.Infof("Would have removed %v as %v no longer shares any folders, yet there are other folders that are shared with this device that haven't been introduced by this introducer.", deviceID, device.IntroducedBy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
devices = append(devices, device)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if changed {
|
return folders, devices, changed
|
||||||
cfg := m.cfg.RawCopy()
|
|
||||||
cfg.Folders = folders
|
|
||||||
cfg.Devices = devices
|
|
||||||
m.cfg.Replace(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleAutoAccepts handles adding and sharing folders for devices that have
|
// handleAutoAccepts handles adding and sharing folders for devices that have
|
||||||
@ -1430,7 +1433,7 @@ func (m *model) handleAutoAccepts(deviceCfg config.DeviceConfiguration, folder p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *model) introduceDevice(device protocol.Device, introducerCfg config.DeviceConfiguration) {
|
func (m *model) introduceDevice(device protocol.Device, introducerCfg config.DeviceConfiguration) config.DeviceConfiguration {
|
||||||
addresses := []string{"dynamic"}
|
addresses := []string{"dynamic"}
|
||||||
for _, addr := range device.Addresses {
|
for _, addr := range device.Addresses {
|
||||||
if addr != "dynamic" {
|
if addr != "dynamic" {
|
||||||
@ -1455,7 +1458,7 @@ func (m *model) introduceDevice(device protocol.Device, introducerCfg config.Dev
|
|||||||
newDeviceCfg.SkipIntroductionRemovals = device.SkipIntroductionRemovals
|
newDeviceCfg.SkipIntroductionRemovals = device.SkipIntroductionRemovals
|
||||||
}
|
}
|
||||||
|
|
||||||
m.cfg.SetDevice(newDeviceCfg)
|
return newDeviceCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closed is called when a connection has been closed
|
// Closed is called when a connection has been closed
|
||||||
|
Loading…
Reference in New Issue
Block a user