Archived
Let server side decide if restart is needed on config change
This commit is contained in:
1 parent
5a2328d9a5
commit
df381fd03f
4 files changed
+69
-13
No files matched your search
+1
-1
@@ -18,7 +18,7 @@ func init() {
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["angular.min.js"] = bs
|
||||
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffec3cfd73dbb692bffbaf4075e923d5c89493bed7bb89ebbc499df43dbf7c79e2a47373ae6f8612218b35052a246845e3e87fbf5d00a4f0458ab693b66fe63cd3c60616fb85c5627701703c26c7f9725da497734ec2e321797cf0e8afe45ff1553e213fe5c525895942723ea70599e68c17e9a4e2795146e459961131aa24052d69714d93680fb07d2829c96784cfd3929479554c290c4c28813f2ff36b5a309a90c91ad092d727eff74bbece28c9d22965308ecf634ea6d035a1886a9657403c65d04ec9ab93e3176fce5e90599ad1686f6ffcdd6f6596324e2645be02f24f082f2a3a124ca6aca2f5dfcbac2af13ff937f96e0c232fb37c1267e4c113328bb312806276596571a1fe46a0bda0825f4a9077ca83c3bdbdebb820e59a4d412c76498eea11d1224faa8c8641d3178cc8f9c5f0500ca88a6c12039a2312808a049e062e024667e96538aba021cd19091fcc395f9e16f9759ad062486ef608fc188d5142677195f132fa5416b37fd218dadec40b41e0bff78fcfdefdbcff3ebfa20c08ed187b9ce75729adc71a2337439b4d5ee459468b3038ab5b8f799181a01aefe5345f822205c99a7754c1b2a0d7cf638e640e0e9bd64bcadfbe84269c926d2bea282eb854b09809e0440822b0232b8c0a822500dc6c0ead4e50a7dbbe589f3c471903a39581452292f30b0f921386821aeca9fe6591f37c9a67c773987fb0e3864d0d861605ac0f177749297b817d2e3760443473592fe832af2515edb024cec022d965090b649617944cf23c2b4906b3092d9cd3c2a4c8b900065e44fb4d9a3c21c1abb4e49401229841d0c214cc5ecc2c3955d21109419e25094c49494b00e4eb252ca980d34f1cfe523325d7d466a4217f1d7f3aa32c793959961afab715bfcc715edfa129bc4a1729f89a97e94fe372b8c5cdaac584169dd8df01be989d3010f43acece340ab287d45d24bc3566655d7ee4aaf3eef84fe322864594bda31f2b00d295032a23a02018c912a1a32d487ffc80441aa5a57944fe33784c227be504f457bd46e11fc2693e63ec058b27194d3422b28b3c4fc1eec0c3afb788d13e3bf97e954f5b908a9e7be13ccd0bde8e90a8eefe3a3ec3f69fe476a3af1d6c26db769d4d63fc875376eaca295b0876fa075f985ef0b24acffc0b5bad577d623e9cdc67317f3005456ccf2ad88b61879dc6c2f17f3044de89f0342ecb555e24dd4835288578b96de9e4f6fd2b7dd96224f2cff7ef4fcf2090280810ba850d3d3b3d7949d71a326820b245a18897e915fc6d4d52b325c21677564da794263409eb1d117fd21909bf111ba0deaa4d70ca521e0e0fcdae30f80f4639e8e04aec21c110378d380b83396cee8105ed6eaff8b33158d86eb6b764633bb09b09842de7154ff215eb86f4edfb26d31b57b93fc7e0d55ccdb68b55505e15ac4d1dfe0969d3facd249e5e2545be043b007a60b96017600d933c2e1215456e5a26a54bc066e39f811c73046e222c9d371165458030ac23cc872418976b58e80be0b144bb2b4b2db44c621edbc299067ae833018911d8c0f11acb4319e4847eee14f27a82f471dbdfdf4e7e83fd34029d95a11eee0c2358ab2fe2e95c439e26cec4781520c2a8bf239aa3001a28c3bce3c3bb93e37cb1cc193818c4d4573d9a1a04def334b97034614ba5ffeee7518b617bcf14c6c62c5f01758ca421765d85c39101c131140d1166bf89b887644c1e1d1c1c989069a21c55fda305e830de140ddd26e80c33b03615096f869dd13c2edfae18c4904b5af0b550b5071e7fea14edd0e9dd382d1c366a3f16248a93028e0a421e60ff75cce7d122fe141e8cc87f91efa42e05c409fb69cd69f93ee71000ec7bd209070a95c793a1cba14139aff82ed210d8f5a16d80b512df406ecca77312d236d53a4a39e82b8207d09c8d8dcf43982999ed26762d06992af55e077682e527b739dcb3932888d078551aee149bedbd0337f67c66ae7a8483757f04395bc520854e19046ffead05020e76c570b7d3bdbb41c1450d1305e904acb16f90442be6339e2f9740d98b59d426b85cc3017a3e0f19d1bf1d5d838b7fcf0f2e229e7f0002c5314c0d38f387b203e66552f2227c343c34e550c38fc8001347d86c07e4f367b26d3d49323ab06591dd0fa19b84832d97586a38a5c514fc737c49d5c43c24836f8703afb44a259a409e193fce2062fcfa139eb259fe15663bc154adf862936dcc5890c2dcb452560b31680b93b6684a39f1ad989645ba88216df361f2a8cf9a43d328befa44c23ed926b147bdb27c28fcb5c07fd00fab3185cb2907a90002760baf9de0c29224c63e008d87435baf62379a6539446840c6ef16b100e6718bd87c3c336267e416dd3cc079362f35207a03ff9e3cbf308d0e016dddd4ed1146651915645189a00adfa6d6b8d625e1b9887f022bfc22144bb6ed23958722212e169b32ec42df0e6d8c1d5e2710e503217ee38d3d9a3d99a254ff0e7acdaf6eab4f959cdc46690b88f6ca766db9cefa4fab2ed73ff6d299eb0c77eaacdd37a2ac58cdf99d35a618134a53c5a42edffef78ef9d654fe8789603981ce7daa5d945fe8ce6940664c4e85a169c7132d6c2a886b5a9480dbc7dfd7544f96c2defb4b3bed1df30cdb6d82841ded98e2a2040bcc69c4698c7e380318324ef51a03f25b93655b551289f5d0c83750448537ca28bbe47308b9c8a316899bf8a04350850d62e5566350c7693bad41452baab767883218b44528cd3c03f996c13a48878ca6c5d4d13fe4b43ff883083ce37de313dc9e62262dc11a165a13a6e9a5af52c24aa65c62d0b05345bbf4d34739bd354393946b557abf66c66308d5ae2889095618314681b1eba6db38938c14c8db659d6cd727d03826346115909e7ffb7061e9bd130f00e838b0a0ab64ea5b09157575bf8acaf89af656515915f0bf7c41e5f9fb549ebf9a8eb03993fda691897eace2acf46b67d4a9e02124b4ce762e7f76a007a5b5a036d599ce42c5f2d0b44990b9a414edb63e6e26ab34cb08a3201d04c113dac80aea52056f2bb871798ae4f188c83cdbb85330c3d64aa87bfe6d1e31c885634bf36cb9ccd6c0fe8a3427d2199ec565eb3d0f0d7396ba0dd49a336f117bab825eb8e424b5236a2e075875fc5609227900a74226626bdf843ae345542eb39487c108d758bcd436c04fda06f829e21053820725f639832cb52df3d2293c0339589cff3a7bfb262ac53582746629613822377371ada47c426e82e39c014f7cff3d38e6401c79016bf2906efc5b99b3606314bff7ba5dc500cf7e066d553a61c5ad7ec03822326daee54ceab647342d6a539883365f6add15d11dd7d92ac562ed8a4e9658c36816332c6c264e5d7457e05f6043f720a04103fb23b21c58c6dab1f6dd756d2373121b13374ce9fb7441f38a3756197a9cc50a62bf7c15e11a479048a352ff6a911989938a9675d779e9467229fe6f6d2feae8f14e26e5b705ed34d3Line truncated
|
||||
bs, _ = hex.DecodeString("1f8b080000096e8800ffec3c6b73db3892dffd2b30bacc929ac89493d99dbb8ae36c659cccae372f579c4c5d9dc757458990c531452a246859e5e8bf5f3700527852749cccee55adab6662038d7ea1d1e86e001c8fc971b15c97e9e59c91f078481e1f3cfa33f9477c554cc8cf457949e23c21059bd3924c8b9c95e9a466455945e47996113eaa2225ad68794d93680fb07dac28296684cdd38a54455d4e290c4c28813f2f8b6b5ae634219335a0256f4e3eec576c9d5192a5539ac338368f199942d78422aa595103f13487764a5e9f1cbf7c7bf692ccd28c467b7be31f7eafb234676452162b20ff84b0b2a623ce649ad7b4f97b99d515fe27fe263f8c61e465564ce28c3c784266715601509c5fd6595ccabf11682fa8e1970ae49db2e0706fef3a2e49b5cea720567e498e9a11d1a248ea8c8641db178cc8f9c5f0900fa8cb6c12039a2312808a389e162e024667e96538aba1212d72123e9833b63c2d8beb34a1e590dcee11f8d11aa384cee23a6355745395b3bfd318dadec60b4ee0bff78fcfdeffb2ffa1b8a23910da31f6b828ae52da8cd5466e86269bac2cb28c966170d6b41eb332034115deab69b1044572920defa8826549af5fc40cc91c1cb6ad9794bd7b054d3825db56d4515c32a1603e13c009178463475672ca09560070bb39343a419d76fb627df202650cb4d61c2c12919c5f38909ce428a8c69eec5f96052ba645763c87f9073b6ed954606859c2fab0715794e62fb1cfe6068c886636eb255d168da4bc1d96c41958647e59c1029915252593a2c82a92c16c420b63b4d42932c6818117de7e9b264f48f03aad18cd0111cc2068610a66cf67969c4ae9888020cf9304a6a4a21500b2f5129654c0e80d83bfe44c8935b51929c8dfc43767344f5e4d969582fe5dcd2e0b9cd7f7680aafd3450abee655faf3b81a6e71e7f56242cb4eecef015f9c9fe420e8759c9d2914440f69ba487867ccd2badcc865e797e33f8dcb181651f69e7eaa0148550ea88c808260649e701d6d41fae30724c2280dcd23f25fc06312d12b26a0bfea150a7fe34ef3799ebfcce34946138588e8222f52b03bf0f0eb2d62b4cf4ebe5f17530f52de732f9ca745c9fc0889eceeafe3336cff596c37eadac166b26d57d9d4c67f3ccd4f6d39450bc14ef7e00bdd0b5ed6e9997b61cbf5aa4eccc793fb2ce68fbaa088ed790d7b31ecb0d3983bfe8f9ac83b119ec655b52acaa41ba90225112fb72d9ddc7e78ad2e5b8c44fefee1c3e919041225014277b0a1e7a727afe85a41060d44b44814f132bd82bf8d496ab744d8e2ceeae994d2842661b323e24f3a23e1777c03545b95094ef39485c343bd2b0cfe23a70c7470c5f79060889b469c85c11c36f7c080b6b757fcd9682c6c37db3bb2b11dd8cd04c256f39a25c52aef8674edfb3ad31b5bb9bfc4e0d56ccdfac52a29abcbdca70ef784f8b47e3b89a75749592cc10e801e582ed80558c3a488cb4446911bcfa47409d86efc3390638ec06d84a5f2c6a3ac0810864d84f99004e36a0d0b7d013c56687755a5849649cc625338dd400f5d262030021b385e617928829cd0cd9d44de4c903a6efbfbbbc9efb09f46a0b32a54c39d61046bf5653c9d2bc8d3c49a18a7027818f5574473144003cd31eff8f8fee4b8582c8b1c1c0c62eaab1e450d1cef799a5c589a30a5527f77f3a8c4b0bd670a63e3bc5801758ca421765d85c39106c130140d1166bf8db887644c1e1d1c1ce89069221d55f3a304e8305e170ddd26e80c33309f8ab837c3ce681e57ef5639c4904b5ab23557b5031e7f9a14edd0eadd582d0c366a3716248a93028e0a421e60ff4dcce6d122be090f46e4bfc80f42971ce224ff79cd68f5a1601000ec3bd2090b0a95c792a1cda146b9a8d92ed210d8f5a1ad8179896f203766d33909a94fb596520efa8ae000d46763e3f2107a4a66ba895d8b41a44abdd7819960b9c96d0ef7cc240a223456579a3bc56673efc08dbd98e9ab1ee160dd1f41ce56e79042a739046feead05028efc2ac7dd4ef5ee1a051b354c14a413b0c6be43125ecc67ac582e81b21333af4d30b18603f47c0e32bc7f3bba01e7ff9e1f5c44acf80804ca63981a70e60f4507cccba46265f86878a8cb21871f9101268eb0d90ec8e7cf64db7a92647460ca22ba1f423709075b2eb1d4704acb29f8e7f892ca89794806df0f074e69a54a14811c337e9c41c4f8ed273ccd67c53798ed0453b5f2ab4db63663410a73e3a52c1762e00b93b6682a31f15e4ccb325dc490b6b93039d467cca16e14df7c22619ff449ec50af281f727fcdf11ff4c3aa4de172ca402a8080ddc26927b8b00489b10b40e1e1d0d42bdf8d665901111a9071bb452c8039dc22361fcfb4d819b945370f708ecd4b0e88dec2bf272f2e74a3434053374d7b8451594639595422a8c2b5a9b5ae754958c1e39fc008bf08c592ad7fa4f45024c4c56252865de8fba189b1c3eb04bc7cc0c56fbdb143b3275394eaff835e8babbbea5326277751da02a2bdcaaf2ddb59ffcbaacbf68fbd74663bc39d3af3fb469415ab397fb0c624635c69b298d4e5dbffda31df8acaff6922184ea0739ff28bf22bdd390dc88cce293734e578c2c3a684b8a66505b85dfc7d4bf56429ecbdbffa69ef9867d86e13246c694717172558604ec34f63d4c319c09031aad61890df866cbe552511580fb57c03459478a38ce6976c0e211779e491b88d0f3a0495d82056f61a833c4edb690d325a91bd3d4394c1c017a1b4f30ce43d8355900e19758b69a27fc8697f72071178c6fbd625b839c5b9b0046358684c98a297be4a096b9172f141c34e15edd24f1fe5f4d60c4d52a654e9dd9a198f2154bba224265861c41805c6aedb6eed4c329220ef964db2dd9c40e398508795406afeedc285a5f74e3c00a0e2c082ae94a96f2594d7d5dd2aaae26bd809e4a16da320cb72a6b840c83fcedebd8d2a7ef499ce0c2e150e7140b164fccc74ce4fc7ab27e436002a0c9cd9fe07b0af8057ee97993c6b18ff5e1579b0d998958a655159753ba005b20143234ec455b5e857a714b8c698e3f4ae7d5893d81e52f3e29bdab6bb3ce99889dec65ad525fcaf58507113622a4ec2f5396b4fc7bf6bad8b7eaae3ac72dbe9a8d3d487e4f3674b15e267077a305f0f6addb0d35928591eea4a07992b4ad1833407ff64956619c9294807e9c884b6b282bae4d1831166da3c45e2a08ad7007cdc4998a1d708ec9b08fa610f9fe63d539ae760f96b607f45dabb01199e8a66eb3dafa145bd5c8e3167871df876ba1de72479f98ac401a70c4989a9531dea8c955105ab9f85c1087d58bc54d6dd8d1260dc44e06d16b043f145e3e262ebbfb4338ebd6e7f39c003b081af54c90dc8bb04b573327dba3d0773773da7f2383f8939f06d28c68519d5679cad52ac58afe86489859c761dc19acaf9d1d39ebd540cdb1edaa7212d1a081290e5c098a28e65672f29139995dde9b8614a3fa40b5ad42cLine truncated
|
||||
gr, _ = gzip.NewReader(bytes.NewBuffer(bs))
|
||||
bs, _ = ioutil.ReadAll(gr)
|
||||
Assets["app.js"] = bs
|
||||
|
||||
+36
-1
@@ -16,6 +16,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -210,9 +211,43 @@ func restPostConfig(req *http.Request) {
|
||||
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
|
||||
saveConfig()
|
||||
configInSync = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,22 @@ type GUIConfiguration struct {
|
||||
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 {
|
||||
s := reflect.ValueOf(data).Elem()
|
||||
t := s.Type()
|
||||
|
||||
+16
-11
@@ -268,6 +268,16 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
|
||||
$('#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 () {
|
||||
// Make sure something changed
|
||||
var changed = ! angular.equals($scope.config.Options, $scope.config.workingOptions) ||
|
||||
@@ -281,10 +291,9 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
|
||||
// Apply new settings locally
|
||||
$scope.config.Options = angular.copy($scope.config.workingOptions);
|
||||
$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(); });
|
||||
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}});
|
||||
|
||||
$scope.saveConfig();
|
||||
}
|
||||
|
||||
$('#settings').modal("hide");
|
||||
@@ -358,14 +367,12 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.configInSync = false;
|
||||
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}});
|
||||
$scope.saveConfig();
|
||||
};
|
||||
|
||||
$scope.saveNode = function () {
|
||||
var nodeCfg, done, i;
|
||||
|
||||
$scope.configInSync = false;
|
||||
$('#editNode').modal('hide');
|
||||
nodeCfg = $scope.currentNode;
|
||||
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.config.Nodes = $scope.nodes;
|
||||
|
||||
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}});
|
||||
$scope.saveConfig();
|
||||
};
|
||||
|
||||
$scope.otherNodes = function () {
|
||||
@@ -462,7 +469,6 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
|
||||
$scope.saveRepo = function () {
|
||||
var repoCfg, done, i;
|
||||
|
||||
$scope.configInSync = false;
|
||||
$('#editRepo').modal('hide');
|
||||
repoCfg = $scope.currentRepo;
|
||||
repoCfg.Nodes = [];
|
||||
@@ -490,7 +496,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
|
||||
$scope.repos[repoCfg.ID] = repoCfg;
|
||||
$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) {
|
||||
@@ -511,8 +517,7 @@ syncthing.controller('SyncthingCtrl', function ($scope, $http) {
|
||||
delete $scope.repos[$scope.currentRepo.ID];
|
||||
$scope.config.Repositories = repoList($scope.repos);
|
||||
|
||||
$scope.configInSync = false;
|
||||
$http.post(urlbase + '/config', JSON.stringify($scope.config), {headers: {'Content-Type': 'application/json'}});
|
||||
$scope.saveConfig();
|
||||
};
|
||||
|
||||
$scope.setAPIKey = function (cfg) {
|
||||
|
||||
Reference in new issue
Block a user