From 85b3ed88d67fadc87b5b4ba7a8e6c19fa2d9e08a Mon Sep 17 00:00:00 2001 From: baron_l Date: Mon, 17 Jun 2019 17:11:10 +0200 Subject: [PATCH] feat(container): upload files inside containers --- app/docker/__module.js | 13 ++++ app/docker/services/containerService.js | 8 ++- .../views/containers/edit/container.html | 7 ++- .../import/containerImportFiles.html | 59 +++++++++++++++++++ .../import/containerImportFilesController.js | 58 ++++++++++++++++++ app/portainer/services/fileUpload.js | 14 +++++ 6 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 app/docker/views/containers/import/containerImportFiles.html create mode 100644 app/docker/views/containers/import/containerImportFilesController.js diff --git a/app/docker/__module.js b/app/docker/__module.js index a3b15cc8f..f9e30a64c 100644 --- a/app/docker/__module.js +++ b/app/docker/__module.js @@ -75,6 +75,18 @@ angular.module('portainer.docker', ['portainer.app']) } }; + var containerFilesImport = { + name: 'docker.containers.container.import', + url: '/import', + views: { + 'content@': { + templateUrl: './views/containers/import/containerImportFiles.html', + controller: 'ContainerImportFilesController', + controllerAs: 'ctrl' + } + } + }; + var containerAttachConsole = { name: 'docker.containers.container.attach', url: '/attach', @@ -484,6 +496,7 @@ angular.module('portainer.docker', ['portainer.app']) $stateRegistryProvider.register(configCreation); $stateRegistryProvider.register(containers); $stateRegistryProvider.register(container); + $stateRegistryProvider.register(containerFilesImport); $stateRegistryProvider.register(containerExecConsole); $stateRegistryProvider.register(containerAttachConsole); $stateRegistryProvider.register(containerCreation); diff --git a/app/docker/services/containerService.js b/app/docker/services/containerService.js index cc4cbea87..329d5aa58 100644 --- a/app/docker/services/containerService.js +++ b/app/docker/services/containerService.js @@ -1,8 +1,8 @@ import { ContainerDetailsViewModel, ContainerViewModel, ContainerStatsViewModel } from '../models/container'; angular.module('portainer.docker') -.factory('ContainerService', ['$q', 'Container', 'ResourceControlService', 'LogHelper', '$timeout', -function ContainerServiceFactory($q, Container, ResourceControlService, LogHelper, $timeout) { +.factory('ContainerService', ['$q', 'Container', 'ResourceControlService', 'LogHelper', '$timeout', 'FileUploadService', +function ContainerServiceFactory($q, Container, ResourceControlService, LogHelper, $timeout, FileUploadService) { 'use strict'; var service = {}; @@ -213,5 +213,9 @@ function ContainerServiceFactory($q, Container, ResourceControlService, LogHelpe return Container.prune({ filters: filters }).$promise; }; + service.uploadFiles = function(containerId, file, path) { + return FileUploadService.loadContainerFiles(containerId, file, path); + }; + return service; }]); diff --git a/app/docker/views/containers/edit/container.html b/app/docker/views/containers/edit/container.html index 41486b432..443bcfdd8 100644 --- a/app/docker/views/containers/edit/container.html +++ b/app/docker/views/containers/edit/container.html @@ -6,7 +6,7 @@ -
+
@@ -14,7 +14,7 @@
- + @@ -27,6 +27,9 @@ Duplicate/Edit
+
diff --git a/app/docker/views/containers/import/containerImportFiles.html b/app/docker/views/containers/import/containerImportFiles.html new file mode 100644 index 000000000..843b75203 --- /dev/null +++ b/app/docker/views/containers/import/containerImportFiles.html @@ -0,0 +1,59 @@ + + + + Containers > {{ ctrl.container.Name|trimcontainername }} > Import files + + + +
+
+ + +
+ +
+ Upload +
+
+ + You can upload a tar archive containing your files. Accepted compressions: identity (no compression), gzip, bzip2, xz. + +
+
+
+ + + {{ ctrl.formValues.UploadFile.name }} + + +
+
+ +
+ +
+ +
+
+ + + +
+ Actions +
+
+
+ + {{ ctrl.state.formValidationError }} +
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/app/docker/views/containers/import/containerImportFilesController.js b/app/docker/views/containers/import/containerImportFilesController.js new file mode 100644 index 000000000..89e09df2c --- /dev/null +++ b/app/docker/views/containers/import/containerImportFilesController.js @@ -0,0 +1,58 @@ +import angular from "angular"; + +class ContainerImportFilesController { + /* @ngInject */ + constructor($transition$, ContainerService, Notifications, HttpRequestHelper, $async) { + this.$transition$ = $transition$; + this.ContainerService = ContainerService; + this.Notifications = Notifications; + this.HttpRequestHelper = HttpRequestHelper; + this.$async = $async; + + this.uploadFilesAsync = this.uploadFilesAsync.bind(this); + } + + async $onInit() { + this.state = { + actionInProgress: false, + nodeName: this.$transition$.params().nodeName + }; + + this.formValues = { + UploadFile: null, + Path: null + }; + + const containerId = this.$transition$.params().id; + try { + this.HttpRequestHelper.setPortainerAgentTargetHeader(this.state.nodeName); + this.container = await this.ContainerService.container(containerId); + } catch (err) { + this.Notifications.error("Failure", err, "Unable retrieve container details"); + } + } + + uploadFiles() { + return this.$async(this.uploadFilesAsync); + } + + async uploadFilesAsync() { + this.state.actionInProgress = true; + const containerId = this.container.Id; + const file = this.formValues.UploadFile; + const path = this.formValues.Path; + try { + await this.ContainerService.uploadFiles(containerId, file, path); + this.Notifications.success("Files successfully uploaded"); + } catch (err) { + this.Notifications.error("Failure", err, "Unable to upload files"); + } finally { + this.state.actionInProgress = false; + } + } +} + +export default ContainerImportFilesController; +angular + .module("portainer.docker") + .controller("ContainerImportFilesController", ContainerImportFilesController); diff --git a/app/portainer/services/fileUpload.js b/app/portainer/services/fileUpload.js index c1634fb36..e8fea4b8c 100644 --- a/app/portainer/services/fileUpload.js +++ b/app/portainer/services/fileUpload.js @@ -42,6 +42,20 @@ angular.module('portainer.app') }); }; + service.loadContainerFiles = function(containerId, file, path) { + var endpointID = EndpointProvider.endpointID(); + return Upload.http({ + url: 'api/endpoints/' + endpointID + '/docker/containers/' + containerId + '/archive?path=' + path, + headers : { + 'Content-Type': file.type + }, + method: 'PUT', + data: file, + ignoreLoadingBar: true, + transformResponse: genericHandler + }); + }; + service.createSchedule = function(payload) { return Upload.upload({ url: 'api/schedules?method=file',