From efb4f088f14aee394599bea21973f82f1867c4fe Mon Sep 17 00:00:00 2001 From: chenjiankun Date: Fri, 11 Aug 2017 09:26:22 +0000 Subject: Add function to upload image from local/url in GUI JIRA: YARDSTICK-782 As user, we need to upload image from local/url. If upload image from local, user need to choose local image, then we will load it to openstack. If upload image from url, we will download it and load it to openstack. Change-Id: Ia9a42fda15a1dfc91476643635343a2f77a94a6b Signed-off-by: chenjiankun --- gui/app/scripts/controllers/image.controller.js | 301 +++++++++++++-------- gui/app/scripts/controllers/main.js | 169 ++++++------ .../controllers/projectDetail.controller.js | 2 +- gui/app/scripts/factory/main.factory.js | 39 ++- gui/app/views/modal/environmentDialog.html | 15 +- gui/app/views/modal/imageDialog.html | 19 ++ gui/app/views/podupload.html | 2 +- gui/app/views/uploadImage.html | 82 ++++-- 8 files changed, 393 insertions(+), 236 deletions(-) create mode 100644 gui/app/views/modal/imageDialog.html (limited to 'gui') diff --git a/gui/app/scripts/controllers/image.controller.js b/gui/app/scripts/controllers/image.controller.js index f6c91592f..d7a7edfa9 100644 --- a/gui/app/scripts/controllers/image.controller.js +++ b/gui/app/scripts/controllers/image.controller.js @@ -1,150 +1,235 @@ 'use strict'; angular.module('yardStickGui2App') - .controller('ImageController', ['$scope', '$state', '$stateParams', 'mainFactory', 'Upload', 'toaster', '$location', '$interval', - function($scope, $state, $stateParams, mainFactory, Upload, toaster, $location, $interval) { + .controller('ImageController', ['$scope', '$state', '$stateParams', 'mainFactory', 'Upload', 'toaster', '$location', '$interval', 'ngDialog', + function($scope, $state, $stateParams, mainFactory, Upload, toaster, $location, $interval, ngDialog) { init(); - $scope.showloading = false; - $scope.ifshowStatus = 0; function init() { + $scope.showloading = false; + $scope.ifshowStatus = 0; + + $scope.yardstickImage = [ + { + 'name': 'yardstick-image', + 'description': '', + 'size': 'N/A', + 'status': 'N/A', + 'time': 'N/A' + }, + { + 'name': 'Ubuntu-16.04', + 'description': '', + 'size': 'N/A', + 'status': 'N/A', + 'time': 'N/A' + }, + { + 'name': 'cirros-0.3.5', + 'description': '', + 'size': 'N/A', + 'status': 'N/A', + 'time': 'N/A' + } + ]; + $scope.customImage = []; $scope.uuid = $stateParams.uuid; - $scope.uploadImage = uploadImage; - getItemIdDetail(); - getImageListSimple(); + $scope.showloading = false; + $scope.url = null; + $scope.environmentInfo = null; + + getYardstickImageList(); + getCustomImageList(function(image, image_id){}); } - function getItemIdDetail() { + function getYardstickImageList(){ + mainFactory.ImageList().get({}).$promise.then(function(response){ + if(response.status == 1){ + angular.forEach($scope.yardstickImage, function(ele, index){ + if(typeof(response.result.images[ele.name]) != 'undefined'){ + $scope.yardstickImage[index] = response.result.images[ele.name]; + } + }); + }else{ + mainFactory.errorHandler1(response); + } + }, function(response){ + mainFactory.errorHandler2(response); + }); + } + + function getCustomImageList(func){ mainFactory.ItemDetail().get({ 'envId': $stateParams.uuid }).$promise.then(function(response) { - if (response.status == 1) { - $scope.baseElementInfo = response.result.environment; - - - } else { - toaster.pop({ - type: 'error', - title: 'fail', - body: response.error_msg, - timeout: 3000 + if(response.status == 1){ + $scope.environmentInfo = response.result.environment; + $scope.customImage = []; + angular.forEach(response.result.environment.image_id, function(ele){ + mainFactory.getImage().get({'imageId': ele}).$promise.then(function(responseData){ + if(responseData.status == 1){ + $scope.customImage.push(responseData.result.image); + func(responseData.result.image, ele); + }else{ + mainFactory.errorHandler1(responseData); + } + }, function(errorData){ + mainFactory.errorHandler2(errorData); + }); }); + }else{ + mainFactory.errorHandler1(response); } - }, function(error) { - toaster.pop({ - type: 'error', - title: 'fail', - body: 'unknow error', - timeout: 3000 - }); - }) + }, function(response){ + mainFactory.errorHandler2(response); + }); } - function getImageListSimple() { - - mainFactory.ImageList().get({}).$promise.then(function(response) { - if (response.status == 1) { - $scope.imageListData = response.result.images; - // $scope.imageStatus = response.result.status; - - } else { - toaster.pop({ - type: 'error', - title: 'get data failed', - body: 'please retry', - timeout: 3000 - }); - } - }, function(error) { - toaster.pop({ - type: 'error', - title: 'get data failed', - body: 'please retry', - timeout: 3000 + $scope.loadYardstickImage = function(image_name){ + + var updateImageTask = $interval(updateYardstickImage, 10000); + + function updateYardstickImage(){ + mainFactory.ImageList().get({}).$promise.then(function(responseData){ + if(responseData.status == 1){ + if(typeof(responseData.result.images[image_name]) != 'undefined' && responseData.result.images[image_name].status == 'ACTIVE'){ + angular.forEach($scope.yardstickImage, function(ele, index){ + if(ele.name == image_name){ + $scope.yardstickImage[index] = responseData.result.images[ele.name]; + } + }); + $interval.cancel(updateImageTask); + } + }else{ + mainFactory.errorHandler1(responseData); + } + },function(errorData){ + mainFactory.errorHandler2(errorData); }); - }) - } + } + mainFactory.uploadImage().post({'action': 'load_image', 'args': {'name': image_name}}).$promise.then(function(response){ + },function(response){ + mainFactory.errorHandler2(response); + }); + } - function getImageList() { - if ($scope.intervalImgae != undefined) { - $interval.cancel($scope.intervalImgae); - } - mainFactory.ImageList().get({}).$promise.then(function(response) { - if (response.status == 1) { - $scope.imageListData = response.result.images; - $scope.imageStatus = response.result.status; - - if ($scope.imageStatus == 0) { - $scope.intervalImgae = $interval(function() { - getImageList(); - }, 5000); - } else if ($scope.intervalImgae != undefined) { - $interval.cancel($scope.intervalImgae); + $scope.deleteYardstickImage = function(image_name){ + + var updateImageTask = $interval(updateYardstickImage, 10000); + + function updateYardstickImage(){ + mainFactory.ImageList().get({}).$promise.then(function(response){ + if(response.status == 1){ + if(typeof(response.result.images[image_name]) == 'undefined'){ + angular.forEach($scope.yardstickImage, function(ele, index){ + if(ele.name == image_name){ + $scope.yardstickImage[index].size = 'N/A'; + $scope.yardstickImage[index].status = 'N/A'; + $scope.yardstickImage[index].time = 'N/A'; + } + }); + $interval.cancel(updateImageTask); + } + }else{ + mainFactory.errorHandler1(response); } + },function(response){ + mainFactory.errorHandler2(response); + }); + } - } else { - toaster.pop({ - type: 'error', - title: 'get data failed', - body: 'please retry', - timeout: 3000 + mainFactory.uploadImage().post({'action': 'delete_image', 'args': {'name': image_name}}).$promise.then(function(response){ + },function(response){ + mainFactory.errorHandler2(response); + }); + } + + $scope.uploadCustomImageByUrl = function(url){ + mainFactory.uploadImageByUrl().post({ + 'action': 'upload_image_by_url', + 'args': { + 'environment_id': $stateParams.uuid, + 'url': url + } + }).$promise.then(function(response){ + if(response.status == 1){ + var updateImageTask = $interval(getCustomImageList, 30000, 10, true, function(image, image_id){ + if(image_id == response.result.uuid && image.status == 'ACTIVE'){ + $interval.cancel(updateImageTask); + } }); + ngDialog.close(); + }else{ + mainFactory.errorHandler1(response); } - }, function(error) { - toaster.pop({ - type: 'error', - title: 'get data failed', - body: 'please retry', - timeout: 3000 - }); - }) + }, function(response){ + mainFactory.errorHandler2(response); + }); } - function uploadImage() { - $scope.imageStatus = 0; - $interval.cancel($scope.intervalImgae); - $scope.ifshowStatus = 1; + $scope.uploadCustomImage = function($file, $invalidFiles) { $scope.showloading = true; - mainFactory.uploadImage().post({ - 'action': 'load_image', - 'args': { - 'environment_id': $scope.uuid - } - }).$promise.then(function(response) { + $scope.displayImageFile = $file; + Upload.upload({ + url: Base_URL + '/api/v2/yardstick/images', + data: { file: $file, 'environment_id': $scope.uuid, 'action': 'upload_image' } + }).then(function(response) { + $scope.showloading = false; - if (response.status == 1) { + if (response.data.status == 1) { + toaster.pop({ type: 'success', - title: 'create success', + title: 'upload success', body: 'you can go next step', timeout: 3000 }); - setTimeout(function() { - getImageList(); - }, 10000); - } else { - toaster.pop({ - type: 'error', - title: 'failed', - body: 'something wrong', - timeout: 3000 + var updateImageTask = $interval(getCustomImageList, 10000, 10, true, function(image, image_id){ + if(image_id == response.data.result.uuid && image.status == 'ACTIVE'){ + $interval.cancel(updateImageTask); + } }); + }else{ + mainFactory.errorHandler1(response); + } + }, function(response) { + $scope.uploadfile = null; + mainFactory.errorHandler2(response); + }) + } + + $scope.deleteCustomImage = function(image_id){ + mainFactory.deleteImage().delete({'imageId': image_id}).$promise.then(function(response){ + if(response.status == 1){ + $interval(getCustomImageList, 10000, 5, true, function(image, image_id){ + }); + }else{ + mainFactory.errorHandler2(response); } - }, function(error) { - toaster.pop({ - type: 'error', - title: 'failed', - body: 'something wrong', - timeout: 3000 - }); + }, function(response){ + mainFactory.errorHandler2(response); + }); + } + + $scope.openImageDialog = function(){ + $scope.url = null; + ngDialog.open({ + preCloseCallback: function(value) { + }, + template: 'views/modal/imageDialog.html', + scope: $scope, + className: 'ngdialog-theme-default', + width: 950, + showClose: true, + closeByDocument: false }) } @@ -158,9 +243,5 @@ angular.module('yardStickGui2App') $state.go('app.podUpload', { uuid: $scope.uuid }); } - - - - } ]); diff --git a/gui/app/scripts/controllers/main.js b/gui/app/scripts/controllers/main.js index ab76bf0f2..ceec83fa9 100644 --- a/gui/app/scripts/controllers/main.js +++ b/gui/app/scripts/controllers/main.js @@ -15,7 +15,7 @@ angular.module('yardStickGui2App') $scope.showImage = null; $scope.showContainer = null; $scope.showNextOpenRc = null; - $scope.showNextPod = null; + $scope.showNextPod = 1; $scope.displayContainerInfo = []; $scope.containerList = [{ value: 'create_influxdb', name: "InfluxDB" }, { value: 'create_grafana', name: "Grafana" }] @@ -51,7 +51,6 @@ angular.module('yardStickGui2App') $scope.chooseResult = chooseResult; getEnvironmentList(); - // getImageList(); } @@ -85,7 +84,7 @@ angular.module('yardStickGui2App') } $scope.goToImage = function goToImage() { - getImageListSimple(); + getImageList(); $scope.showImage = 1; } $scope.goToPod = function goToPod() { @@ -290,7 +289,7 @@ angular.module('yardStickGui2App') $scope.showImage = null; $scope.showContainer = null; $scope.showNextOpenRc = null; - $scope.showNextPod = null; + $scope.showNextPod = 1; $scope.displayContainerInfo = []; $scope.displayPodFile = null; @@ -308,7 +307,6 @@ angular.module('yardStickGui2App') ngDialog.open({ preCloseCallback: function(value) { getEnvironmentList(); - // getImageList(); }, template: 'views/modal/environmentDialog.html', scope: $scope, @@ -479,106 +477,97 @@ angular.module('yardStickGui2App') }) } - $scope.uploadImage = function uploadImage() { - $scope.imageStatus = 0; - $scope.showImageStatus = 1; - $scope.showloading = true; - mainFactory.uploadImage().post({ - 'action': 'load_image', - 'args': { - 'environment_id': $scope.uuid + $scope.yardstickImage = { + 'yardstick-image': { + 'name': 'yardstick-image', + 'description': '', + 'status': 'N/A' + }, + 'Ubuntu-16.04': { + 'name': 'Ubuntu-16.04', + 'description': '', + 'status': 'N/A' + }, + 'cirros-0.3.5': { + 'name': 'cirros-0.3.5', + 'description': '', + 'status': 'N/A' + } + }; - } - }).$promise.then(function(response) { - $scope.showloading = false; - if (response.status == 1) { - toaster.pop({ - type: 'success', - title: 'create success', - body: 'you can go next step', - timeout: 3000 - }); - setTimeout(function() { - getImageList(); - }, 10000); - $scope.showNextPod = 1; + $scope.selectImageList = []; - } else { - toaster.pop({ - type: 'error', - title: 'failed', - body: 'something wrong', - timeout: 3000 - }); + $scope.selectImage = function(name){ + $scope.selectImageList.push(name); + } - } - }, function(error) { - toaster.pop({ - type: 'error', - title: 'failed', - body: 'something wrong', - timeout: 3000 - }); - }) + $scope.unselectImage = function(name){ + var index = $scope.selectImageList.indexOf(name); + $scope.selectImageList.splice(index, 1); } - function getImageList() { - if ($scope.intervalImgae != undefined) { - $interval.cancel($scope.intervalImgae); - } - mainFactory.ImageList().get({}).$promise.then(function(response) { - if (response.status == 1) { - $scope.imageListData = response.result.images; - $scope.imageStatus = response.result.status; + $scope.uploadImage = function() { + $scope.imageStatus = 0; + $scope.showImageStatus = 1; + $scope.showloading = true; - if ($scope.imageStatus == 0) { - $scope.intervalImgae = $interval(function() { - getImageList(); - }, 5000); - } else if ($scope.intervalImgae != undefined) { - $interval.cancel($scope.intervalImgae); + var updateImageTask = $interval(function(){ + mainFactory.ImageList().get({}).$promise.then(function(response){ + if(response.status == 1){ + var isOk = true; + angular.forEach($scope.selectImageList, function(ele){ + if(typeof(response.result.images[ele]) != 'undefined' && response.result.images[ele].status == 'ACTIVE'){ + $scope.yardstickImage[ele] = response.result.images[ele]; + }else{ + isOk = false; + } + }); + if(isOk){ + $interval.cancel(updateImageTask); + $scope.imageStatus = 1; + } + }else{ + mainFactory.errorHandler1(response); } - - } else { - toaster.pop({ - type: 'error', - title: 'get data failed', - body: 'please retry', - timeout: 3000 - }); - } - }, function(error) { - toaster.pop({ - type: 'error', - title: 'get data failed', - body: 'please retry', - timeout: 3000 + }, function(response){ + mainFactory.errorHandler2(response); }); - }) + }, 10000); + + angular.forEach($scope.selectImageList, function(ele){ + mainFactory.uploadImage().post({ + 'action': 'load_image', + 'args': { + 'name': ele + } + }).$promise.then(function(response) { + if(response.status == 1){ + $scope.showloading = false; + $scope.showNextPod = 1; + }else{ + mainFactory.errorHandler1(response); + } + }, function(response) { + mainFactory.errorHandler2(response); + }) + }); } - function getImageListSimple() { + function getImageList() { mainFactory.ImageList().get({}).$promise.then(function(response) { if (response.status == 1) { - $scope.imageListData = response.result.images; - $scope.imageStatus = response.result.status; - - } else { - toaster.pop({ - type: 'error', - title: 'get data failed', - body: 'please retry', - timeout: 3000 + angular.forEach($scope.yardstickImage, function(value, key){ + if(typeof(response.result.images[key]) != 'undefined'){ + $scope.yardstickImage[key] = response.result.images[key]; + } }); + $scope.imageStatus = response.result.status; + }else{ + mainFactory.errorHandler1(response); } - }, function(error) { - toaster.pop({ - type: 'error', - title: 'get data failed', - body: 'please retry', - timeout: 3000 - }); + }, function(response) { + mainFactory.errorHandler2(response); }) } diff --git a/gui/app/scripts/controllers/projectDetail.controller.js b/gui/app/scripts/controllers/projectDetail.controller.js index 843f66c57..e8468045d 100644 --- a/gui/app/scripts/controllers/projectDetail.controller.js +++ b/gui/app/scripts/controllers/projectDetail.controller.js @@ -672,7 +672,7 @@ angular.module('yardStickGui2App') } $scope.gotoLog = function gotoLog(task_id) { - $state.go('app2.taskLog', { taskId: task_id }); + $state.go('app.taskLog', { taskId: task_id }); } } ]); diff --git a/gui/app/scripts/factory/main.factory.js b/gui/app/scripts/factory/main.factory.js index 44fbeb39f..7637a9ff3 100644 --- a/gui/app/scripts/factory/main.factory.js +++ b/gui/app/scripts/factory/main.factory.js @@ -9,7 +9,7 @@ var Base_URL; var Grafana_URL; angular.module('yardStickGui2App') - .factory('mainFactory', ['$resource','$rootScope','$http', '$location',function($resource, $rootScope,$http,$location) { + .factory('mainFactory', ['$resource','$rootScope','$http', '$location', 'toaster',function($resource, $rootScope ,$http ,$location, toaster) { Base_URL = 'http://' + $location.host() + ':' + $location.port(); Grafana_URL = 'http://' + $location.host(); @@ -86,6 +86,20 @@ angular.module('yardStickGui2App') } }) }, + getImage: function(){ + return $resource(Base_URL + '/api/v2/yardstick/images/:imageId', {imageId: "@imageId"}, { + 'get': { + method: 'GET' + } + }) + }, + deleteImage: function() { + return $resource(Base_URL + '/api/v2/yardstick/images/:imageId', { imageId: '@imageId' }, { + 'delete': { + method: 'DELETE' + } + }) + }, uploadImage: function() { return $resource(Base_URL + '/api/v2/yardstick/images', {}, { 'post': { @@ -93,6 +107,13 @@ angular.module('yardStickGui2App') } }) }, + uploadImageByUrl: function() { + return $resource(Base_URL + '/api/v2/yardstick/images', {}, { + 'post': { + method: 'POST' + } + }) + }, getPodDetail: function() { return $resource(Base_URL + '/api/v2/yardstick/pods/:podId', { podId: "@podId" }, { 'get': { @@ -249,6 +270,22 @@ angular.module('yardStickGui2App') method: 'DELETE' } }) + }, + errorHandler1: function(response){ + toaster.pop({ + 'type': 'error', + 'title': 'error', + 'body': response.result, + 'showCloseButton': true + }); + }, + errorHandler2: function(response){ + toaster.pop({ + 'type': 'error', + 'title': response.status, + 'body': response.statusText, + 'showCloseButton': true + }); } }; diff --git a/gui/app/views/modal/environmentDialog.html b/gui/app/views/modal/environmentDialog.html index 389de8340..4c539fc33 100644 --- a/gui/app/views/modal/environmentDialog.html +++ b/gui/app/views/modal/environmentDialog.html @@ -133,16 +133,17 @@ + - + - - - - - - + + + + + + diff --git a/gui/app/views/modal/imageDialog.html b/gui/app/views/modal/imageDialog.html new file mode 100644 index 000000000..c568f2aba --- /dev/null +++ b/gui/app/views/modal/imageDialog.html @@ -0,0 +1,19 @@ +
+ +

Enter Remote Image Url

+ + +
+ +
+ +
+ + + diff --git a/gui/app/views/podupload.html b/gui/app/views/podupload.html index 99e83aca2..d6d7c0c6e 100644 --- a/gui/app/views/podupload.html +++ b/gui/app/views/podupload.html @@ -13,7 +13,7 @@
- diff --git a/gui/app/views/uploadImage.html b/gui/app/views/uploadImage.html index 17ccfdb8b..0c337feeb 100644 --- a/gui/app/views/uploadImage.html +++ b/gui/app/views/uploadImage.html @@ -4,56 +4,86 @@
-

{{baseElementInfo.name}} -- Image +

{{environmentInfo.name}} -- Image

-
- - - - -
-

Current Images

- +

Alternative Images

choose namesizedescription statustime
{{image.name}}{{image.size/1024}} mb{{image.status}}{{image.time}}
{{name}}{{value.description}}{{value.status}}
+ + - + - + + - + - - -
namedescription size status timeaction
{{image.name}}{{image.size/1024}} MB{{image.description}}{{image.size | number:2}} MB {{image.status}} {{image.time}} +
+ + +
+
+
+

Custom Images

+
+ + +
+
+ - - - - - - + + + + + + + + + + + + + + + + +
namedescriptionsizestatustimeaction
{{image.name}}{{image.description}}{{image.size | number:2}} MB{{image.status}}{{image.time}} +
+ + +
+
+
- - -- cgit 1.2.3-korg