Let server side decide if restart is needed on config change

This commit is contained in:
Jakob Borg 2014-06-07 04:00:46 +02:00
parent 5a2328d9a5
commit df381fd03f
4 changed files with 69 additions and 13 deletions

File diff suppressed because one or more lines are too long

View File

@ -16,6 +16,7 @@ import (
"net" "net"
"net/http" "net/http"
"path/filepath" "path/filepath"
"reflect"
"runtime" "runtime"
"sync" "sync"
"time" "time"
@ -210,9 +211,43 @@ func restPostConfig(req *http.Request) {
newCfg.GUI.Password = string(hash) newCfg.GUI.Password = string(hash)
} }
} }
// Figure out if any changes require a restart
if len(cfg.Repositories) != len(newCfg.Repositories) {
configInSync = false
} else {
om := cfg.RepoMap()
nm := newCfg.RepoMap()
for id := range om {
if !reflect.DeepEqual(om[id], nm[id]) {
configInSync = false
break
}
}
}
if len(cfg.Nodes) != len(newCfg.Nodes) {
configInSync = false
} else {
om := cfg.NodeMap()
nm := newCfg.NodeMap()
for k := range om {
if _, ok := nm[k]; !ok {
configInSync = false
break
}
}
}
if !reflect.DeepEqual(cfg.Options, newCfg.Options) {
configInSync = false
}
// Activate and save
cfg = newCfg cfg = newCfg
saveConfig() saveConfig()
configInSync = false
} }
} }

View File

@ -126,6 +126,22 @@ type GUIConfiguration struct {
APIKey string `xml:"apikey,omitempty"` APIKey string `xml:"apikey,omitempty"`
} }
func (cfg *Configuration) NodeMap() map[string]NodeConfiguration {
m := make(map[string]NodeConfiguration, len(cfg.Nodes))
for _, n := range cfg.Nodes {
m[n.NodeID] = n
}
return m
}
func (cfg *Configuration) RepoMap() map[string]RepositoryConfiguration {
m := make(map[string]RepositoryConfiguration, len(cfg.Repositories))
for _, r := range cfg.Repositories {
m[r.ID] = r
}
return m
}
func setDefaults(data interface{}) error { func setDefaults(data interface{}) error {
s := reflect.ValueOf(data).Elem() s := reflect.ValueOf(data).Elem()
t := s.Type() t := s.Type()

View File

@ -268,6 +268,16 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
$('#settings').modal({backdrop: 'static', keyboard: true}); $('#settings').modal({backdrop: 'static', keyboard: true});
}; };
$scope.saveConfig = function() {
var cfg = JSON.stringify($scope.config);
var opts = {headers: {'Content-Type': 'application/json'}};
$http.post(urlbase + '/config', cfg, opts).success(function () {
$http.get(urlbase + '/config/sync').success(function (data) {
$scope.configInSync = data.configInSync;
});
});
};
$scope.saveSettings = function () { $scope.saveSettings = function () {
// Make sure something changed // Make sure something changed
var changed = ! angular.equals($scope.config.Options, $scope.config.workingOptions) || var changed = ! angular.equals($scope.config.Options, $scope.config.workingOptions) ||
@ -281,10 +291,9 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
// Apply new settings locally // Apply new settings locally
$scope.config.Options = angular.copy($scope.config.workingOptions); $scope.config.Options = angular.copy($scope.config.workingOptions);
$scope.config.GUI = angular.copy($scope.config.workingGUI); $scope.config.GUI = angular.copy($scope.config.workingGUI);
$scope.configInSync = false;
$scope.config.Options.ListenAddress = $scope.config.Options.ListenStr.split(',').map(function (x) { return x.trim(); }); $scope.config.Options.ListenAddress = $scope.config.Options.ListenStr.split(',').map(function (x) { return x.trim(); });
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}});
$scope.saveConfig();
} }
$('#settings').modal("hide"); $('#settings').modal("hide");
@ -358,14 +367,12 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
}); });
} }
$scope.configInSync = false; $scope.saveConfig();
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}});
}; };
$scope.saveNode = function () { $scope.saveNode = function () {
var nodeCfg, done, i; var nodeCfg, done, i;
$scope.configInSync = false;
$('#editNode').modal('hide'); $('#editNode').modal('hide');
nodeCfg = $scope.currentNode; nodeCfg = $scope.currentNode;
nodeCfg.NodeID = nodeCfg.NodeID.replace(/ /g, '').replace(/-/g, '').toUpperCase().trim(); nodeCfg.NodeID = nodeCfg.NodeID.replace(/ /g, '').replace(/-/g, '').toUpperCase().trim();
@ -387,7 +394,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
$scope.nodes.sort(nodeCompare); $scope.nodes.sort(nodeCompare);
$scope.config.Nodes = $scope.nodes; $scope.config.Nodes = $scope.nodes;
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}}); $scope.saveConfig();
}; };
$scope.otherNodes = function () { $scope.otherNodes = function () {
@ -462,7 +469,6 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
$scope.saveRepo = function () { $scope.saveRepo = function () {
var repoCfg, done, i; var repoCfg, done, i;
$scope.configInSync = false;
$('#editRepo').modal('hide'); $('#editRepo').modal('hide');
repoCfg = $scope.currentRepo; repoCfg = $scope.currentRepo;
repoCfg.Nodes = []; repoCfg.Nodes = [];
@ -490,7 +496,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
$scope.repos[repoCfg.ID] = repoCfg; $scope.repos[repoCfg.ID] = repoCfg;
$scope.config.Repositories = repoList($scope.repos); $scope.config.Repositories = repoList($scope.repos);
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}}); $scope.saveConfig();
}; };
$scope.sharesRepo = function(repoCfg) { $scope.sharesRepo = function(repoCfg) {
@ -511,8 +517,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
delete $scope.repos[$scope.currentRepo.ID]; delete $scope.repos[$scope.currentRepo.ID];
$scope.config.Repositories = repoList($scope.repos); $scope.config.Repositories = repoList($scope.repos);
$scope.configInSync = false; $scope.saveConfig();
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}});
}; };
$scope.setAPIKey = function (cfg) { $scope.setAPIKey = function (cfg) {