diff --git a/src/index.html b/src/index.html
index c044a20e8..d32e393e2 100644
--- a/src/index.html
+++ b/src/index.html
@@ -154,7 +154,8 @@
Settings
Support
- System
+ Services
+ System
Logout
diff --git a/src/js/index.js b/src/js/index.js
index 3c03fd77d..5c1e705c2 100644
--- a/src/js/index.js
+++ b/src/js/index.js
@@ -99,6 +99,9 @@ app.config(['$routeProvider', function ($routeProvider) {
}).when('/system', {
controller: 'SystemController',
templateUrl: 'views/system.html?<%= revision %>'
+ }).when('/services', {
+ controller: 'ServicesController',
+ templateUrl: 'views/services.html?<%= revision %>'
}).otherwise({ redirectTo: '/'});
}]);
diff --git a/src/views/services.html b/src/views/services.html
new file mode 100644
index 000000000..eab1b0b4e
--- /dev/null
+++ b/src/views/services.html
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
Services
+
+
+
+
+
+
+ Cloudron services implement functionality such as databases, email and authentication.
+
+
+
+
+
+
+
+
+
+
+
+ |
+ Service |
+ Memory Usage |
+ Memory Limit |
+ Actions |
+
+
+
+
+ |
+ cloudron |
+ |
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+ {{ service.displayName }}
+ |
+
+
+ |
+
+ {{ service.config.memorySwap | prettyByteSize }}
+ |
+
+
+
+
+ |
+
+
+ |
+
+ |
+ redis |
+
+
+ |
+
+
+ |
+
+ {{ service.displayName }}
+ |
+
+
+ |
+
+ {{ service.config.memorySwap | prettyByteSize }}
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/src/views/services.js b/src/views/services.js
new file mode 100644
index 000000000..acc7fb54c
--- /dev/null
+++ b/src/views/services.js
@@ -0,0 +1,152 @@
+'use strict';
+
+/* global angular */
+/* global $ */
+
+angular.module('Application').controller('ServicesController', ['$scope', '$location', '$timeout', 'Client', function ($scope, $location, $timeout, Client) {
+ Client.onReady(function () { if (!Client.getUserInfo().isAtLeastAdmin) $location.path('/'); });
+
+ $scope.config = Client.getConfig();
+ $scope.servicesReady = false;
+ $scope.services = [];
+ $scope.hasRedisServices = false;
+ $scope.redisServicesExpanded = false;
+ $scope.memory = null;
+
+ function refresh(serviceName, callback) {
+ callback = callback || function () {};
+
+ Client.getService(serviceName, function (error, result) {
+ if (error) return console.log('Error getting status of ' + serviceName + ':' + error.message);
+
+ var service = $scope.services.find(function (s) { return s.name === serviceName; });
+ if (!service) $scope.services.find(function (s) { return s.name === serviceName; });
+
+ service.status = result.status;
+ service.config = result.config;
+ service.memoryUsed = result.memoryUsed;
+ service.memoryPercent = result.memoryPercent;
+
+ callback(null, service);
+ });
+ }
+
+ $scope.restartService = function (serviceName) {
+ function waitForActive(serviceName) {
+ refresh(serviceName, function (error, result) {
+ if (result.status === 'active') return;
+
+ setTimeout(function () { waitForActive(serviceName); }, 3000);
+ });
+ }
+
+ $scope.services.find(function (s) { return s.name === serviceName; }).status = 'starting';
+
+ Client.restartService(serviceName, function (error) {
+ if (error) return Client.error(error);
+
+ // show "busy" indicator for 3 seconds to show some ui activity
+ setTimeout(function () { waitForActive(serviceName); }, 3000);
+ });
+ };
+
+ $scope.serviceConfigure = {
+ error: null,
+ busy: false,
+ service: null,
+
+ // form model
+ memoryLimit: 0,
+ memoryTicks: [],
+
+ show: function (service) {
+ $scope.serviceConfigure.reset();
+
+ $scope.serviceConfigure.service = service;
+ $scope.serviceConfigure.memoryLimit = service.config.memorySwap; // memory + swap
+
+ // TODO improve those
+ $scope.serviceConfigure.memoryTicks = [];
+
+ // create ticks starting from manifest memory limit. the memory limit here is currently split into ram+swap (and thus *2 below)
+ // TODO: the *2 will overallocate since 4GB is max swap that cloudron itself allocates
+ $scope.serviceConfigure.memoryTicks = [];
+ var npow2 = Math.pow(2, Math.ceil(Math.log($scope.memory.memory)/Math.log(2)));
+ for (var i = 256; i <= (npow2*2/1024/1024); i *= 2) {
+ $scope.serviceConfigure.memoryTicks.push(i * 1024 * 1024);
+ }
+
+ $('#serviceConfigureModal').modal('show');
+ },
+
+ submit: function (memoryLimit) {
+ $scope.serviceConfigure.busy = true;
+ $scope.serviceConfigure.error = null;
+
+ Client.configureService($scope.serviceConfigure.service.name, { memorySwap: memoryLimit, memory: memoryLimit/2 }, function (error) {
+ $scope.serviceConfigure.busy = false;
+ if (error) {
+ $scope.serviceConfigure.error = error.message;
+ return;
+ }
+
+ refresh($scope.serviceConfigure.service.name);
+
+ $('#serviceConfigureModal').modal('hide');
+ $scope.serviceConfigure.reset();
+ });
+ },
+
+ reset: function () {
+ $scope.serviceConfigure.busy = false;
+ $scope.serviceConfigure.error = null;
+ $scope.serviceConfigure.service = null;
+
+ $scope.serviceConfigure.memoryLimit = 0;
+ $scope.serviceConfigure.memoryTicks = [];
+
+ $scope.serviceConfigureForm.$setPristine();
+ $scope.serviceConfigureForm.$setUntouched();
+ }
+ };
+
+ Client.onReady(function () {
+ Client.memory(function (error, memory) {
+ if (error) console.error(error);
+
+ $scope.memory = memory;
+
+ Client.getServices(function (error, result) {
+ if (error) return Client.error(error);
+
+ $scope.services = result.map(function (name) {
+ var displayName = name;
+ var isRedis = false;
+
+ if (name.indexOf('redis') === 0) {
+ isRedis = true;
+ var app = Client.getCachedAppSync(name.slice('redis:'.length));
+ if (app) {
+ displayName = 'Redis (' + (app.label || app.fqdn) + ')';
+ } else {
+ displayName = 'Redis (unknown app)';
+ }
+ }
+
+ return {
+ name: name,
+ displayName: displayName,
+ isRedis: isRedis
+ };
+ });
+ $scope.hasRedisServices = !!$scope.services.find(function (service) { return service.isRedis; });
+
+ // just kick off the status fetching
+ $scope.services.forEach(function (s) { refresh(s.name); });
+
+ $scope.servicesReady = true;
+ });
+ });
+ });
+
+}]);
diff --git a/src/views/system.html b/src/views/system.html
index 8733f9fb5..a0b4de73d 100644
--- a/src/views/system.html
+++ b/src/views/system.html
@@ -1,40 +1,3 @@
-
-
-
@@ -129,103 +92,4 @@
-
-
-
Services
-
-
-
-
-
-
- Cloudron services implement functionality such as databases, email and authentication.
-
-
-
-
-
-
-
-
-
-
-
- |
- Service |
- Memory Usage |
- Memory Limit |
- Actions |
-
-
-
-
- |
- cloudron |
- |
- |
-
-
- |
-
-
- |
-
-
- |
-
- {{ service.displayName }}
- |
-
-
- |
-
- {{ service.config.memorySwap | prettyByteSize }}
- |
-
-
-
-
- |
-
-
- |
-
- |
- redis |
-
-
- |
-
-
- |
-
- {{ service.displayName }}
- |
-
-
- |
-
- {{ service.config.memorySwap | prettyByteSize }}
- |
-
-
-
-
- |
-
-
-
-
-
-
-
-
diff --git a/src/views/system.js b/src/views/system.js
index 1111f6f4c..9387f6f32 100644
--- a/src/views/system.js
+++ b/src/views/system.js
@@ -9,10 +9,6 @@ angular.module('Application').controller('SystemController', ['$scope', '$locati
Client.onReady(function () { if (!Client.getUserInfo().isAtLeastAdmin) $location.path('/'); });
$scope.config = Client.getConfig();
- $scope.servicesReady = false;
- $scope.services = [];
- $scope.hasRedisServices = false;
- $scope.redisServicesExpanded = false;
$scope.memory = null;
$scope.activeTab = 0;
@@ -33,103 +29,6 @@ angular.module('Application').controller('SystemController', ['$scope', '$locati
return getRandomColor();
}
- function refresh(serviceName, callback) {
- callback = callback || function () {};
-
- Client.getService(serviceName, function (error, result) {
- if (error) return console.log('Error getting status of ' + serviceName + ':' + error.message);
-
- var service = $scope.services.find(function (s) { return s.name === serviceName; });
- if (!service) $scope.services.find(function (s) { return s.name === serviceName; });
-
- service.status = result.status;
- service.config = result.config;
- service.memoryUsed = result.memoryUsed;
- service.memoryPercent = result.memoryPercent;
-
- callback(null, service);
- });
- }
-
- $scope.restartService = function (serviceName) {
- function waitForActive(serviceName) {
- refresh(serviceName, function (error, result) {
- if (result.status === 'active') return;
-
- setTimeout(function () { waitForActive(serviceName); }, 3000);
- });
- }
-
- $scope.services.find(function (s) { return s.name === serviceName; }).status = 'starting';
-
- Client.restartService(serviceName, function (error) {
- if (error) return Client.error(error);
-
- // show "busy" indicator for 3 seconds to show some ui activity
- setTimeout(function () { waitForActive(serviceName); }, 3000);
- });
- };
-
- $scope.serviceConfigure = {
- error: null,
- busy: false,
- service: null,
-
- // form model
- memoryLimit: 0,
- memoryTicks: [],
-
- show: function (service) {
- $scope.serviceConfigure.reset();
-
- $scope.serviceConfigure.service = service;
- $scope.serviceConfigure.memoryLimit = service.config.memorySwap; // memory + swap
-
- // TODO improve those
- $scope.serviceConfigure.memoryTicks = [];
-
- // create ticks starting from manifest memory limit. the memory limit here is currently split into ram+swap (and thus *2 below)
- // TODO: the *2 will overallocate since 4GB is max swap that cloudron itself allocates
- $scope.serviceConfigure.memoryTicks = [];
- var npow2 = Math.pow(2, Math.ceil(Math.log($scope.memory.memory)/Math.log(2)));
- for (var i = 256; i <= (npow2*2/1024/1024); i *= 2) {
- $scope.serviceConfigure.memoryTicks.push(i * 1024 * 1024);
- }
-
- $('#serviceConfigureModal').modal('show');
- },
-
- submit: function (memoryLimit) {
- $scope.serviceConfigure.busy = true;
- $scope.serviceConfigure.error = null;
-
- Client.configureService($scope.serviceConfigure.service.name, { memorySwap: memoryLimit, memory: memoryLimit/2 }, function (error) {
- $scope.serviceConfigure.busy = false;
- if (error) {
- $scope.serviceConfigure.error = error.message;
- return;
- }
-
- refresh($scope.serviceConfigure.service.name);
-
- $('#serviceConfigureModal').modal('hide');
- $scope.serviceConfigure.reset();
- });
- },
-
- reset: function () {
- $scope.serviceConfigure.busy = false;
- $scope.serviceConfigure.error = null;
- $scope.serviceConfigure.service = null;
-
- $scope.serviceConfigure.memoryLimit = 0;
- $scope.serviceConfigure.memoryTicks = [];
-
- $scope.serviceConfigureForm.$setPristine();
- $scope.serviceConfigureForm.$setUntouched();
- }
- };
-
$scope.reboot = {
busy: false,
show: function () {
@@ -378,37 +277,6 @@ angular.module('Application').controller('SystemController', ['$scope', '$locati
$scope.memory = memory;
$scope.disks.update();
-
- Client.getServices(function (error, result) {
- if (error) return Client.error(error);
-
- $scope.services = result.map(function (name) {
- var displayName = name;
- var isRedis = false;
-
- if (name.indexOf('redis') === 0) {
- isRedis = true;
- var app = Client.getCachedAppSync(name.slice('redis:'.length));
- if (app) {
- displayName = 'Redis (' + (app.label || app.fqdn) + ')';
- } else {
- displayName = 'Redis (unknown app)';
- }
- }
-
- return {
- name: name,
- displayName: displayName,
- isRedis: isRedis
- };
- });
- $scope.hasRedisServices = !!$scope.services.find(function (service) { return service.isRedis; });
-
- // just kick off the status fetching
- $scope.services.forEach(function (s) { refresh(s.name); });
-
- $scope.servicesReady = true;
- });
});
});