diff --git a/README.md b/README.md index 65694873c..75eb93060 100644 --- a/README.md +++ b/README.md @@ -101,16 +101,6 @@ You can hide it in the view by starting the ui with: $ docker run -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock cloudinovasi/cloudinovasi-ui -l owner=acme ``` -### Custom Docker registries support - -You can specify the support of others registries than DockerHub by using the `--registries` or `-r` options and specifying a registry using the format *REGISTRY_NAME=REGISTRY_ADDRESS*. - -For example, if I want the registry 'myCustomRegistry' pointing to *myregistry.domain.com:5000* available in the UI: - -``` -$ docker run -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock cloudinovasi/cloudinovasi-ui -r myCustomRegistry=myregistry.domain.com:5000 -``` - ### Available options The following options are available for the `ui-for-docker` binary: @@ -120,7 +110,6 @@ The following options are available for the `ui-for-docker` binary: * `--data`, `-d`: Path to the data folder (default: `"."`) * `--assets`, `-a`: Path to the assets (default: `"."`) * `--swarm`, `-s`: Swarm cluster support (default: `false`) -* `--registries`, `-r`: Available registries in the UI (format *REGISTRY_NAME=REGISTRY_ADDRESS*) * `--tlsverify`: TLS support (default: `false`) * `--tlscacert`: Path to the CA (default `/certs/ca.pem`) * `--tlscert`: Path to the TLS certificate file (default `/certs/cert.pem`) diff --git a/api/main.go b/api/main.go index 89abdb47e..1ab338b69 100644 --- a/api/main.go +++ b/api/main.go @@ -8,17 +8,16 @@ import ( func main() { kingpin.Version("1.6.0") var ( - endpoint = kingpin.Flag("host", "Dockerd endpoint").Default("unix:///var/run/docker.sock").Short('H').String() - addr = kingpin.Flag("bind", "Address and port to serve UI For Docker").Default(":9000").Short('p').String() - assets = kingpin.Flag("assets", "Path to the assets").Default(".").Short('a').String() - data = kingpin.Flag("data", "Path to the data").Default(".").Short('d').String() - tlsverify = kingpin.Flag("tlsverify", "TLS support").Default("false").Bool() - tlscacert = kingpin.Flag("tlscacert", "Path to the CA").Default("/certs/ca.pem").String() - tlscert = kingpin.Flag("tlscert", "Path to the TLS certificate file").Default("/certs/cert.pem").String() - tlskey = kingpin.Flag("tlskey", "Path to the TLS key").Default("/certs/key.pem").String() - swarm = kingpin.Flag("swarm", "Swarm cluster support").Default("false").Short('s').Bool() - labels = pairs(kingpin.Flag("hide-label", "Hide containers with a specific label in the UI").Short('l')) - registries = pairs(kingpin.Flag("registries", "Supported Docker registries").Short('r')) + endpoint = kingpin.Flag("host", "Dockerd endpoint").Default("unix:///var/run/docker.sock").Short('H').String() + addr = kingpin.Flag("bind", "Address and port to serve UI For Docker").Default(":9000").Short('p').String() + assets = kingpin.Flag("assets", "Path to the assets").Default(".").Short('a').String() + data = kingpin.Flag("data", "Path to the data").Default(".").Short('d').String() + tlsverify = kingpin.Flag("tlsverify", "TLS support").Default("false").Bool() + tlscacert = kingpin.Flag("tlscacert", "Path to the CA").Default("/certs/ca.pem").String() + tlscert = kingpin.Flag("tlscert", "Path to the TLS certificate file").Default("/certs/cert.pem").String() + tlskey = kingpin.Flag("tlskey", "Path to the TLS key").Default("/certs/key.pem").String() + swarm = kingpin.Flag("swarm", "Swarm cluster support").Default("false").Short('s').Bool() + labels = pairs(kingpin.Flag("hide-label", "Hide containers with a specific label in the UI").Short('l')) logo = kingpin.Flag("logo", "URL for the logo displayed in the UI").String() ) kingpin.Parse() @@ -38,10 +37,6 @@ func main() { settings := &Settings{ Swarm: *swarm, HiddenLabels: *labels, -<<<<<<< HEAD - Registries: *registries, -======= ->>>>>>> feat107-push-registry Logo: *logo, } diff --git a/api/settings.go b/api/settings.go index 4936ceff4..b707a8e69 100644 --- a/api/settings.go +++ b/api/settings.go @@ -9,7 +9,6 @@ import ( type Settings struct { Swarm bool `json:"swarm"` HiddenLabels pairList `json:"hiddenLabels"` - Registries pairList `json:"registries"` Logo string `json:"logo"` } diff --git a/app/app.js b/app/app.js index 77934004a..1b7b13682 100644 --- a/app/app.js +++ b/app/app.js @@ -21,7 +21,9 @@ angular.module('uifordocker', [ 'swarm', 'network', 'networks', - 'volumes']) + 'createNetwork', + 'volumes', + 'createVolume']) .config(['$stateProvider', '$urlRouterProvider', '$httpProvider', function ($stateProvider, $urlRouterProvider, $httpProvider) { 'use strict'; diff --git a/app/components/createNetwork/createNetworkController.js b/app/components/createNetwork/createNetworkController.js new file mode 100644 index 000000000..56ffb79f6 --- /dev/null +++ b/app/components/createNetwork/createNetworkController.js @@ -0,0 +1,74 @@ +angular.module('createNetwork', []) +.controller('CreateNetworkController', ['$scope', '$state', 'Messages', 'Network', 'errorMsgFilter', +function ($scope, $state, Messages, Network, errorMsgFilter) { + $scope.formValues = { + DriverOptions: [], + Subnet: '', + Gateway: '' + }; + + $scope.config = { + Driver: 'bridge', + CheckDuplicate: true, + Internal: false, + IPAM: { + Config: [] + } + }; + + $scope.addDriverOption = function() { + $scope.formValues.DriverOptions.push({ name: '', value: '' }); + }; + + $scope.removeDriverOption = function(index) { + $scope.formValues.DriverOptions.splice(index, 1); + }; + + function createNetwork(config) { + $('#createNetworkSpinner').show(); + Network.create(config, function (d) { + if (d.Id) { + Messages.send("Network created", d.Id); + $('#createNetworkSpinner').hide(); + $state.go('networks', {}, {reload: true}); + } else { + $('#createNetworkSpinner').hide(); + Messages.error('Unable to create network', errorMsgFilter(d)); + } + }, function (e) { + $('#createNetworkSpinner').hide(); + Messages.error('Unable to create network', e.data); + }); + } + + function prepareIPAMConfiguration(config) { + if ($scope.formValues.Subnet) { + var ipamConfig = {}; + ipamConfig.Subnet = $scope.formValues.Subnet; + if ($scope.formValues.Gateway) { + ipamConfig.Gateway = $scope.formValues.Gateway ; + } + config.IPAM.Config.push(ipamConfig); + } + } + + function prepareDriverOptions(config) { + var options = {}; + $scope.formValues.DriverOptions.forEach(function (option) { + options[option.name] = option.value; + }); + config.Options = options; + } + + function prepareConfiguration() { + var config = angular.copy($scope.config); + prepareIPAMConfiguration(config); + prepareDriverOptions(config); + return config; + } + + $scope.create = function () { + var config = prepareConfiguration(); + createNetwork(config); + }; +}]); diff --git a/app/components/createNetwork/createnetwork.html b/app/components/createNetwork/createnetwork.html new file mode 100644 index 000000000..31ed20d37 --- /dev/null +++ b/app/components/createNetwork/createnetwork.html @@ -0,0 +1,95 @@ + + + + Networks > Add network + + + +
+
+ + +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+ +
+ + driver option + +
+ +
+
+
+ name + +
+
+ value + + + + +
+
+
+ +
+ + +
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+ + Cancel +
+
diff --git a/app/components/createVolume/createVolumeController.js b/app/components/createVolume/createVolumeController.js new file mode 100644 index 000000000..fb347adb1 --- /dev/null +++ b/app/components/createVolume/createVolumeController.js @@ -0,0 +1,56 @@ +angular.module('createVolume', []) +.controller('CreateVolumeController', ['$scope', '$state', 'Volume', 'Messages', 'errorMsgFilter', +function ($scope, $state, Volume, Messages, errorMsgFilter) { + + $scope.formValues = { + DriverOptions: [] + }; + + $scope.config = { + Driver: 'local' + }; + + $scope.addDriverOption = function() { + $scope.formValues.DriverOptions.push({ name: '', value: '' }); + }; + + $scope.removeDriverOption = function(index) { + $scope.formValues.DriverOptions.splice(index, 1); + }; + + function createVolume(config) { + $('#createVolumeSpinner').show(); + Volume.create(config, function (d) { + if (d.Name) { + Messages.send("Volume created", d.Name); + $('#createVolumeSpinner').hide(); + $state.go('volumes', {}, {reload: true}); + } else { + $('#createVolumeSpinner').hide(); + Messages.error('Unable to create volume', errorMsgFilter(d)); + } + }, function (e) { + $('#createVolumeSpinner').hide(); + Messages.error('Unable to create volume', e.data); + }); + } + + function prepareDriverOptions(config) { + var options = {}; + $scope.formValues.DriverOptions.forEach(function (option) { + options[option.name] = option.value; + }); + config.DriverOpts = options; + } + + function prepareConfiguration() { + var config = angular.copy($scope.config); + prepareDriverOptions(config); + return config; + } + + $scope.create = function () { + var config = prepareConfiguration(); + createVolume(config); + }; +}]); diff --git a/app/components/createVolume/createvolume.html b/app/components/createVolume/createvolume.html new file mode 100644 index 000000000..b60bc1a27 --- /dev/null +++ b/app/components/createVolume/createvolume.html @@ -0,0 +1,72 @@ + + + + Volumes > Add volume + + + +
+
+ + +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+ +
+ + driver option + +
+ +
+
+
+ name + +
+
+ value + + + + +
+
+
+ +
+ +
+
+
+
+
+ +
+
+
+ +
+ + Cancel +
+
diff --git a/app/components/images/images.html b/app/components/images/images.html index fc840144b..f4bf6fd4e 100644 --- a/app/components/images/images.html +++ b/app/components/images/images.html @@ -22,10 +22,7 @@
- +
@@ -91,6 +88,13 @@ + + + Created + + + + @@ -101,11 +105,12 @@ {{ tag }} {{ image.VirtualSize|humansize }} + {{ image.Created|getisodatefromtimestamp }} - - - + + + diff --git a/app/components/images/imagesController.js b/app/components/images/imagesController.js index 76eac5564..d31cbb01f 100644 --- a/app/components/images/imagesController.js +++ b/app/components/images/imagesController.js @@ -40,7 +40,7 @@ function ($scope, $state, Config, Image, Messages) { $scope.pullImage = function() { $('#pullImageSpinner').show(); var image = _.toLower($scope.config.Image); - var registry = $scope.config.Registry; + var registry = _.toLower($scope.config.Registry); var imageConfig = createImageConfig(image, registry); Image.create(imageConfig, function (data) { var err = data.length > 0 && data[data.length - 1].hasOwnProperty('error'); diff --git a/app/components/networks/networks.html b/app/components/networks/networks.html index 6a558690d..aba75e57f 100644 --- a/app/components/networks/networks.html +++ b/app/components/networks/networks.html @@ -7,64 +7,6 @@ Networks - -
-
- - - - -
- -
- -
- -
-
- - -
-
-
- -
-
-
- - -
- -
- -
- -
- -
-
- - -
-
- Note: The network will be created using the overlay driver and will allow containers to communicate across the hosts of your cluster. -
-
- -
-
- - -
-
-
-
-
-
-
-
@@ -75,6 +17,7 @@
+ Add network
@@ -93,6 +36,13 @@ + + + Id + + + + Scope @@ -100,16 +50,30 @@ + + + Driver + + + + + + + IPAM Driver + + + + - Subnet + IPAM Subnet - Gateway + IPAM Gateway @@ -120,7 +84,10 @@ {{ network.Name|truncate:40}} + {{ network.Id }} {{ network.Scope }} + {{ network.Driver }} + {{ network.IPAM.Driver }} {{ network.IPAM.Config[0].Subnet ? network.IPAM.Config[0].Subnet : '-' }} {{ network.IPAM.Config[0].Gateway ? network.IPAM.Config[0].Gateway : '-' }} diff --git a/app/components/networks/networksController.js b/app/components/networks/networksController.js index d01623177..79347b6e1 100644 --- a/app/components/networks/networksController.js +++ b/app/components/networks/networksController.js @@ -4,7 +4,7 @@ function ($scope, $state, Network, Config, Messages, errorMsgFilter) { $scope.state = {}; $scope.state.selectedItemCount = 0; $scope.state.advancedSettings = false; - $scope.sortType = 'Scope'; + $scope.sortType = 'Name'; $scope.sortReverse = false; $scope.formValues = { @@ -32,44 +32,6 @@ function ($scope, $state, Network, Config, Messages, errorMsgFilter) { } }; - function prepareIPAMConfiguration(config) { - if ($scope.formValues.Subnet) { - var ipamConfig = {}; - ipamConfig.Subnet = $scope.formValues.Subnet; - if ($scope.formValues.Gateway) { - ipamConfig.Gateway = $scope.formValues.Gateway ; - } - config.IPAM.Config.push(ipamConfig); - } - } - - function prepareNetworkConfiguration() { - var config = angular.copy($scope.config); - prepareIPAMConfiguration(config); - if ($scope.swarm) { - config.Driver = 'overlay'; - } - return config; - } - - $scope.createNetwork = function() { - $('#createNetworkSpinner').show(); - var config = prepareNetworkConfiguration(); - Network.create(config, function (d) { - if (d.Id) { - Messages.send("Network created", d.Id); - $('#createNetworkSpinner').hide(); - $state.go('networks', {}, {reload: true}); - } else { - $('#createNetworkSpinner').hide(); - Messages.error('Unable to create network', errorMsgFilter(d)); - } - }, function (e) { - $('#createNetworkSpinner').hide(); - Messages.error('Unable to create network', e.data); - }); - }; - $scope.removeAction = function () { $('#loadNetworksSpinner').show(); var counter = 0; @@ -111,8 +73,5 @@ function ($scope, $state, Network, Config, Messages, errorMsgFilter) { }); } - Config.$promise.then(function (c) { - $scope.swarm = c.swarm; - fetchNetworks(); - }); + fetchNetworks(); }]); diff --git a/app/components/volumes/volumes.html b/app/components/volumes/volumes.html index 6c7cc2bc9..869ec72b4 100644 --- a/app/components/volumes/volumes.html +++ b/app/components/volumes/volumes.html @@ -7,40 +7,6 @@ Volumes -
-
- - - - -
- -
- -
- -
-
- - -
-
- Note: The volume will be created in our persisted storage and will be available across all the hosts of your cluster. -
-
- -
-
- - -
-
-
-
-
-
-
-
@@ -51,6 +17,7 @@
+ Add volume
@@ -76,6 +43,13 @@ + + + Mountpoint + + + + @@ -83,10 +57,11 @@ {{ volume.Name|truncate:50 }} {{ volume.Driver }} + {{ volume.Mountpoint }}
- -
+ +
diff --git a/app/components/volumes/volumesController.js b/app/components/volumes/volumesController.js index 8006af5bc..cad6790e3 100644 --- a/app/components/volumes/volumesController.js +++ b/app/components/volumes/volumesController.js @@ -3,7 +3,7 @@ angular.module('volumes', []) function ($scope, $state, Volume, Messages, errorMsgFilter) { $scope.state = {}; $scope.state.selectedItemCount = 0; - $scope.sortType = 'Driver'; + $scope.sortType = 'Name'; $scope.sortReverse = true; $scope.config = { @@ -23,32 +23,6 @@ function ($scope, $state, Volume, Messages, errorMsgFilter) { } }; - function prepareVolumeConfiguration() { - var config = angular.copy($scope.config); - config.Driver = 'local-persist'; - config.DriverOpts = {}; - config.DriverOpts.mountpoint = '/volume/' + config.Name; - return config; - } - - $scope.createVolume = function() { - $('#createVolumeSpinner').show(); - var config = prepareVolumeConfiguration(); - Volume.create(config, function (d) { - if (d.Name) { - Messages.send("Volume created", d.Name); - $('#createVolumeSpinner').hide(); - $state.go('volumes', {}, {reload: true}); - } else { - $('#createVolumeSpinner').hide(); - Messages.error('Unable to create volume', errorMsgFilter(d)); - } - }, function (e) { - $('#createVolumeSpinner').hide(); - Messages.error('Unable to create volume', e.data); - }); - }; - $scope.removeAction = function () { $('#loadVolumesSpinner').show(); var counter = 0; @@ -77,7 +51,7 @@ function ($scope, $state, Volume, Messages, errorMsgFilter) { function fetchVolumes() { $('#loadVolumesSpinner').show(); Volume.query({}, function (d) { - $scope.volumes = _.uniqBy(d.Volumes, 'Name'); + $scope.volumes = d.Volumes; $('#loadVolumesSpinner').hide(); }, function (e) { Messages.error("Failure", e.data);