From ad0d23d6868218e3b0ec19eb92fca86629d5298b Mon Sep 17 00:00:00 2001 From: Roman Usachev Date: Mon, 22 Feb 2016 09:10:16 +0300 Subject: [PATCH 1/8] Container env vars editing using commit and recreate --- app/components/container/container.html | 34 ++++++- .../container/containerController.js | 95 ++++++++++++++++++- app/shared/services.js | 8 +- 3 files changed, 129 insertions(+), 8 deletions(-) diff --git a/app/components/container/container.html b/app/components/container/container.html index 083baf33c..95ba886d4 100644 --- a/app/components/container/container.html +++ b/app/components/container/container.html @@ -76,9 +76,37 @@ Environment: - +
+ + +
+
+
+ + +
+
+ + +
+
+ +
+
+
+ +
+ + diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index b384b6a3f..0c0c516d4 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -1,8 +1,11 @@ angular.module('container', []) - .controller('ContainerController', ['$scope', '$routeParams', '$location', 'Container', 'ContainerCommit', 'Messages', 'ViewSpinner', '$timeout', - function ($scope, $routeParams, $location, Container, ContainerCommit, Messages, ViewSpinner, $timeout) { + .controller('ContainerController', ['$scope', '$routeParams', '$location', 'Container', 'ContainerCommit', 'Image', 'Messages', 'ViewSpinner', '$timeout', + function ($scope, $routeParams, $location, Container, ContainerCommit, Image, Messages, ViewSpinner, $timeout) { $scope.changes = []; $scope.edit = false; + $scope.newCfg = { + Env: [] + }; var update = function () { ViewSpinner.spin(); @@ -10,6 +13,10 @@ angular.module('container', []) $scope.container = d; $scope.container.edit = false; $scope.container.newContainerName = d.Name; + $scope.newCfg.Env = d.Config.Env.map(function(entry) { + return {name: entry.split('=')[0], value: entry.split('=')[1]}; + }); + ViewSpinner.stop(); }, function (e) { if (e.status === 404) { @@ -20,6 +27,7 @@ angular.module('container', []) } ViewSpinner.stop(); }); + }; $scope.start = function () { @@ -58,6 +66,80 @@ angular.module('container', []) }); }; + $scope.restartEnv = function () { + var config = angular.copy($scope.container.Config); + + config.Env = $scope.newCfg.Env.map(function(entry) { + return entry.name+"="+entry.value; + }); + + console.log(config); + + + + ViewSpinner.spin(); + ContainerCommit.commit({id: $routeParams.id, tag: $scope.container.Config.Image, config: config }, function (d) { + console.log(d.Id); + if ('Id' in d) { + var imageId = d.Id; + Image.inspect({id: imageId}, function(imageData) { + console.log(imageData); + Container.create(imageData.Config, function(containerData) { + console.log(containerData); + // Stop current if running + if ($scope.container.State.Running) { + Container.stop({id: $routeParams.id}, function (d) { + Messages.send("Container stopped", $routeParams.id); + // start new + Container.start({ + id: containerData.Id + // HostConfig: $scope.container.HostConfig we really need this? + }, function (d) { + $location.url('/containers/' + containerData.Id + '/'); + Messages.send("Container started", $routeParams.id); + }, function (e) { + update(); + Messages.error("Failure", "Container failed to start." + e.data); + }); + }, function (e) { + update(); + Messages.error("Failure", "Container failed to stop." + e.data); + }); + } else { + // start new + Container.start({ + id: containerData.Id + // HostConfig: $scope.container.HostConfig we really need this? + }, function (d) { + $location.url('/containers/'+containerData.Id+'/'); + Messages.send("Container started", $routeParams.id); + }, function (e) { + update(); + Messages.error("Failure", "Container failed to start." + e.data); + }); + } + + }, function(e) { + update(); + Messages.error("Failure", "Image failed to get." + e.data); + }); + }, function (e) { + update(); + Messages.error("Failure", "Image failed to get." + e.data); + }) + + } else { + update(); + Messages.send("Container commit failed", $routeParams.id); + } + + + }, function (e) { + update(); + Messages.error("Failure", "Container failed to commit." + e.data); + }); + }; + $scope.commit = function () { ViewSpinner.spin(); ContainerCommit.commit({id: $routeParams.id, repo: $scope.container.Config.Image}, function (d) { @@ -139,6 +221,15 @@ angular.module('container', []) $scope.container.edit = false; }; + $scope.addEntry = function (array, entry) { + array.push(entry); + }; + $scope.rmEntry = function (array, entry) { + var idx = array.indexOf(entry); + array.splice(idx, 1); + }; + update(); $scope.getChanges(); }]); + diff --git a/app/shared/services.js b/app/shared/services.js index 2f9530d73..ba38178e2 100644 --- a/app/shared/services.js +++ b/app/shared/services.js @@ -31,8 +31,9 @@ angular.module('dockerui.services', ['ngResource']) url: Settings.url + '/commit', params: { 'container': params.id, - 'repo': params.repo - } + 'tag': params.tag + }, + data: params.config }).success(callback).error(function (data, status, headers, config) { console.log(error, data); }); @@ -92,7 +93,8 @@ angular.module('dockerui.services', ['ngResource']) insert: {method: 'POST', params: {id: '@id', action: 'insert'}}, push: {method: 'POST', params: {id: '@id', action: 'push'}}, tag: {method: 'POST', params: {id: '@id', action: 'tag', force: 0, repo: '@repo', tag: '@tag'}}, - remove: {method: 'DELETE', params: {id: '@id'}, isArray: true} + remove: {method: 'DELETE', params: {id: '@id'}, isArray: true}, + inspect: {method: 'GET', params: {id: '@id', action: 'json'}} }); }]) .factory('Version', ['$resource', 'Settings', function VersionFactory($resource, Settings) { From 35dbacdfffcf10f4612fc39612aa852437a3c240 Mon Sep 17 00:00:00 2001 From: Roman Usachev Date: Tue, 23 Feb 2016 20:47:21 +0300 Subject: [PATCH 2/8] Port bindings edit, HostConfig fix --- app/components/container/container.html | 61 +++++++++++++++---- .../container/containerController.js | 19 ++++-- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/app/components/container/container.html b/app/components/container/container.html index 95ba886d4..8754845a5 100644 --- a/app/components/container/container.html +++ b/app/components/container/container.html @@ -76,37 +76,43 @@ Environment: -
+
+ +
    +
  • {{ k }}
  • +
+
+
-
-
-
+
- + @@ -132,11 +138,42 @@ Ports: -
    +
    + +
    • - {{ containerport }} => {{ v.HostIp }}:{{ v.HostPort }} + {{ containerport }} => + {{ v.HostIp }}:{{ v.HostPort }}
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    + +
    diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index 0c0c516d4..ef3a7f3c2 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -4,7 +4,8 @@ angular.module('container', []) $scope.changes = []; $scope.edit = false; $scope.newCfg = { - Env: [] + Env: [], + NetworkSettings: {} }; var update = function () { @@ -16,6 +17,8 @@ angular.module('container', []) $scope.newCfg.Env = d.Config.Env.map(function(entry) { return {name: entry.split('=')[0], value: entry.split('=')[1]}; }); + $scope.newCfg.NetworkSettings.Ports = angular.copy(d.NetworkSettings.Ports) || []; + angular.forEach($scope.newCfg.NetworkSettings.Ports, function(conf, port, arr) { arr[port] = conf || []; }); ViewSpinner.stop(); }, function (e) { @@ -73,19 +76,19 @@ angular.module('container', []) return entry.name+"="+entry.value; }); - console.log(config); - + var portBindings = angular.copy($scope.newCfg.NetworkSettings.Ports); ViewSpinner.spin(); ContainerCommit.commit({id: $routeParams.id, tag: $scope.container.Config.Image, config: config }, function (d) { - console.log(d.Id); if ('Id' in d) { var imageId = d.Id; Image.inspect({id: imageId}, function(imageData) { - console.log(imageData); + // Append current host config to image with new port bindings + imageData.Config.HostConfig = angular.copy($scope.container.HostConfig); + imageData.Config.HostConfig.PortBindings = portBindings; + Container.create(imageData.Config, function(containerData) { - console.log(containerData); // Stop current if running if ($scope.container.State.Running) { Container.stop({id: $routeParams.id}, function (d) { @@ -229,6 +232,10 @@ angular.module('container', []) array.splice(idx, 1); }; + $scope.toggleEdit = function() { + $scope.edit = !$scope.edit; + }; + update(); $scope.getChanges(); }]); From fc0dedfda768f6c6921aa197606bc298479824bf Mon Sep 17 00:00:00 2001 From: Roman Usachev Date: Wed, 24 Feb 2016 01:34:20 +0300 Subject: [PATCH 3/8] Ports list now using HostConfig.PortBindings --- app/components/container/container.html | 4 ++-- app/components/container/containerController.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/components/container/container.html b/app/components/container/container.html index 8754845a5..419932e95 100644 --- a/app/components/container/container.html +++ b/app/components/container/container.html @@ -141,14 +141,14 @@
      -
    • +
    • {{ containerport }} => {{ v.HostIp }}:{{ v.HostPort }}
    -
    +
    diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index ef3a7f3c2..9977ff37b 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -5,7 +5,7 @@ angular.module('container', []) $scope.edit = false; $scope.newCfg = { Env: [], - NetworkSettings: {} + Ports: {} }; var update = function () { @@ -17,8 +17,8 @@ angular.module('container', []) $scope.newCfg.Env = d.Config.Env.map(function(entry) { return {name: entry.split('=')[0], value: entry.split('=')[1]}; }); - $scope.newCfg.NetworkSettings.Ports = angular.copy(d.NetworkSettings.Ports) || []; - angular.forEach($scope.newCfg.NetworkSettings.Ports, function(conf, port, arr) { arr[port] = conf || []; }); + $scope.newCfg.Ports = angular.copy(d.HostConfig.PortBindings) || []; + angular.forEach($scope.newCfg.Ports, function(conf, port, arr) { arr[port] = conf || []; }); ViewSpinner.stop(); }, function (e) { @@ -76,7 +76,7 @@ angular.module('container', []) return entry.name+"="+entry.value; }); - var portBindings = angular.copy($scope.newCfg.NetworkSettings.Ports); + var portBindings = angular.copy($scope.newCfg.Ports); ViewSpinner.spin(); From 50d33a07dfea390260d63d6627eb542cdc23bb9c Mon Sep 17 00:00:00 2001 From: Roman Usachev Date: Wed, 24 Feb 2016 03:13:24 +0300 Subject: [PATCH 4/8] Filesystem binds edit --- app/components/container/container.html | 50 ++++++++++++++-- .../container/containerController.js | 59 ++++++++++++++++++- 2 files changed, 100 insertions(+), 9 deletions(-) diff --git a/app/components/container/container.html b/app/components/container/container.html index 419932e95..2ec08ef6c 100644 --- a/app/components/container/container.html +++ b/app/components/container/container.html @@ -76,13 +76,13 @@ Environment: -
    - +
    +
    • {{ k }}
    -
    +
    @@ -138,8 +138,8 @@ Ports: -
    - +
    +
    • {{ containerport }} => @@ -147,7 +147,7 @@
    -
    +
    @@ -195,6 +195,44 @@
    {{ container.Config.Entrypoint.join(' ') }}
    + + Bindings: + +
    + + +
      +
    • {{ b }}
    • +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + + + +
    + + Volumes: {{ container.Volumes }} diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index 9977ff37b..56881de7a 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -2,7 +2,9 @@ angular.module('container', []) .controller('ContainerController', ['$scope', '$routeParams', '$location', 'Container', 'ContainerCommit', 'Image', 'Messages', 'ViewSpinner', '$timeout', function ($scope, $routeParams, $location, Container, ContainerCommit, Image, Messages, ViewSpinner, $timeout) { $scope.changes = []; - $scope.edit = false; + $scope.editEnv = false; + $scope.editPorts = false; + $scope.editBinds = false; $scope.newCfg = { Env: [], Ports: {} @@ -14,11 +16,46 @@ angular.module('container', []) $scope.container = d; $scope.container.edit = false; $scope.container.newContainerName = d.Name; + + // fill up env $scope.newCfg.Env = d.Config.Env.map(function(entry) { return {name: entry.split('=')[0], value: entry.split('=')[1]}; }); - $scope.newCfg.Ports = angular.copy(d.HostConfig.PortBindings) || []; - angular.forEach($scope.newCfg.Ports, function(conf, port, arr) { arr[port] = conf || []; }); + + // fill up ports + $scope.newCfg.Ports = {}; + angular.forEach(d.Config.ExposedPorts, function(i, port) { + $scope.newCfg.Ports[port] = d.HostConfig.PortBindings[port] || []; + }); + //angular.forEach($scope.newCfg.Ports, function(conf, port, arr) { arr[port] = conf || []; }); + + // fill up bindings + $scope.newCfg.Binds = []; + var defaultBinds = {}; + angular.forEach(d.Config.Volumes, function(value, vol) { + defaultBinds[vol] = { ContPath: vol, HostPath: '', ReadOnly: false, DefaultBind: true }; + }); + angular.forEach(d.HostConfig.Binds, function(binding, i) { + var mountpoint = binding.split(':')[0]; + var vol = binding.split(':')[1] || ''; + var ro = binding.split(':').length > 2 && binding.split(':')[2] == 'ro'; + var defaultBind = false; + if (vol == '') { + vol = mountpoint; + mountpoint = ''; + } + + if (vol in defaultBinds) { + delete defaultBinds[vol]; + defaultBind = true; + } + $scope.newCfg.Binds.push({ ContPath: vol, HostPath: mountpoint, ReadOnly: ro, DefaultBind: defaultBind }); + }); + angular.forEach(defaultBinds, function(bind) { + $scope.newCfg.Binds.push(bind); + }); + + console.log($scope.newCfg); ViewSpinner.stop(); }, function (e) { @@ -78,6 +115,21 @@ angular.module('container', []) var portBindings = angular.copy($scope.newCfg.Ports); + var binds = []; + angular.forEach($scope.newCfg.Binds, function(b) { + if (b.ContPath != '') { + var bindLine = ''; + if (b.HostPath != '') { + bindLine = b.HostPath + ':'; + } + bindLine += b.ContPath; + if (b.ReadOnly) { + bindLine += ':ro'; + } + binds.push(bindLine); + } + }); + ViewSpinner.spin(); ContainerCommit.commit({id: $routeParams.id, tag: $scope.container.Config.Image, config: config }, function (d) { @@ -87,6 +139,7 @@ angular.module('container', []) // Append current host config to image with new port bindings imageData.Config.HostConfig = angular.copy($scope.container.HostConfig); imageData.Config.HostConfig.PortBindings = portBindings; + imageData.Config.HostConfig.Binds = binds; Container.create(imageData.Config, function(containerData) { // Stop current if running From cc1b67575c7c7afc54706be393dc321e0c1d492b Mon Sep 17 00:00:00 2001 From: Roman Usachev Date: Wed, 24 Feb 2016 05:34:53 +0300 Subject: [PATCH 5/8] Null vars fix --- app/components/container/containerController.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index 56881de7a..7ef89ab9c 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -1,4 +1,4 @@ -angular.module('container', []) + angular.module('container', []) .controller('ContainerController', ['$scope', '$routeParams', '$location', 'Container', 'ContainerCommit', 'Image', 'Messages', 'ViewSpinner', '$timeout', function ($scope, $routeParams, $location, Container, ContainerCommit, Image, Messages, ViewSpinner, $timeout) { $scope.changes = []; @@ -18,16 +18,20 @@ angular.module('container', []) $scope.container.newContainerName = d.Name; // fill up env - $scope.newCfg.Env = d.Config.Env.map(function(entry) { - return {name: entry.split('=')[0], value: entry.split('=')[1]}; - }); + if (d.Config.Env) { + $scope.newCfg.Env = d.Config.Env.map(function (entry) { + return {name: entry.split('=')[0], value: entry.split('=')[1]}; + }); + } // fill up ports $scope.newCfg.Ports = {}; angular.forEach(d.Config.ExposedPorts, function(i, port) { - $scope.newCfg.Ports[port] = d.HostConfig.PortBindings[port] || []; + if (d.HostConfig.PortBindings && port in d.HostConfig.PortBindings) + $scope.newCfg.Ports[port] = d.HostConfig.PortBindings[port]; + else + $scope.newCfg.Ports[port] = []; }); - //angular.forEach($scope.newCfg.Ports, function(conf, port, arr) { arr[port] = conf || []; }); // fill up bindings $scope.newCfg.Binds = []; From cf18a3cd60dbb0fb43077159dc56e1deaeaea1e6 Mon Sep 17 00:00:00 2001 From: Roman Usachev Date: Wed, 24 Feb 2016 05:45:10 +0300 Subject: [PATCH 6/8] Null vars fix --- app/components/container/containerController.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index 7ef89ab9c..ebac2b36b 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -59,8 +59,6 @@ $scope.newCfg.Binds.push(bind); }); - console.log($scope.newCfg); - ViewSpinner.stop(); }, function (e) { if (e.status === 404) { @@ -130,7 +128,9 @@ if (b.ReadOnly) { bindLine += ':ro'; } - binds.push(bindLine); + if (b.HostPath != '' || !b.DefaultBind) { + binds.push(bindLine); + } } }); From f1b5037ee51cdd24ad4f8eaf9714861c64cd7526 Mon Sep 17 00:00:00 2001 From: Roman Usachev Date: Wed, 24 Feb 2016 09:19:02 +0300 Subject: [PATCH 7/8] Host mode fix --- app/components/container/containerController.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index ebac2b36b..fc46e45ab 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -116,6 +116,11 @@ }); var portBindings = angular.copy($scope.newCfg.Ports); + angular.forEach(portBindings, function(item, key) { + if (item.length == 0) + delete portBindings[key]; + }); + var binds = []; angular.forEach($scope.newCfg.Binds, function(b) { @@ -144,8 +149,15 @@ imageData.Config.HostConfig = angular.copy($scope.container.HostConfig); imageData.Config.HostConfig.PortBindings = portBindings; imageData.Config.HostConfig.Binds = binds; + if (imageData.Config.HostConfig.NetworkMode == 'host') { + imageData.Config.Hostname = ''; + } Container.create(imageData.Config, function(containerData) { + if (!('Id' in containerData)) { + Messages.error("Failure", "Container failed to create."); + return; + } // Stop current if running if ($scope.container.State.Running) { Container.stop({id: $routeParams.id}, function (d) { From da1a5ead3971c5ac00642332a8a9a85f426518b2 Mon Sep 17 00:00:00 2001 From: Roman Usachev Date: Wed, 24 Feb 2016 10:07:59 +0300 Subject: [PATCH 8/8] Bugfixes --- app/components/container/containerController.js | 4 +--- app/shared/services.js | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index fc46e45ab..8e485ca0b 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -165,7 +165,6 @@ // start new Container.start({ id: containerData.Id - // HostConfig: $scope.container.HostConfig we really need this? }, function (d) { $location.url('/containers/' + containerData.Id + '/'); Messages.send("Container started", $routeParams.id); @@ -181,7 +180,6 @@ // start new Container.start({ id: containerData.Id - // HostConfig: $scope.container.HostConfig we really need this? }, function (d) { $location.url('/containers/'+containerData.Id+'/'); Messages.send("Container started", $routeParams.id); @@ -202,7 +200,7 @@ } else { update(); - Messages.send("Container commit failed", $routeParams.id); + Messages.error("Failure", "Container commit failed."); } diff --git a/app/shared/services.js b/app/shared/services.js index ba38178e2..d2f1babf8 100644 --- a/app/shared/services.js +++ b/app/shared/services.js @@ -31,7 +31,8 @@ angular.module('dockerui.services', ['ngResource']) url: Settings.url + '/commit', params: { 'container': params.id, - 'tag': params.tag + 'tag': params.tag || null, + 'repo': params.repo || null }, data: params.config }).success(callback).error(function (data, status, headers, config) {