'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) callback(new Error('no such service' + serviceName)); // cannot happen service.status = result.status; service.config = result.config; service.memoryUsed = result.memoryUsed; service.memoryPercent = result.memoryPercent; service.defaultMemoryLimit = result.defaultMemoryLimit; callback(null, service); }); } function waitForActive(serviceName) { refresh(serviceName, function (error, result) { if (result.status === 'active') return; setTimeout(function () { waitForActive(serviceName); }, 3000); }); } $scope.restartService = function (serviceName) { $scope.services.find(function (s) { return s.name === serviceName; }).status = 'starting'; Client.restartService(serviceName, function (error) { if (error && error.statusCode === 404) { Client.rebuildService(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); }); return; } if (error) { refresh(serviceName); 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: [], recoveryMode: false, show: function (service) { $scope.serviceConfigure.reset(); $scope.serviceConfigure.service = service; $scope.serviceConfigure.recoveryMode = !!service.config.recoveryMode; $scope.serviceConfigure.memoryTicks = []; // we max system memory and current service memory for the case where the user configured the service on another server with more resources var nearest256m = Math.ceil(Math.max($scope.memory.memory, service.config.memoryLimit) / (256*1024*1024)) * 256 * 1024 * 1024; var startTick = service.defaultMemoryLimit; // code below ensure we atleast have 2 ticks to keep the slider usable $scope.serviceConfigure.memoryTicks.push(startTick); // start tick for (var i = startTick * 2; i < nearest256m; i *= 2) { $scope.serviceConfigure.memoryTicks.push(i); } $scope.serviceConfigure.memoryTicks.push(nearest256m); // end tick // for firefox widget update $timeout(function() { $scope.serviceConfigure.memoryLimit = service.config.memoryLimit; }, 500); $('#serviceConfigureModal').modal('show'); }, submit: function () { $scope.serviceConfigure.busy = true; $scope.serviceConfigure.error = null; var data = { memoryLimit: parseInt($scope.serviceConfigure.memoryLimit), recoveryMode: $scope.serviceConfigure.recoveryMode }; Client.configureService($scope.serviceConfigure.service.name, data, function (error) { $scope.serviceConfigure.busy = false; if (error) { $scope.serviceConfigure.error = error.message; return; } if ($scope.serviceConfigure.recoveryMode === true) { refresh($scope.serviceConfigure.service.name); } else { waitForActive($scope.serviceConfigure.service.name); } $('#serviceConfigureModal').modal('hide'); $scope.serviceConfigure.reset(); }); }, resetToDefaults: function () { $scope.serviceConfigure.memoryLimit = $scope.serviceConfigure.service.defaultMemoryLimit; }, 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.refreshAll = function (callback) { 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); }); if (callback) return callback(); }); }; Client.onReady(function () { Client.memory(function (error, memory) { if (error) console.error(error); $scope.memory = memory; $scope.refreshAll(function () { $scope.servicesReady = true; }); }); }); }]);