diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3ddc75e8c..e26559a7e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -77,14 +77,14 @@ The subject contains succinct description of the change:
## Contribution process
-Our contribution process is described below. Some of the steps can be visualized inside Github via specific `contrib/` labels, such as `contrib/func-review-in-progress` or `contrib/tech-review-approved`.
+Our contribution process is described below. Some of the steps can be visualized inside Github via specific `status/` labels, such as `status/1-functional-review` or `status/2-technical-review`.
### Bug report
-
+
### Feature request
-The feature request process is similar to the bug report process but has an extra functional validation before the technical validation.
+The feature request process is similar to the bug report process but has an extra functional validation before the technical validation as well as a documentation validation before the testing phase.
-
+
diff --git a/api/bolt/migrator/migrator.go b/api/bolt/migrator/migrator.go
index b70172256..4d05820aa 100644
--- a/api/bolt/migrator/migrator.go
+++ b/api/bolt/migrator/migrator.go
@@ -178,7 +178,7 @@ func (m *Migrator) Migrate() error {
}
}
- // 1.19.2-dev
+ // Portainer 1.19.2
if m.currentDBVersion < 14 {
err := m.updateResourceControlsToDBVersion14()
if err != nil {
diff --git a/api/http/client/client.go b/api/http/client/client.go
index 541ec8257..8892b6472 100644
--- a/api/http/client/client.go
+++ b/api/http/client/client.go
@@ -15,6 +15,7 @@ import (
const (
errInvalidResponseStatus = portainer.Error("Invalid response status (expecting 200)")
+ defaultHTTPTimeout = 5
)
// HTTPClient represents a client to send HTTP requests.
@@ -26,7 +27,7 @@ type HTTPClient struct {
func NewHTTPClient() *HTTPClient {
return &HTTPClient{
&http.Client{
- Timeout: time.Second * 5,
+ Timeout: time.Second * time.Duration(defaultHTTPTimeout),
},
}
}
@@ -67,10 +68,16 @@ func (client *HTTPClient) ExecuteAzureAuthenticationRequest(credentials *portain
}
// Get executes a simple HTTP GET to the specified URL and returns
-// the content of the response body.
-func Get(url string) ([]byte, error) {
+// the content of the response body. Timeout can be specified via the timeout parameter,
+// will default to defaultHTTPTimeout if set to 0.
+func Get(url string, timeout int) ([]byte, error) {
+
+ if timeout == 0 {
+ timeout = defaultHTTPTimeout
+ }
+
client := &http.Client{
- Timeout: time.Second * 3,
+ Timeout: time.Second * time.Duration(timeout),
}
response, err := client.Get(url)
diff --git a/api/http/handler/motd/motd.go b/api/http/handler/motd/motd.go
index fbe8b5acd..ca279d890 100644
--- a/api/http/handler/motd/motd.go
+++ b/api/http/handler/motd/motd.go
@@ -16,7 +16,7 @@ type motdResponse struct {
func (handler *Handler) motd(w http.ResponseWriter, r *http.Request) {
- motd, err := client.Get(portainer.MessageOfTheDayURL)
+ motd, err := client.Get(portainer.MessageOfTheDayURL, 0)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
diff --git a/api/http/handler/templates/template_list.go b/api/http/handler/templates/template_list.go
index 24ca93bbd..7e802528f 100644
--- a/api/http/handler/templates/template_list.go
+++ b/api/http/handler/templates/template_list.go
@@ -26,7 +26,7 @@ func (handler *Handler) templateList(w http.ResponseWriter, r *http.Request) *ht
}
} else {
var templateData []byte
- templateData, err = client.Get(settings.TemplatesURL)
+ templateData, err = client.Get(settings.TemplatesURL, 0)
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve external templates", err}
}
diff --git a/api/ldap/ldap.go b/api/ldap/ldap.go
index 528a92e7f..05c9d55d7 100644
--- a/api/ldap/ldap.go
+++ b/api/ldap/ldap.go
@@ -22,11 +22,13 @@ type Service struct{}
func searchUser(username string, conn *ldap.Conn, settings []portainer.LDAPSearchSettings) (string, error) {
var userDN string
found := false
+ usernameEscaped := ldap.EscapeFilter(username)
+
for _, searchSettings := range settings {
searchRequest := ldap.NewSearchRequest(
searchSettings.BaseDN,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
- fmt.Sprintf("(&%s(%s=%s))", searchSettings.Filter, searchSettings.UserNameAttribute, username),
+ fmt.Sprintf("(&%s(%s=%s))", searchSettings.Filter, searchSettings.UserNameAttribute, usernameEscaped),
[]string{"dn"},
nil,
)
@@ -134,12 +136,13 @@ func (*Service) GetUserGroups(username string, settings *portainer.LDAPSettings)
// Get a list of group names for specified user from LDAP/AD
func getGroups(userDN string, conn *ldap.Conn, settings []portainer.LDAPGroupSearchSettings) []string {
groups := make([]string, 0)
+ userDNEscaped := ldap.EscapeFilter(userDN)
for _, searchSettings := range settings {
searchRequest := ldap.NewSearchRequest(
searchSettings.GroupBaseDN,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
- fmt.Sprintf("(&%s(%s=%s))", searchSettings.GroupFilter, searchSettings.GroupAttribute, userDN),
+ fmt.Sprintf("(&%s(%s=%s))", searchSettings.GroupFilter, searchSettings.GroupAttribute, userDNEscaped),
[]string{"cn"},
nil,
)
diff --git a/api/portainer.go b/api/portainer.go
index 839abea7a..2db839506 100644
--- a/api/portainer.go
+++ b/api/portainer.go
@@ -639,7 +639,7 @@ type (
const (
// APIVersion is the version number of the Portainer API
- APIVersion = "1.19.2-dev"
+ APIVersion = "1.20-dev"
// DBVersion is the version number of the Portainer database
DBVersion = 14
// MessageOfTheDayURL represents the URL where Portainer MOTD message can be retrieved
diff --git a/api/swagger.yaml b/api/swagger.yaml
index 17785d43e..1fda7d40f 100644
--- a/api/swagger.yaml
+++ b/api/swagger.yaml
@@ -54,7 +54,7 @@ info:
**NOTE**: You can find more information on how to query the Docker API in the [Docker official documentation](https://docs.docker.com/engine/api/v1.30/) as well as in [this Portainer example](https://gist.github.com/deviantony/77026d402366b4b43fa5918d41bc42f8).
- version: "1.19.2-dev"
+ version: "1.20-dev"
title: "Portainer API"
contact:
email: "info@portainer.io"
@@ -2816,7 +2816,7 @@ definitions:
description: "Is analytics enabled"
Version:
type: "string"
- example: "1.19.2-dev"
+ example: "1.20-dev"
description: "Portainer API version"
PublicSettingsInspectResponse:
type: "object"
diff --git a/app/docker/components/container-restart-policy/container-restart-policy-controller.js b/app/docker/components/container-restart-policy/container-restart-policy-controller.js
index c9ece16d4..64a8604fc 100644
--- a/app/docker/components/container-restart-policy/container-restart-policy-controller.js
+++ b/app/docker/components/container-restart-policy/container-restart-policy-controller.js
@@ -1,36 +1,26 @@
angular
- .module('portainer.docker')
- .controller('ContainerRestartPolicyController', [
- function ContainerRestartPolicyController() {
- var ctrl = this;
+.module('portainer.docker')
+.controller('ContainerRestartPolicyController', [function ContainerRestartPolicyController() {
+ var ctrl = this;
- this.state = {
- editMode :false,
- editModel :{}
- };
-
+ this.state = {
+ editModel : {}
+ };
- ctrl.toggleEdit = toggleEdit;
- ctrl.save = save;
+ ctrl.save = save;
- function toggleEdit() {
- ctrl.state.editMode = true;
- ctrl.state.editModel = {
- name: ctrl.name,
- maximumRetryCount: ctrl.maximumRetryCount
- };
- }
-
- function save() {
- if (ctrl.state.editModel.name === ctrl.name &&
- ctrl.state.editModel.maximumRetryCount === ctrl.maximumRetryCount) {
- ctrl.state.editMode = false;
- return;
- }
- ctrl.updateRestartPolicy(ctrl.state.editModel)
- .then(function onUpdateSucceed() {
- ctrl.state.editMode = false;
- });
- }
+ function save() {
+ if (ctrl.state.editModel.name === ctrl.name && ctrl.state.editModel.maximumRetryCount === ctrl.maximumRetryCount) {
+ return;
}
- ]);
+ ctrl.updateRestartPolicy(ctrl.state.editModel);
+ }
+
+ this.$onInit = function() {
+ ctrl.state.editModel = {
+ name: ctrl.name ? ctrl.name : 'no',
+ maximumRetryCount: ctrl.maximumRetryCount
+ };
+ };
+}
+]);
diff --git a/app/docker/components/container-restart-policy/container-restart-policy.html b/app/docker/components/container-restart-policy/container-restart-policy.html
index c5352b6e4..41b87c2fc 100644
--- a/app/docker/components/container-restart-policy/container-restart-policy.html
+++ b/app/docker/components/container-restart-policy/container-restart-policy.html
@@ -1,23 +1,5 @@
-
-
-
-
-
-
- Name
- |
- {{$ctrl.name }} |
-
-
- Maximum Retry Count |
-
- {{ $ctrl.maximumRetryCount }}
- |
-
-
-
-
+
-
\ No newline at end of file
+
diff --git a/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html b/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html
index 433be02d8..cfba0524f 100644
--- a/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html
+++ b/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html
@@ -65,7 +65,7 @@
diff --git a/app/docker/views/containers/edit/container.html b/app/docker/views/containers/edit/container.html
index 92815f9c0..a251ae2d2 100644
--- a/app/docker/views/containers/edit/container.html
+++ b/app/docker/views/containers/edit/container.html
@@ -226,7 +226,7 @@
|
Restart policies |
-
diff --git a/app/docker/views/containers/edit/containerController.js b/app/docker/views/containers/edit/containerController.js
index e7b1a988b..f687b116c 100644
--- a/app/docker/views/containers/edit/containerController.js
+++ b/app/docker/views/containers/edit/containerController.js
@@ -323,6 +323,7 @@ function ($q, $scope, $state, $transition$, $filter, Commit, ContainerHelper, Co
Name: restartPolicy,
MaximumRetryCount: maximumRetryCount
};
+ Notifications.success('Restart policy updated');
}
function notifyOnError(err) {
diff --git a/app/portainer/views/endpoints/create/createEndpointController.js b/app/portainer/views/endpoints/create/createEndpointController.js
index 13fc1ad16..c682bee1b 100644
--- a/app/portainer/views/endpoints/create/createEndpointController.js
+++ b/app/portainer/views/endpoints/create/createEndpointController.js
@@ -1,6 +1,6 @@
angular.module('portainer.app')
-.controller('CreateEndpointController', ['$q', '$scope', '$state', '$filter', 'EndpointService', 'GroupService', 'TagService', 'Notifications',
-function ($q, $scope, $state, $filter, EndpointService, GroupService, TagService, Notifications) {
+.controller('CreateEndpointController', ['$q', '$scope', '$state', '$filter', 'clipboard', 'EndpointService', 'GroupService', 'TagService', 'Notifications',
+function ($q, $scope, $state, $filter, clipboard, EndpointService, GroupService, TagService, Notifications) {
$scope.state = {
EnvironmentType: 'docker',
@@ -19,6 +19,12 @@ function ($q, $scope, $state, $filter, EndpointService, GroupService, TagService
Tags: []
};
+ $scope.copyAgentCommand = function() {
+ clipboard.copyText('curl -L https://portainer.io/download/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent');
+ $('#copyNotification').show();
+ $('#copyNotification').fadeOut(2000);
+ };
+
$scope.addDockerEndpoint = function() {
var name = $scope.formValues.Name;
var URL = $filter('stripprotocol')($scope.formValues.URL);
diff --git a/app/portainer/views/endpoints/create/createendpoint.html b/app/portainer/views/endpoints/create/createendpoint.html
index ff8e7c232..4b7a762bd 100644
--- a/app/portainer/views/endpoints/create/createendpoint.html
+++ b/app/portainer/views/endpoints/create/createendpoint.html
@@ -64,8 +64,16 @@
diff --git a/build.sh b/build.sh
index 36e86b8a9..c00f5dd0b 100755
--- a/build.sh
+++ b/build.sh
@@ -24,7 +24,7 @@ function build_archive() {
function build_all() {
mkdir -pv "${ARCHIVE_BUILD_FOLDER}"
for tag in $@; do
- grunt "release:`echo "$tag" | tr '-' ':'`"
+ yarn grunt "release:`echo "$tag" | tr '-' ':'`"
name="portainer"; if [ "$(echo "$tag" | cut -c1)" = "w" ]; then name="${name}.exe"; fi
mv dist/portainer-$tag* dist/$name
if [ `echo $tag | cut -d \- -f 1` == 'linux' ]; then build_and_push_images "$tag"; fi
diff --git a/distribution/portainer.spec b/distribution/portainer.spec
index c62ed0b72..abbd4b371 100644
--- a/distribution/portainer.spec
+++ b/distribution/portainer.spec
@@ -1,5 +1,5 @@
Name: portainer
-Version: 1.19.2-dev
+Version: 1.20-dev
Release: 0
License: Zlib
Summary: A lightweight docker management UI
diff --git a/gruntfile.js b/gruntfile.js
index 79e05c95d..873d55473 100644
--- a/gruntfile.js
+++ b/gruntfile.js
@@ -80,7 +80,7 @@ module.exports = function (grunt) {
grunt.initConfig({
root: 'dist',
distdir: 'dist/public',
- shippedDockerVersion: '18.03.1-ce',
+ shippedDockerVersion: '18.06.1-ce',
shippedDockerVersionWindows: '17.09.0-ce',
pkg: grunt.file.readJSON('package.json'),
config: gruntfile_cfg.config,
diff --git a/package.json b/package.json
index b908a30b3..6d7486278 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"author": "Portainer.io",
"name": "portainer",
"homepage": "http://portainer.io",
- "version": "1.19.2-dev",
+ "version": "1.20-dev",
"repository": {
"type": "git",
"url": "git@github.com:portainer/portainer.git"
@@ -20,6 +20,7 @@
}
],
"scripts": {
+ "grunt": "grunt",
"dev": "yarn grunt run-dev",
"clean-all": "yarn grunt clean:all",
"build": "yarn grunt build",
|