diff --git a/api/cli/cli.go b/api/cli/cli.go index d1bace6a3..5df0ce974 100644 --- a/api/cli/cli.go +++ b/api/cli/cli.go @@ -33,7 +33,6 @@ func (*Service) ParseFlags(version string) (*portainer.CLIFlags, error) { flags := &portainer.CLIFlags{ Addr: kingpin.Flag("bind", "Address and port to serve Portainer").Default(defaultBindAddress).Short('p').String(), Assets: kingpin.Flag("assets", "Path to the assets").Default(defaultAssetsDirectory).Short('a').String(), - CheckHealth: kingpin.Flag("check-health", "GET http://localhost:/api/health endpoint").Default(defaultCheckHealth).Short('c').Bool(), Data: kingpin.Flag("data", "Path to the folder where the data is stored").Default(defaultDataDirectory).Short('d').String(), Endpoint: kingpin.Flag("host", "Dockerd endpoint").Short('H').String(), ExternalEndpoints: kingpin.Flag("external-endpoints", "Path to a file defining available endpoints").String(), diff --git a/api/cli/defaults.go b/api/cli/defaults.go index 2c913ad84..2d350c1c7 100644 --- a/api/cli/defaults.go +++ b/api/cli/defaults.go @@ -6,7 +6,6 @@ const ( defaultBindAddress = ":9000" defaultDataDirectory = "/data" defaultAssetsDirectory = "./" - defaultCheckHealth = "false" defaultNoAuth = "false" defaultNoAnalytics = "false" defaultTLSVerify = "false" diff --git a/api/cli/defaults_windows.go b/api/cli/defaults_windows.go index 9971063b6..a94657258 100644 --- a/api/cli/defaults_windows.go +++ b/api/cli/defaults_windows.go @@ -4,7 +4,6 @@ const ( defaultBindAddress = ":9000" defaultDataDirectory = "C:\\data" defaultAssetsDirectory = "./" - defaultCheckHealth = "false" defaultNoAuth = "false" defaultNoAnalytics = "false" defaultTLSVerify = "false" diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index efa51c1f3..3c8c9f2aa 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -14,7 +14,6 @@ import ( "github.com/portainer/portainer/ldap" "log" - "os" ) func initCLI() *portainer.CLIFlags { @@ -172,19 +171,6 @@ func retrieveFirstEndpointFromDatabase(endpointService portainer.EndpointService func main() { flags := initCLI() - if *flags.CheckHealth { - statuscode, err := http.HealthCheck(*flags.Addr) - if err == nil { - if statuscode == 200 { - log.Println(*flags.Addr, ": Online - response:", statuscode) - os.Exit(0) - } else { - log.Fatal(*flags.Addr, ": Error - response:", statuscode) - } - } - log.Fatal("Connection error:", err.Error()) - } - fileService := initFileService(*flags.Data) store := initStore(*flags.Data) diff --git a/api/http/health_check.go b/api/http/health_check.go deleted file mode 100644 index 08f4623f0..000000000 --- a/api/http/health_check.go +++ /dev/null @@ -1,11 +0,0 @@ -package http - -import ( - "net/http" -) - -// HealthCheck GETs /api/status -func HealthCheck(addr string) (int, error) { - resp, err := http.Get("http://" + addr + "/api/status") - return resp.StatusCode, err -} diff --git a/api/portainer.go b/api/portainer.go index 9aac8cfb2..cdfd3f2ff 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -13,7 +13,6 @@ type ( CLIFlags struct { Addr *string Assets *string - CheckHealth *bool Data *string Endpoint *string ExternalEndpoints *string @@ -391,7 +390,7 @@ type ( const ( // APIVersion is the version number of the Portainer API. - APIVersion = "1.16.0" + APIVersion = "1.16.1" // DBVersion is the version number of the Portainer database. DBVersion = 7 // DefaultTemplatesURL represents the default URL for the templates definitions. diff --git a/api/swagger.yaml b/api/swagger.yaml index 542aeb667..66806bdca 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -56,7 +56,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.16.0" + version: "1.16.1" title: "Portainer API" contact: email: "info@portainer.io" @@ -2143,7 +2143,7 @@ definitions: description: "Is analytics enabled" Version: type: "string" - example: "1.16.0" + example: "1.16.1" description: "Portainer API version" PublicSettingsInspectResponse: type: "object" diff --git a/app/components/service/serviceController.js b/app/components/service/serviceController.js index e39b4a76f..f77910791 100644 --- a/app/components/service/serviceController.js +++ b/app/components/service/serviceController.js @@ -277,12 +277,14 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll, Order: service.UpdateOrder }; - config.TaskTemplate.RestartPolicy = { - Condition: service.RestartCondition, - Delay: ServiceHelper.translateHumanDurationToNanos(service.RestartDelay) || 5000000000, - MaxAttempts: service.RestartMaxAttempts, - Window: ServiceHelper.translateHumanDurationToNanos(service.RestartWindow) || 0 - }; + if ($scope.hasChanges(service, ['RestartCondition', 'RestartDelay', 'RestartMaxAttempts', 'RestartWindow'])){ + config.TaskTemplate.RestartPolicy = { + Condition: service.RestartCondition, + Delay: ServiceHelper.translateHumanDurationToNanos(service.RestartDelay) || 5000000000, + MaxAttempts: service.RestartMaxAttempts, + Window: ServiceHelper.translateHumanDurationToNanos(service.RestartWindow) || 0 + }; + } config.TaskTemplate.LogDriver = null; if (service.LogDriverName) { diff --git a/app/extensions/storidge/rest/cluster.js b/app/extensions/storidge/rest/cluster.js index 98b4fc429..022f8620a 100644 --- a/app/extensions/storidge/rest/cluster.js +++ b/app/extensions/storidge/rest/cluster.js @@ -40,5 +40,13 @@ angular.module('extension.storidge') }); }; + service.shutdown = function() { + return $http({ + method: 'POST', + url: StoridgeManager.StoridgeAPIURL() + '/cluster/shutdown', + skipAuthorization: true + }); + }; + return service; }]); diff --git a/app/extensions/storidge/services/clusterService.js b/app/extensions/storidge/services/clusterService.js index 41cc9a34c..ec1aaec93 100644 --- a/app/extensions/storidge/services/clusterService.js +++ b/app/extensions/storidge/services/clusterService.js @@ -7,6 +7,10 @@ angular.module('extension.storidge') return StoridgeCluster.reboot(); }; + service.shutdown = function() { + return StoridgeCluster.shutdown(); + }; + service.info = function() { var deferred = $q.defer(); diff --git a/app/extensions/storidge/views/cluster/cluster.html b/app/extensions/storidge/views/cluster/cluster.html index 9dfae86a9..da715f485 100644 --- a/app/extensions/storidge/views/cluster/cluster.html +++ b/app/extensions/storidge/views/cluster/cluster.html @@ -37,12 +37,12 @@
diff --git a/app/extensions/storidge/views/cluster/clusterController.js b/app/extensions/storidge/views/cluster/clusterController.js index 371abc8c4..b1d7fbbfa 100644 --- a/app/extensions/storidge/views/cluster/clusterController.js +++ b/app/extensions/storidge/views/cluster/clusterController.js @@ -42,8 +42,18 @@ function ($q, $scope, $state, Notifications, StoridgeClusterService, StoridgeNod }; function shutdownCluster() { - Notifications.error('Not implemented', {}, 'Not implemented yet'); - $state.reload(); + $scope.state.shutdownInProgress = true; + StoridgeClusterService.shutdown() + .then(function success(data) { + Notifications.success('Cluster successfully shutdown'); + $state.go('dashboard'); + }) + .catch(function error(err) { + Notifications.error('Failure', err, 'Unable to shutdown cluster'); + }) + .finally(function final() { + $scope.state.shutdownInProgress = false; + }); } function rebootCluster() { diff --git a/app/services/docker/pluginService.js b/app/services/docker/pluginService.js index b7d94d4e4..85a054738 100644 --- a/app/services/docker/pluginService.js +++ b/app/services/docker/pluginService.js @@ -5,16 +5,17 @@ angular.module('portainer.services') service.plugins = function() { var deferred = $q.defer(); + var plugins = []; Plugin.query({}).$promise .then(function success(data) { - var plugins = data.map(function (item) { - return new PluginViewModel(item); - }); - deferred.resolve(plugins); + for (var i = 0; i < data.length; i++) { + var plugin = new PluginViewModel(data[i]); + plugins.push(plugin); + } }) - .catch(function error(err) { - deferred.reject({ msg: 'Unable to retrieve plugins', err: err }); + .finally(function final() { + deferred.resolve(plugins); }); return deferred.promise; @@ -61,7 +62,7 @@ angular.module('portainer.services') }; service.loggingPlugins = function(systemOnly) { - return servicePlugins(systemOnly, 'Log', 'docker.logdriver/1.0'); + return servicePlugins(systemOnly, 'Log', 'docker.logdriver/1.0'); }; return service; diff --git a/app/services/extensionManager.js b/app/services/extensionManager.js index 32dfe9f0f..9e8b77ae4 100644 --- a/app/services/extensionManager.js +++ b/app/services/extensionManager.js @@ -23,10 +23,9 @@ angular.module('portainer.services') if (_.includes(volumePlugins, 'cio:latest')) { extensions.push('storidge'); } - deferred.resolve(extensions); }) - .catch(function error(err) { - deferred.reject({ msg: 'Unable to retrieve extensions', err: err }); + .finally(function final() { + deferred.resolve(extensions); }); return deferred.promise; diff --git a/app/services/stateManager.js b/app/services/stateManager.js index 36b3dc3cb..c2f358375 100644 --- a/app/services/stateManager.js +++ b/app/services/stateManager.js @@ -114,15 +114,17 @@ angular.module('portainer.services') } $q.all({ info: SystemService.info(), - version: SystemService.version(), - extensions: ExtensionManager.extensions() + version: SystemService.version() }) .then(function success(data) { var endpointMode = InfoHelper.determineEndpointMode(data.info); var endpointAPIVersion = parseFloat(data.version.ApiVersion); state.endpoint.mode = endpointMode; state.endpoint.apiVersion = endpointAPIVersion; - state.endpoint.extensions = data.extensions; + return $q.when(endpointAPIVersion < 1.25 || ExtensionManager.extensions()); + }) + .then(function success(data) { + state.endpoint.extensions = data instanceof Array ? data : []; LocalStorage.storeEndpointState(state.endpoint); deferred.resolve(); }) diff --git a/build/linux/Dockerfile b/build/linux/Dockerfile index 3bbc694f9..e16144acc 100644 --- a/build/linux/Dockerfile +++ b/build/linux/Dockerfile @@ -9,5 +9,3 @@ WORKDIR / EXPOSE 9000 ENTRYPOINT ["/portainer"] - -HEALTHCHECK --start-period=10ms --interval=30s --timeout=5s --retries=3 CMD ["/portainer", "-c"] diff --git a/distribution/portainer.spec b/distribution/portainer.spec index 2e65fa4d0..f2b1b9751 100644 --- a/distribution/portainer.spec +++ b/distribution/portainer.spec @@ -1,5 +1,5 @@ Name: portainer -Version: 1.16.0 +Version: 1.16.1 Release: 0 License: Zlib Summary: A lightweight docker management UI diff --git a/package.json b/package.json index b4f8a52a2..f3880333c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Portainer.io", "name": "portainer", "homepage": "http://portainer.io", - "version": "1.16.0", + "version": "1.16.1", "repository": { "type": "git", "url": "git@github.com:portainer/portainer.git" @@ -45,7 +45,7 @@ "filesize": "~3.3.0", "font-awesome": "~4.7.0", "isteven-angular-multiselect": "~4.0.0", - "jquery": "1.11.1", + "jquery": "^3.3.1", "js-yaml": "~3.10.0", "lodash": "4.12.0", "moment": "~2.14.1", diff --git a/yarn.lock b/yarn.lock index 6aa370d3f..0e86be870 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2370,14 +2370,14 @@ isteven-angular-multiselect@~4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/isteven-angular-multiselect/-/isteven-angular-multiselect-4.0.0.tgz#70276da5ff3bc4d9a0887dc585ee26a1a26a8ed6" -jquery@1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-1.11.1.tgz#b6ec928590112ebed69e1e49cbfd0025ccd60ddb" - jquery@>=1.12.0: version "3.2.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.2.1.tgz#5c4d9de652af6cd0a770154a631bba12b015c787" +jquery@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" + js-base64@^2.1.9: version "2.4.0" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"