diff --git a/app/components/startContainer/startContainerController.js b/app/components/startContainer/startContainerController.js index fc99597af..674032d4e 100644 --- a/app/components/startContainer/startContainerController.js +++ b/app/components/startContainer/startContainerController.js @@ -9,7 +9,8 @@ function($scope, $routeParams, $location, Container, Messages) { cpuShares: 1024, env: '', commands: '', - volumesFrom: '' + volumesFrom: '', + portBindings: [] }; $scope.commandPlaceholder = '["/bin/echo", "Hello world"]'; @@ -27,6 +28,27 @@ function($scope, $routeParams, $location, Container, Messages) { var loc = $location; var s = $scope; + var exposedPorts = {}; + var portBindings = {}; + // TODO: consider using compatibility library + $scope.config.portBindings.forEach(function(portBinding) { + var intPort = portBinding.intPort + "/tcp"; + var binding = { + HostIp: portBinding.ip, + HostPort: portBinding.extPort + }; + if (portBinding.intPort) { + exposedPorts[intPort] = {}; + if (intPort in portBindings) { + portBindings[intPort].push(binding); + } else { + portBindings[intPort] = [binding]; + } + } else { + // TODO: Send warning message? Internal port need to be specified. + } + }); + Container.create({ Image: id, name: $scope.config.name, @@ -34,10 +56,19 @@ function($scope, $routeParams, $location, Container, Messages) { MemorySwap: $scope.config.memorySwap, CpuShares: $scope.config.cpuShares, Cmd: cmds, - VolumesFrom: $scope.config.volumesFrom + VolumesFrom: $scope.config.volumesFrom, + ExposedPorts: exposedPorts, + HostConfig: { + PortBindings: portBindings + } }, function(d) { if (d.Id) { - ctor.start({id: d.Id}, function(cd) { + ctor.start({ + id: d.Id, + HostConfig: { + PortBindings: portBindings + } + }, function(cd) { $('#create-modal').modal('hide'); loc.path('/containers/' + d.Id + '/'); }, function(e) { @@ -50,4 +81,13 @@ function($scope, $routeParams, $location, Container, Messages) { failedRequestHandler(e, Messages); }); }; + + $scope.addPortBinding = function() { + $scope.config.portBindings.push({ip: '', extPort: '', intPort: ''}); + }; + + $scope.removePortBinding = function(portBinding) { + var idx = $scope.config.portBindings.indexOf(portBinding); + $scope.config.portBindings.splice(idx, 1); + }; }]); diff --git a/app/components/startContainer/startContainerController.spec.js b/app/components/startContainer/startContainerController.spec.js new file mode 100644 index 000000000..97d75133e --- /dev/null +++ b/app/components/startContainer/startContainerController.spec.js @@ -0,0 +1,63 @@ +describe('startContainerController', function () { + var scope, $location, createController, mockContainer, $httpBackend; + + beforeEach(angular.mock.module('dockerui')); + + beforeEach(inject(function ($rootScope, $controller, _$location_) { + $location = _$location_; + scope = $rootScope.$new(); + + createController = function() { + return $controller('StartContainerController', { + '$scope': scope + }); + }; + + angular.mock.inject(function (_Container_, _$httpBackend_) { + mockContainer = _Container_; + $httpBackend = _$httpBackend_; + }); + })); + + describe('Starting a container with options', function () { + it('should issue a correct create request to the Docker remote API', function() { + var controller = createController(); + var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c'; + var expectedBody = { + "name": "container-name", + "Memory": 0, + "MemorySwap": 0, + "CpuShares": 1024, + "Cmd": null, + "VolumesFrom": "", + "ExposedPorts":{ + "9000/tcp": {}, + }, + "HostConfig": { + "PortBindings":{ + "9000/tcp": [{ + "HostPort": "9999", + "HostIp": "10.20.10.15", + }] + }, + }}; + $httpBackend.expectPOST('/dockerapi/containers/create?name=container-name', expectedBody).respond({ + "Id": id, + "Warnings": null + }); + $httpBackend.expectPOST('/dockerapi/containers/' + id + '/start?').respond({ + "Id": id, + "Warnings": null + }); + + scope.config.name = 'container-name'; + scope.config.portBindings = [{ip: '10.20.10.15', extPort: '9999', intPort: '9000'}] + + //var response = mockContainer.create({}); + scope.create(); + + $httpBackend.flush(); + //console.log(response); + }); + }); +}); \ No newline at end of file diff --git a/app/components/startContainer/startcontainer.html b/app/components/startContainer/startcontainer.html index 42f5f5a7c..91f7ab268 100644 --- a/app/components/startContainer/startcontainer.html +++ b/app/components/startContainer/startcontainer.html @@ -33,6 +33,27 @@ +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ +
diff --git a/gruntFile.js b/gruntFile.js index 7a96965de..2bf53a59a 100644 --- a/gruntFile.js +++ b/gruntFile.js @@ -37,7 +37,7 @@ module.exports = function (grunt) { ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;\n' + ' * Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n */\n', src: { - js: ['app/**/*.js'], + js: ['app/**/*.js', '!app/**/*.spec.js'], jsTpl: ['<%= distdir %>/templates/**/*.js'], specs: ['test/**/*.spec.js'], scenarios: ['test/**/*.scenario.js'],