diff --git a/app/docker/__module.js b/app/docker/__module.js
index c372684de..32253b43a 100644
--- a/app/docker/__module.js
+++ b/app/docker/__module.js
@@ -184,6 +184,17 @@ angular.module('portainer.docker', ['portainer.app'])
}
};
+ var imageImport = {
+ name: 'docker.images.import',
+ url: '/import',
+ views: {
+ 'content@': {
+ templateUrl: 'app/docker/views/images/import/importimage.html',
+ controller: 'ImportImageController'
+ }
+ }
+ };
+
var networks = {
name: 'docker.networks',
url: '/networks',
@@ -422,6 +433,7 @@ angular.module('portainer.docker', ['portainer.app'])
$stateRegistryProvider.register(images);
$stateRegistryProvider.register(image);
$stateRegistryProvider.register(imageBuild);
+ $stateRegistryProvider.register(imageImport);
$stateRegistryProvider.register(networks);
$stateRegistryProvider.register(network);
$stateRegistryProvider.register(networkCreation);
diff --git a/app/docker/components/datatables/images-datatable/imagesDatatable.html b/app/docker/components/datatables/images-datatable/imagesDatatable.html
index fe556201b..87cba5507 100644
--- a/app/docker/components/datatables/images-datatable/imagesDatatable.html
+++ b/app/docker/components/datatables/images-datatable/imagesDatatable.html
@@ -23,6 +23,17 @@
+
+
+
+
@@ -108,7 +119,7 @@
Unused
- {{ tag }}
+ {{ tag }}
|
{{ item.VirtualSize | humansize }} |
{{ item.Created | getisodatefromtimestamp }} |
diff --git a/app/docker/components/datatables/images-datatable/imagesDatatable.js b/app/docker/components/datatables/images-datatable/imagesDatatable.js
index 25963e468..615f4375e 100644
--- a/app/docker/components/datatables/images-datatable/imagesDatatable.js
+++ b/app/docker/components/datatables/images-datatable/imagesDatatable.js
@@ -10,6 +10,8 @@ angular.module('portainer.docker').component('imagesDatatable', {
reverseOrder: '<',
showHostColumn: '<',
removeAction: '<',
- forceRemoveAction: '<'
+ downloadAction: '<',
+ forceRemoveAction: '<',
+ exportInProgress: '<'
}
});
diff --git a/app/docker/helpers/imageHelper.js b/app/docker/helpers/imageHelper.js
index 01e3484ac..df3b76fd9 100644
--- a/app/docker/helpers/imageHelper.js
+++ b/app/docker/helpers/imageHelper.js
@@ -25,6 +25,15 @@ angular.module('portainer.docker')
};
};
+ helper.getImagesNamesForDownload = function(images) {
+ var names = images.map(function(image) {
+ return image.RepoTags[0] !== ':' ? image.RepoTags[0] : image.Id;
+ });
+ return {
+ names: names
+ };
+ };
+
function extractNameAndTag(imageName, registry) {
var imageNameAndTag = imageName.split(':');
var image = imageNameAndTag[0];
diff --git a/app/docker/rest/image.js b/app/docker/rest/image.js
index 5395bb6c7..2d3cb2256 100644
--- a/app/docker/rest/image.js
+++ b/app/docker/rest/image.js
@@ -26,6 +26,12 @@ function ImageFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider, HttpR
headers: { 'X-Registry-Auth': HttpRequestHelper.registryAuthenticationHeader },
ignoreLoadingBar: true
},
+ download: {
+ method: 'GET', params: {action:'get', names: '@names'},
+ transformResponse: imageGetResponse,
+ responseType: 'blob',
+ ignoreLoadingBar: true
+ },
remove: {
method: 'DELETE', params: {id: '@id', force: '@force'},
isArray: true, transformResponse: deleteImageHandler
diff --git a/app/docker/rest/response/image.js b/app/docker/rest/response/image.js
new file mode 100644
index 000000000..4db1ef506
--- /dev/null
+++ b/app/docker/rest/response/image.js
@@ -0,0 +1,10 @@
+// The get action of the Image service returns a file.
+// ngResource will transform it as an array of chars.
+// This functions simply creates a response object and assign
+// the data to a field.
+function imageGetResponse(data) {
+ var response = {};
+ response.file = data;
+ return response;
+ }
+
\ No newline at end of file
diff --git a/app/docker/services/imageService.js b/app/docker/services/imageService.js
index 112536cca..dd93badad 100644
--- a/app/docker/services/imageService.js
+++ b/app/docker/services/imageService.js
@@ -1,5 +1,6 @@
angular.module('portainer.docker')
-.factory('ImageService', ['$q', 'Image', 'ImageHelper', 'RegistryService', 'HttpRequestHelper', 'ContainerService', function ImageServiceFactory($q, Image, ImageHelper, RegistryService, HttpRequestHelper, ContainerService) {
+.factory('ImageService', ['$q', 'Image', 'ImageHelper', 'RegistryService', 'HttpRequestHelper', 'ContainerService', 'FileUploadService',
+ function ImageServiceFactory($q, Image, ImageHelper, RegistryService, HttpRequestHelper, ContainerService, FileUploadService) {
'use strict';
var service = {};
@@ -138,6 +139,15 @@ angular.module('portainer.docker')
return Image.tag({id: id, tag: imageConfig.tag, repo: imageConfig.repo}).$promise;
};
+ service.downloadImages = function(images) {
+ var names = ImageHelper.getImagesNamesForDownload(images);
+ return Image.download(names).$promise;
+ };
+
+ service.uploadImage = function(file) {
+ return FileUploadService.loadImages(file);
+ };
+
service.deleteImage = function(id, forceRemoval) {
var deferred = $q.defer();
Image.remove({id: id, force: forceRemoval}).$promise
diff --git a/app/docker/views/images/build/buildimage.html b/app/docker/views/images/build/buildimage.html
index 35742d59f..7820c4b9b 100644
--- a/app/docker/views/images/build/buildimage.html
+++ b/app/docker/views/images/build/buildimage.html
@@ -143,7 +143,7 @@