mirror of
https://github.com/portainer/portainer.git
synced 2025-07-27 01:09:41 +02:00
Merge branch 'release/1.9.1'
This commit is contained in:
commit
e88b22bd45
21 changed files with 96 additions and 88 deletions
|
@ -3,6 +3,7 @@
|
||||||
The easiest way to manage Docker.
|
The easiest way to manage Docker.
|
||||||
|
|
||||||
[](http://microbadger.com/images/portainer/portainer "Image size")
|
[](http://microbadger.com/images/portainer/portainer "Image size")
|
||||||
|
[](http://portainer.readthedocs.io/en/stable/?badge=stable)
|
||||||
[](https://gitter.im/portainer/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
[](https://gitter.im/portainer/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
|
|
||||||
Portainer is a lightweight management UI which allows you to **easily** manage your Docker host or Swarm cluster.
|
Portainer is a lightweight management UI which allows you to **easily** manage your Docker host or Swarm cluster.
|
||||||
|
@ -29,7 +30,7 @@ If you don't specify any target, its default behaviour is to use a bind mount on
|
||||||
$ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
|
$ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
|
||||||
```
|
```
|
||||||
|
|
||||||
Have a look at our [wiki](https://github.com/portainer/portainer/wiki/Deployment) for more deployment options.
|
Have a look at our [documentation](http://portainer.readthedocs.io/en/stable/deployment.html) for more deployment options.
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
|
@ -61,13 +62,13 @@ Add the `--templates` flag and specify the external location of your templates w
|
||||||
$ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer --templates http://my-host.my-domain/templates.json
|
$ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer --templates http://my-host.my-domain/templates.json
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information about hosting your own template definitions and the format, see: https://github.com/portainer/templates
|
For more information about hosting your own template definitions and the format, see the [templates documentation](http://portainer.readthedocs.io/en/stable/templates.html).
|
||||||
|
|
||||||
Have a look at our [wiki](https://github.com/portainer/portainer/wiki/Configuration) for more configuration options.
|
Check our [documentation](http://portainer.readthedocs.io/en/stable/configuration.html) for more configuration options.
|
||||||
|
|
||||||
# FAQ
|
# FAQ
|
||||||
|
|
||||||
Be sure to check our [FAQ](https://github.com/portainer/portainer/wiki/FAQ) if you are missing some information.
|
Be sure to check our [FAQ](http://portainer.readthedocs.io/en/stable/faq.html) if you are missing some information.
|
||||||
|
|
||||||
# Limitations
|
# Limitations
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
// main is the entry point of the program
|
// main is the entry point of the program
|
||||||
func main() {
|
func main() {
|
||||||
kingpin.Version("1.9.0")
|
kingpin.Version("1.9.1")
|
||||||
var (
|
var (
|
||||||
endpoint = kingpin.Flag("host", "Dockerd endpoint").Default("unix:///var/run/docker.sock").Short('H').String()
|
endpoint = kingpin.Flag("host", "Dockerd endpoint").Default("unix:///var/run/docker.sock").Short('H').String()
|
||||||
addr = kingpin.Flag("bind", "Address and port to serve Portainer").Default(":9000").Short('p').String()
|
addr = kingpin.Flag("bind", "Address and port to serve Portainer").Default(":9000").Short('p').String()
|
||||||
|
|
|
@ -188,4 +188,4 @@ angular.module('portainer', [
|
||||||
.constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is requred. If you have a port, prefix it with a ':' i.e. :4243
|
.constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is requred. If you have a port, prefix it with a ':' i.e. :4243
|
||||||
.constant('CONFIG_ENDPOINT', 'settings')
|
.constant('CONFIG_ENDPOINT', 'settings')
|
||||||
.constant('TEMPLATES_ENDPOINT', 'templates')
|
.constant('TEMPLATES_ENDPOINT', 'templates')
|
||||||
.constant('UI_VERSION', 'v1.9.0');
|
.constant('UI_VERSION', 'v1.9.1');
|
||||||
|
|
|
@ -9,7 +9,7 @@ function ($scope, $stateParams, Settings, Container, Exec, $timeout, Messages) {
|
||||||
|
|
||||||
// Ensure the socket is closed before leaving the view
|
// Ensure the socket is closed before leaving the view
|
||||||
$scope.$on('$stateChangeStart', function (event, next, current) {
|
$scope.$on('$stateChangeStart', function (event, next, current) {
|
||||||
if (socket !== null) {
|
if (socket && socket !== null) {
|
||||||
socket.close();
|
socket.close();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
<th>
|
<th>
|
||||||
<a ui-sref="containers" ng-click="order('Status')">
|
<a ui-sref="containers" ng-click="order('Status')">
|
||||||
State
|
State
|
||||||
<span ng-show="sortType == 'State' && !sortReverse" class="glyphicon glyphicon-chevron-down"></span>
|
<span ng-show="sortType == 'Status' && !sortReverse" class="glyphicon glyphicon-chevron-down"></span>
|
||||||
<span ng-show="sortType == 'State' && sortReverse" class="glyphicon glyphicon-chevron-up"></span>
|
<span ng-show="sortType == 'Status' && sortReverse" class="glyphicon glyphicon-chevron-up"></span>
|
||||||
</a>
|
</a>
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
<td ng-if="swarm && !swarm_mode">{{ container.hostIP }}</td>
|
<td ng-if="swarm && !swarm_mode">{{ container.hostIP }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a ng-if="container.Ports.length > 0" ng-repeat="p in container.Ports" class="image-tag" ng-href="http://{{p.host}}:{{p.public}}" target="_blank">
|
<a ng-if="container.Ports.length > 0" ng-repeat="p in container.Ports" class="image-tag" ng-href="http://{{p.host}}:{{p.public}}" target="_blank">
|
||||||
<i class="fa fa-external-link" aria-hidden="true"></i> {{ p.private }}
|
<i class="fa fa-external-link" aria-hidden="true"></i> {{p.public}}:{{ p.private }}
|
||||||
</a>
|
</a>
|
||||||
<span ng-if="container.Ports.length == 0" >-</span>
|
<span ng-if="container.Ports.length == 0" >-</span>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Nodes</td>
|
<td>Nodes</td>
|
||||||
<td>{{ infoData.SystemStatus[3][1] }}</td>
|
<td>{{ infoData.SystemStatus[0][1] == 'primary' ? infoData.SystemStatus[3][1] : infoData.SystemStatus[4][1] }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Swarm version</td>
|
<td>Swarm version</td>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Total memory</td>
|
<td>Total memory</td>
|
||||||
<td>{{ infoData.MemTotal|humansize }}</td>
|
<td>{{ infoData.MemTotal|humansize: 2 }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -87,7 +87,7 @@ function (Settings, $scope, Messages, $timeout, Container, ContainerTop, $stateP
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scaleLabel: function (valueObj) {
|
scaleLabel: function (valueObj) {
|
||||||
return humansizeFilter(parseInt(valueObj.value, 10));
|
return humansizeFilter(parseInt(valueObj.value, 10), 2);
|
||||||
},
|
},
|
||||||
responsive: true
|
responsive: true
|
||||||
//scaleOverride: true,
|
//scaleOverride: true,
|
||||||
|
@ -100,7 +100,7 @@ function (Settings, $scope, Messages, $timeout, Container, ContainerTop, $stateP
|
||||||
datasets: [networkRxDataset, networkTxDataset]
|
datasets: [networkRxDataset, networkTxDataset]
|
||||||
}, {
|
}, {
|
||||||
scaleLabel: function (valueObj) {
|
scaleLabel: function (valueObj) {
|
||||||
return humansizeFilter(parseInt(valueObj.value, 10));
|
return humansizeFilter(parseInt(valueObj.value, 10), 2);
|
||||||
},
|
},
|
||||||
responsive: true
|
responsive: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Total memory</td>
|
<td>Total memory</td>
|
||||||
<td ng-if="!swarm_mode">{{ info.MemTotal|humansize }}</td>
|
<td ng-if="!swarm_mode">{{ info.MemTotal|humansize: 2 }}</td>
|
||||||
<td ng-if="swarm_mode">{{ totalMemory|humansize }}</td>
|
<td ng-if="swarm_mode">{{ totalMemory|humansize: 2 }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-if="!swarm_mode">
|
<tr ng-if="!swarm_mode">
|
||||||
<td>Operating system</td>
|
<td>Operating system</td>
|
||||||
|
|
|
@ -47,7 +47,8 @@ function ($scope, Info, Version, Node) {
|
||||||
// Swarm filters
|
// Swarm filters
|
||||||
$scope.swarm[systemStatus[2][0]] = systemStatus[2][1];
|
$scope.swarm[systemStatus[2][0]] = systemStatus[2][1];
|
||||||
// Swarm node count
|
// Swarm node count
|
||||||
var node_count = parseInt(systemStatus[3][1], 10);
|
var nodes = systemStatus[0][1] === 'primary' ? systemStatus[3][1] : systemStatus[4][1];
|
||||||
|
var node_count = parseInt(nodes, 10);
|
||||||
$scope.swarm[systemStatus[3][0]] = node_count;
|
$scope.swarm[systemStatus[3][0]] = node_count;
|
||||||
|
|
||||||
$scope.swarm.Status = [];
|
$scope.swarm.Status = [];
|
||||||
|
@ -55,9 +56,10 @@ function ($scope, Info, Version, Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractNodesInfo(info, node_count) {
|
function extractNodesInfo(info, node_count) {
|
||||||
// First information for node1 available at element #4 of SystemStatus
|
// First information for node1 available at element #4 of SystemStatus if connected to a primary
|
||||||
|
// If connected to a replica, information for node1 is available at element #5
|
||||||
// The next 10 elements are information related to the node
|
// The next 10 elements are information related to the node
|
||||||
var node_offset = 4;
|
var node_offset = info[0][1] === 'primary' ? 4 : 5;
|
||||||
for (i = 0; i < node_count; i++) {
|
for (i = 0; i < node_count; i++) {
|
||||||
extractNodeInfo(info, node_offset);
|
extractNodeInfo(info, node_offset);
|
||||||
node_offset += 9;
|
node_offset += 9;
|
||||||
|
|
|
@ -7,31 +7,11 @@
|
||||||
<rd-header-content>Templates</rd-header-content>
|
<rd-header-content>Templates</rd-header-content>
|
||||||
</rd-header>
|
</rd-header>
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 col-md-12 col-xs-12">
|
|
||||||
<rd-widget>
|
|
||||||
<rd-widget-header icon="fa-rocket" title="Available templates">
|
|
||||||
<div class="pull-right">
|
|
||||||
<i id="loadTemplatesSpinner" class="fa fa-cog fa-2x fa-spin" style="margin-top: 5px;"></i>
|
|
||||||
</div>
|
|
||||||
</rd-widget-header>
|
|
||||||
<rd-widget-body classes="padding">
|
|
||||||
<div class="template-list">
|
|
||||||
<div ng-repeat="tpl in templates" class="container-template hvr-grow" id="template_{{ $index }}" ng-click="selectTemplate($index)">
|
|
||||||
<img class="logo" ng-src="{{ tpl.logo }}" />
|
|
||||||
<div class="title">{{ tpl.title }}</div>
|
|
||||||
<div class="description">{{ tpl.description }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</rd-widget-body>
|
|
||||||
</rd-widget>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row" ng-if="selectedTemplate">
|
<div class="row" ng-if="selectedTemplate">
|
||||||
<div class="col-lg-12 col-md-12 col-xs-12">
|
<div class="col-lg-12 col-md-12 col-xs-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
<rd-widget-header icon="fa-cogs" title="Configuration"></rd-widget-header>
|
<rd-widget-custom-header icon="selectedTemplate.logo" title="selectedTemplate.image">
|
||||||
|
</rd-widget-custom-header>
|
||||||
<rd-widget-body classes="padding">
|
<rd-widget-body classes="padding">
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div class="form-group" ng-if="globalNetworkCount === 0 && !swarm_mode">
|
<div class="form-group" ng-if="globalNetworkCount === 0 && !swarm_mode">
|
||||||
|
@ -62,15 +42,21 @@
|
||||||
<div ng-repeat="var in selectedTemplate.env" ng-if="!var.set" class="form-group">
|
<div ng-repeat="var in selectedTemplate.env" ng-if="!var.set" class="form-group">
|
||||||
<label for="field_{{ $index }}" class="col-sm-2 control-label text-left">{{ var.label }}</label>
|
<label for="field_{{ $index }}" class="col-sm-2 control-label text-left">{{ var.label }}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select ng-if="!swarm && var.type === 'container'" ng-options="container|containername for container in runningContainers" class="selectpicker form-control" ng-model="var.value">
|
<select ng-if="(!swarm || swarm && swarm_mode) && var.type === 'container'" ng-options="container|containername for container in runningContainers" class="selectpicker form-control" ng-model="var.value">
|
||||||
<option selected disabled hidden value="">Select a container</option>
|
<option selected disabled hidden value="">Select a container</option>
|
||||||
</select>
|
</select>
|
||||||
<select ng-if="swarm && var.type === 'container'" ng-options="container|swarmcontainername for container in runningContainers" class="selectpicker form-control" ng-model="var.value">
|
<select ng-if="swarm && !swarm_mode && var.type === 'container'" ng-options="container|swarmcontainername for container in runningContainers" class="selectpicker form-control" ng-model="var.value">
|
||||||
<option selected disabled hidden value="">Select a container</option>
|
<option selected disabled hidden value="">Select a container</option>
|
||||||
</select>
|
</select>
|
||||||
<input ng-if="!var.type || !var.type === 'container'" type="text" class="form-control" ng-model="var.value" id="field_{{ $index }}">
|
<input ng-if="!var.type || !var.type === 'container'" type="text" class="form-control" ng-model="var.value" id="field_{{ $index }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<button type="button" class="btn btn-default btn-sm" ng-disabled="!formValues.network" ng-click="createTemplate()">Create</button>
|
||||||
|
<i id="createContainerSpinner" class="fa fa-cog fa-spin" style="margin-left: 5px; display: none;"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
</rd-widget>
|
</rd-widget>
|
||||||
|
@ -78,10 +64,26 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" ng-if="selectedTemplate">
|
<div class="row" ng-if="selectedTemplate">
|
||||||
<div class="col-lg-12 col-md-12 col-xs-12" style="text-align: center;">
|
|
||||||
<div>
|
</div>
|
||||||
<i id="createContainerSpinner" class="fa fa-cog fa-3x fa-spin" style="margin-bottom: 5px; display: none;"></i>
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 col-md-12 col-xs-12">
|
||||||
|
<rd-widget>
|
||||||
|
<rd-widget-header icon="fa-rocket" title="Available templates">
|
||||||
|
<div class="pull-right">
|
||||||
|
<i id="loadTemplatesSpinner" class="fa fa-cog fa-2x fa-spin" style="margin-top: 5px;"></i>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-default btn-lg" ng-disabled="!formValues.network" ng-click="createTemplate()">Create</button>
|
</rd-widget-header>
|
||||||
|
<rd-widget-body classes="padding">
|
||||||
|
<div class="template-list">
|
||||||
|
<div ng-repeat="tpl in templates" class="container-template hvr-grow" id="template_{{ $index }}" ng-click="selectTemplate($index)">
|
||||||
|
<img class="logo" ng-src="{{ tpl.logo }}" />
|
||||||
|
<div class="title">{{ tpl.title }}</div>
|
||||||
|
<div class="description">{{ tpl.description }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</rd-widget-body>
|
||||||
|
</rd-widget>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
15
app/directives/widget-custom-header.js
Normal file
15
app/directives/widget-custom-header.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
angular
|
||||||
|
.module('portainer')
|
||||||
|
.directive('rdWidgetCustomHeader', function rdWidgetCustomHeader() {
|
||||||
|
var directive = {
|
||||||
|
requires: '^rdWidget',
|
||||||
|
scope: {
|
||||||
|
title: '=',
|
||||||
|
icon: '='
|
||||||
|
},
|
||||||
|
transclude: true,
|
||||||
|
template: '<div class="widget-header"><div class="row"><span class="pull-left"><img class="custom-header-ico" ng-src="{{icon}}"></img> <span class="small text-muted"> {{title}} </span> </span><span class="pull-right col-xs-6 col-sm-4" ng-transclude></span></div></div>',
|
||||||
|
restrict: 'E'
|
||||||
|
};
|
||||||
|
return directive;
|
||||||
|
});
|
|
@ -123,15 +123,13 @@ angular.module('portainer.filters', [])
|
||||||
})
|
})
|
||||||
.filter('humansize', function () {
|
.filter('humansize', function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
return function (bytes) {
|
return function (bytes, round) {
|
||||||
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
if (!round) {
|
||||||
if (bytes === 0) {
|
round = 1;
|
||||||
return 'n/a';
|
}
|
||||||
|
if (bytes || bytes === 0) {
|
||||||
|
return filesize(bytes, {base: 10, round: round});
|
||||||
}
|
}
|
||||||
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10);
|
|
||||||
var value = bytes / Math.pow(1024, i);
|
|
||||||
var decimalPlaces = (i < 1) ? 0 : (i - 1);
|
|
||||||
return value.toFixed(decimalPlaces) + ' ' + sizes[[i]];
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter('containername', function () {
|
.filter('containername', function () {
|
||||||
|
|
|
@ -105,6 +105,9 @@ function createEventDetails(event) {
|
||||||
case 'unpause':
|
case 'unpause':
|
||||||
details = 'Container ' + eventAttr.name + ' unpaused';
|
details = 'Container ' + eventAttr.name + ' unpaused';
|
||||||
break;
|
break;
|
||||||
|
case 'attach':
|
||||||
|
details = 'Container ' + eventAttr.name + ' attached';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (event.Action.indexOf('exec_create') === 0) {
|
if (event.Action.indexOf('exec_create') === 0) {
|
||||||
details = 'Exec instance created';
|
details = 'Exec instance created';
|
||||||
|
@ -159,6 +162,12 @@ function createEventDetails(event) {
|
||||||
case 'destroy':
|
case 'destroy':
|
||||||
details = 'Volume ' + event.Actor.ID + ' deleted';
|
details = 'Volume ' + event.Actor.ID + ' deleted';
|
||||||
break;
|
break;
|
||||||
|
case 'mount':
|
||||||
|
details = 'Volume ' + event.Actor.ID + ' mounted';
|
||||||
|
break;
|
||||||
|
case 'unmount':
|
||||||
|
details = 'Volume ' + event.Actor.ID + ' unmounted';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
details = 'Unsupported event';
|
details = 'Unsupported event';
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,6 +216,11 @@ input[type="radio"] {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-header-ico {
|
||||||
|
max-width: 16px;
|
||||||
|
max-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.container-template {
|
.container-template {
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
width: 256px;
|
width: 256px;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 880 B |
Binary file not shown.
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 880 B |
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "portainer",
|
"name": "portainer",
|
||||||
"version": "1.9.0",
|
"version": "1.9.1",
|
||||||
"homepage": "https://github.com/portainer/portainer",
|
"homepage": "https://github.com/portainer/portainer",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Anthony Lapenna <anthony.lapenna at gmail dot com>"
|
"Anthony Lapenna <anthony.lapenna at gmail dot com>"
|
||||||
|
@ -34,13 +34,14 @@
|
||||||
"angular-ui-select": "~0.17.1",
|
"angular-ui-select": "~0.17.1",
|
||||||
"bootstrap": "~3.3.6",
|
"bootstrap": "~3.3.6",
|
||||||
"font-awesome": "~4.6.3",
|
"font-awesome": "~4.6.3",
|
||||||
|
"filesize": "~3.3.0",
|
||||||
"Hover": "2.0.2",
|
"Hover": "2.0.2",
|
||||||
"jquery": "1.11.1",
|
"jquery": "1.11.1",
|
||||||
"jquery.gritter": "1.7.4",
|
"jquery.gritter": "1.7.4",
|
||||||
"lodash": "4.12.0",
|
"lodash": "4.12.0",
|
||||||
"rdash-ui": "1.0.*",
|
"rdash-ui": "1.0.*",
|
||||||
"moment": "~2.14.1",
|
"moment": "~2.14.1",
|
||||||
"xterm.js": "~1.0.0"
|
"xterm.js": "~1.1.3"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"angular": "1.5.5"
|
"angular": "1.5.5"
|
||||||
|
|
|
@ -71,6 +71,7 @@ module.exports = function (grunt) {
|
||||||
'bower_components/bootstrap/dist/js/bootstrap.min.js',
|
'bower_components/bootstrap/dist/js/bootstrap.min.js',
|
||||||
'bower_components/Chart.js/Chart.min.js',
|
'bower_components/Chart.js/Chart.min.js',
|
||||||
'bower_components/lodash/dist/lodash.min.js',
|
'bower_components/lodash/dist/lodash.min.js',
|
||||||
|
'bower_components/filesize/lib/filesize.min.js',
|
||||||
'bower_components/moment/min/moment.min.js',
|
'bower_components/moment/min/moment.min.js',
|
||||||
'bower_components/xterm.js/src/xterm.js',
|
'bower_components/xterm.js/src/xterm.js',
|
||||||
'assets/js/jquery.gritter.js', // Using custom version to fix error in minified build due to "use strict"
|
'assets/js/jquery.gritter.js', // Using custom version to fix error in minified build due to "use strict"
|
||||||
|
@ -274,7 +275,7 @@ module.exports = function (grunt) {
|
||||||
command: [
|
command: [
|
||||||
'docker stop portainer',
|
'docker stop portainer',
|
||||||
'docker rm portainer',
|
'docker rm portainer',
|
||||||
'docker run -d -p 9000:9000 -v /tmp/portainer:/data --name portainer portainer -H tcp://10.0.7.10:4000 --swarm -d /data'
|
'docker run -d -p 9000:9000 -v /tmp/portainer:/data --name portainer portainer -H tcp://10.0.7.10:2375 --swarm -d /data'
|
||||||
].join(';')
|
].join(';')
|
||||||
},
|
},
|
||||||
runSsl: {
|
runSsl: {
|
||||||
|
|
|
@ -59,13 +59,13 @@
|
||||||
<li class="sidebar-list">
|
<li class="sidebar-list">
|
||||||
<a ui-sref="volumes">Volumes <span class="menu-icon fa fa-cubes"></span></a>
|
<a ui-sref="volumes">Volumes <span class="menu-icon fa fa-cubes"></span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="sidebar-list" ng-if="swarm_mode || !swarm">
|
<li class="sidebar-list" ng-if="!swarm">
|
||||||
<a ui-sref="events">Events <span class="menu-icon fa fa-history"></span></a>
|
<a ui-sref="events">Events <span class="menu-icon fa fa-history"></span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="sidebar-list" ng-if="(swarm && !swarm_mode) || (swarm_mode && swarm_manager)">
|
<li class="sidebar-list" ng-if="(swarm && !swarm_mode) || (swarm_mode && swarm_manager)">
|
||||||
<a ui-sref="swarm">Swarm <span class="menu-icon fa fa-object-group"></span></a>
|
<a ui-sref="swarm">Swarm <span class="menu-icon fa fa-object-group"></span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="sidebar-list" ng-if="swarm_mode || !swarm">
|
<li class="sidebar-list" ng-if="!swarm">
|
||||||
<a ui-sref="docker">Docker <span class="menu-icon fa fa-cogs"></span></a>
|
<a ui-sref="docker">Docker <span class="menu-icon fa fa-cogs"></span></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"author": "Portainer.io",
|
"author": "Portainer.io",
|
||||||
"name": "portainer",
|
"name": "portainer",
|
||||||
"homepage": "http://portainer.io",
|
"homepage": "http://portainer.io",
|
||||||
"version": "1.9.0",
|
"version": "1.9.1",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git@github.com:portainer/portainer.git"
|
"url": "git@github.com:portainer/portainer.git"
|
||||||
|
|
|
@ -82,32 +82,6 @@ describe('filters', function () {
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('humansize', function () {
|
|
||||||
it('should return n/a when size is zero', inject(function (humansizeFilter) {
|
|
||||||
expect(humansizeFilter(0)).toBe('n/a');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should handle Bytes values', inject(function (humansizeFilter) {
|
|
||||||
expect(humansizeFilter(512)).toBe('512 Bytes');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should handle KB values', inject(function (humansizeFilter) {
|
|
||||||
expect(humansizeFilter(5 * 1024)).toBe('5 KB');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should handle MB values', inject(function (humansizeFilter) {
|
|
||||||
expect(humansizeFilter(5 * 1024 * 1024)).toBe('5.0 MB');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should handle GB values', inject(function (humansizeFilter) {
|
|
||||||
expect(humansizeFilter(5 * 1024 * 1024 * 1024)).toBe('5.00 GB');
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should handle TB values', inject(function (humansizeFilter) {
|
|
||||||
expect(humansizeFilter(5 * 1024 * 1024 * 1024 * 1024)).toBe('5.000 TB');
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('containername', function () {
|
describe('containername', function () {
|
||||||
it('should strip the leading slash from container name', inject(function (containernameFilter) {
|
it('should strip the leading slash from container name', inject(function (containernameFilter) {
|
||||||
var container = {
|
var container = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue