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.
    +

    +
    +
    +
    +
    +
    +
    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ServiceMemory UsageMemory LimitActions
    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 @@ - - - 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; - }); }); });