From b08d2b07bcd65b2e8047dc932206f7ab9b3f55e9 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Tue, 25 Jul 2017 16:21:32 +0200 Subject: [PATCH] feat(volume-creation): add plugin support (#1044) * feat(volume-creation): add plugin support * feat(plugins): only use systemInfo to retrieve plugins when API version < 1.25 * refactor(createVolume): remove unused dependencies --- .../createVolume/createVolumeController.js | 10 ++-- app/models/docker/plugin.js | 9 +++ app/rest/docker/plugin.js | 9 +++ app/services/docker/pluginService.js | 56 +++++++++++++++++++ app/services/docker/systemService.js | 8 +-- 5 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 app/models/docker/plugin.js create mode 100644 app/rest/docker/plugin.js create mode 100644 app/services/docker/pluginService.js diff --git a/app/components/createVolume/createVolumeController.js b/app/components/createVolume/createVolumeController.js index 579b948d1..8319337ba 100644 --- a/app/components/createVolume/createVolumeController.js +++ b/app/components/createVolume/createVolumeController.js @@ -1,6 +1,6 @@ angular.module('createVolume', []) -.controller('CreateVolumeController', ['$scope', '$state', 'VolumeService', 'SystemService', 'ResourceControlService', 'Authentication', 'Notifications', 'FormValidator', -function ($scope, $state, VolumeService, SystemService, ResourceControlService, Authentication, Notifications, FormValidator) { +.controller('CreateVolumeController', ['$q', '$scope', '$state', 'VolumeService', 'PluginService', 'ResourceControlService', 'Authentication', 'Notifications', 'FormValidator', +function ($q, $scope, $state, VolumeService, PluginService, ResourceControlService, Authentication, Notifications, FormValidator) { $scope.formValues = { Driver: 'local', @@ -70,8 +70,10 @@ function ($scope, $state, VolumeService, SystemService, ResourceControlService, function initView() { $('#loadingViewSpinner').show(); - if ($scope.applicationState.endpoint.mode.provider !== 'DOCKER_SWARM') { - SystemService.getVolumePlugins() + var endpointProvider = $scope.applicationState.endpoint.mode.provider; + var apiVersion = $scope.applicationState.endpoint.apiVersion; + if (endpointProvider !== 'DOCKER_SWARM') { + PluginService.volumePlugins(apiVersion < 1.25) .then(function success(data) { $scope.availableVolumeDrivers = data; }) diff --git a/app/models/docker/plugin.js b/app/models/docker/plugin.js new file mode 100644 index 000000000..fde1ab840 --- /dev/null +++ b/app/models/docker/plugin.js @@ -0,0 +1,9 @@ +// This model is based on https://github.com/moby/moby/blob/0ac25dfc751fa4304ab45afd5cd8705c2235d101/api/types/plugin.go#L8-L31 +// instead of the official documentation. +// See: https://github.com/moby/moby/issues/34241 +function PluginViewModel(data) { + this.Id = data.Id; + this.Name = data.Name; + this.Enabled = data.Enabled; + this.Config = data.Config; +} diff --git a/app/rest/docker/plugin.js b/app/rest/docker/plugin.js new file mode 100644 index 000000000..a0a342d2d --- /dev/null +++ b/app/rest/docker/plugin.js @@ -0,0 +1,9 @@ +angular.module('portainer.rest') +.factory('Plugin', ['$resource', 'API_ENDPOINT_ENDPOINTS', 'EndpointProvider', function PluginFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) { + 'use strict'; + return $resource(API_ENDPOINT_ENDPOINTS + '/:endpointId/docker/plugins/:id/:action', { + endpointId: EndpointProvider.endpointID + }, { + query: { method: 'GET', isArray: true } + }); +}]); diff --git a/app/services/docker/pluginService.js b/app/services/docker/pluginService.js new file mode 100644 index 000000000..d6e3325e6 --- /dev/null +++ b/app/services/docker/pluginService.js @@ -0,0 +1,56 @@ +angular.module('portainer.services') +.factory('PluginService', ['$q', 'Plugin', 'SystemService', function PluginServiceFactory($q, Plugin, SystemService) { + 'use strict'; + var service = {}; + + service.plugins = function() { + var deferred = $q.defer(); + + Plugin.query({}).$promise + .then(function success(data) { + var plugins = data.map(function (item) { + return new PluginViewModel(item); + }); + deferred.resolve(plugins); + }) + .catch(function error(err) { + deferred.reject({ msg: 'Unable to retrieve plugins', err: err }); + }); + + return deferred.promise; + }; + + service.volumePlugins = function(systemOnly) { + var deferred = $q.defer(); + + $q.all({ + system: SystemService.plugins(), + plugins: systemOnly ? [] : service.plugins() + }) + .then(function success(data) { + var volumePlugins = []; + var systemPlugins = data.system; + var plugins = data.plugins; + + if (systemPlugins.Volume) { + volumePlugins = volumePlugins.concat(systemPlugins.Volume); + } + + for (var i = 0; i < plugins.length; i++) { + var plugin = plugins[i]; + if (plugin.Enabled && _.includes(plugin.Config.Interface.Types, 'docker.volumedriver/1.0')) { + volumePlugins.push(plugin.Name); + } + } + + deferred.resolve(volumePlugins); + }) + .catch(function error(err) { + deferred.reject({ msg: err.msg, err: err }); + }); + + return deferred.promise; + }; + + return service; +}]); diff --git a/app/services/docker/systemService.js b/app/services/docker/systemService.js index 4c017c0be..fcaed9e73 100644 --- a/app/services/docker/systemService.js +++ b/app/services/docker/systemService.js @@ -3,15 +3,15 @@ angular.module('portainer.services') 'use strict'; var service = {}; - service.getVolumePlugins = function() { + service.plugins = function() { var deferred = $q.defer(); System.info({}).$promise .then(function success(data) { - var plugins = data.Plugins.Volume; + var plugins = data.Plugins; deferred.resolve(plugins); }) .catch(function error(err) { - deferred.reject({msg: 'Unable to retrieve volume plugin information', err: err}); + deferred.reject({msg: 'Unable to retrieve plugins information from system', err: err}); }); return deferred.promise; }; @@ -40,7 +40,7 @@ angular.module('portainer.services') return deferred.promise; }; - + service.dataUsage = function () { return System.dataUsage().$promise; };