mirror of
https://github.com/portainer/portainer.git
synced 2025-08-08 07:15:23 +02:00
feat(docker): show docker pull rate limits (#4666)
* feat(dockerhub): introduce local status endpoint * feat(proxy): rewrite request with dockerhub credentials * feat(endpoint): check env type * feat(endpoint): check for local endpoint * feat(docker): introduce client side service to get limits * feat(container): add info about rate limits in container * feat(dockerhub): load rate limits just for specific endpoints * feat(images): show specific dockerhub messages for admin * feat(service-create): show docker rate limits * feat(service-edit): show rate limit messages * fix(images): fix loading of page * refactor(images): move rate limits check to container * feat(kubernetes): proxy agent requests * feat(kubernetes/apps): show pull limits in application creation * refactor(image-registry): move warning to end of field * fix(image-registry): show right message for admin * fix(images): silently fail when loading rate limits * fix(kube/apps): use new rate limits comp * fix(images): move rate warning to end * fix(registry): move search to right place * fix(service): remove service warning * fix(endpoints): check if kube endpoint is local
This commit is contained in:
parent
d1a21ef6c1
commit
f5aa6c4dc2
29 changed files with 605 additions and 139 deletions
|
@ -58,6 +58,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
|||
endpoint
|
||||
) {
|
||||
$scope.create = create;
|
||||
$scope.endpoint = endpoint;
|
||||
|
||||
$scope.formValues = {
|
||||
alwaysPull: true,
|
||||
|
@ -90,6 +91,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
|||
formValidationError: '',
|
||||
actionInProgress: false,
|
||||
mode: '',
|
||||
pullImageValidity: true,
|
||||
};
|
||||
|
||||
$scope.refreshSlider = function () {
|
||||
|
@ -103,6 +105,14 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
|||
$scope.formValues.EntrypointMode = 'default';
|
||||
};
|
||||
|
||||
$scope.setPullImageValidity = setPullImageValidity;
|
||||
function setPullImageValidity(validity) {
|
||||
if (!validity) {
|
||||
$scope.formValues.alwaysPull = false;
|
||||
}
|
||||
$scope.state.pullImageValidity = validity;
|
||||
}
|
||||
|
||||
$scope.config = {
|
||||
Image: '',
|
||||
Env: [],
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
</div>
|
||||
<div ng-if="!formValues.RegistryModel.Registry && fromContainer">
|
||||
<i class="fa fa-exclamation-triangle orange-icon" aria-hidden="true"></i>
|
||||
<span class="small text-danger" style="margin-left: 5px;"
|
||||
>The Docker registry for the <code>{{ config.Image }}</code> image is not registered inside Portainer, you will not be able to create a container. Please register
|
||||
that registry first.</span
|
||||
>
|
||||
<span class="small text-danger" style="margin-left: 5px;">
|
||||
The Docker registry for the <code>{{ config.Image }}</code> image is not registered inside Portainer, you will not be able to create a container. Please register that
|
||||
registry first.
|
||||
</span>
|
||||
</div>
|
||||
<div ng-if="formValues.RegistryModel.Registry || !fromContainer">
|
||||
<!-- image-and-registry -->
|
||||
|
@ -45,23 +45,30 @@
|
|||
auto-complete="true"
|
||||
label-class="col-sm-1"
|
||||
input-class="col-sm-11"
|
||||
endpoint="endpoint"
|
||||
is-admin="isAdmin"
|
||||
check-rate-limits="formValues.alwaysPull"
|
||||
on-image-change="onImageNameChange()"
|
||||
></por-image-registry>
|
||||
<!-- !image-and-registry -->
|
||||
<!-- always-pull -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label for="ownership" class="control-label text-left">
|
||||
Always pull the image
|
||||
<portainer-tooltip
|
||||
position="bottom"
|
||||
message="When enabled, Portainer will automatically try to pull the specified image before creating the container."
|
||||
></portainer-tooltip>
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px;"> <input type="checkbox" ng-model="formValues.alwaysPull" /><i></i> </label>
|
||||
set-validity="setPullImageValidity"
|
||||
>
|
||||
<!-- always-pull -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label for="ownership" class="control-label text-left">
|
||||
Always pull the image
|
||||
<portainer-tooltip
|
||||
position="bottom"
|
||||
message="When enabled, Portainer will automatically try to pull the specified image before creating the container."
|
||||
></portainer-tooltip>
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px;">
|
||||
<input type="checkbox" ng-model="formValues.alwaysPull" ng-disabled="!state.pullImageValidity" /><i></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !always-pull -->
|
||||
<!-- !always-pull -->
|
||||
</por-image-registry>
|
||||
<!-- !image-and-registry -->
|
||||
</div>
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Network ports configuration
|
||||
|
|
|
@ -14,30 +14,41 @@
|
|||
<rd-widget-body>
|
||||
<form class="form-horizontal">
|
||||
<!-- image-and-registry -->
|
||||
<por-image-registry model="formValues.RegistryModel" auto-complete="true" pull-warning="true" label-class="col-sm-1" input-class="col-sm-11"></por-image-registry>
|
||||
<por-image-registry
|
||||
model="formValues.RegistryModel"
|
||||
auto-complete="true"
|
||||
pull-warning="true"
|
||||
label-class="col-sm-1"
|
||||
input-class="col-sm-11"
|
||||
endpoint="endpoint"
|
||||
is-admin="isAdmin"
|
||||
set-validity="setPullImageValidity"
|
||||
check-rate-limits="true"
|
||||
>
|
||||
<div ng-if="applicationState.endpoint.mode.agentProxy && applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE'">
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Deployment
|
||||
</div>
|
||||
<!-- node-selection -->
|
||||
<node-selector model="formValues.NodeName"> </node-selector>
|
||||
<!-- !node-selection -->
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
ng-disabled="state.actionInProgress || !formValues.RegistryModel.Image || !state.pullRateValid"
|
||||
ng-click="pullImage()"
|
||||
button-spinner="state.actionInProgress"
|
||||
>
|
||||
<span ng-hide="state.actionInProgress">Pull the image</span>
|
||||
<span ng-show="state.actionInProgress">Download in progress...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</por-image-registry>
|
||||
<!-- !image-and-registry -->
|
||||
<div ng-if="applicationState.endpoint.mode.agentProxy && applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE'">
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Deployment
|
||||
</div>
|
||||
<!-- node-selection -->
|
||||
<node-selector model="formValues.NodeName"> </node-selector>
|
||||
<!-- !node-selection -->
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
ng-disabled="state.actionInProgress || !formValues.RegistryModel.Image"
|
||||
ng-click="pullImage()"
|
||||
button-spinner="state.actionInProgress"
|
||||
>
|
||||
<span ng-hide="state.actionInProgress">Pull the image</span>
|
||||
<span ng-show="state.actionInProgress">Download in progress...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { PorImageRegistryModel } from 'Docker/models/porImageRegistry';
|
|||
angular.module('portainer.docker').controller('ImagesController', [
|
||||
'$scope',
|
||||
'$state',
|
||||
'Authentication',
|
||||
'ImageService',
|
||||
'Notifications',
|
||||
'ModalService',
|
||||
|
@ -11,10 +12,15 @@ angular.module('portainer.docker').controller('ImagesController', [
|
|||
'FileSaver',
|
||||
'Blob',
|
||||
'EndpointProvider',
|
||||
function ($scope, $state, ImageService, Notifications, ModalService, HttpRequestHelper, FileSaver, Blob, EndpointProvider) {
|
||||
'endpoint',
|
||||
function ($scope, $state, Authentication, ImageService, Notifications, ModalService, HttpRequestHelper, FileSaver, Blob, EndpointProvider, endpoint) {
|
||||
$scope.endpoint = endpoint;
|
||||
$scope.isAdmin = Authentication.isAdmin();
|
||||
|
||||
$scope.state = {
|
||||
actionInProgress: false,
|
||||
exportInProgress: false,
|
||||
pullRateValid: false,
|
||||
};
|
||||
|
||||
$scope.formValues = {
|
||||
|
@ -140,6 +146,11 @@ angular.module('portainer.docker').controller('ImagesController', [
|
|||
});
|
||||
}
|
||||
|
||||
$scope.setPullImageValidity = setPullImageValidity;
|
||||
function setPullImageValidity(validity) {
|
||||
$scope.state.pullRateValid = validity;
|
||||
}
|
||||
|
||||
function initView() {
|
||||
getImages();
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [
|
|||
$scope.state = {
|
||||
formValidationError: '',
|
||||
actionInProgress: false,
|
||||
pullImageValidity: false,
|
||||
};
|
||||
|
||||
$scope.allowBindMounts = false;
|
||||
|
@ -114,6 +115,11 @@ angular.module('portainer.docker').controller('CreateServiceController', [
|
|||
});
|
||||
};
|
||||
|
||||
$scope.setPullImageValidity = setPullImageValidity;
|
||||
function setPullImageValidity(validity) {
|
||||
$scope.state.pullImageValidity = validity;
|
||||
}
|
||||
|
||||
$scope.addPortBinding = function () {
|
||||
$scope.formValues.Ports.push({ PublishedPort: '', TargetPort: '', Protocol: 'tcp', PublishMode: 'ingress' });
|
||||
};
|
||||
|
|
|
@ -20,7 +20,17 @@
|
|||
Image configuration
|
||||
</div>
|
||||
<!-- image-and-registry -->
|
||||
<por-image-registry model="formValues.RegistryModel" auto-complete="true" label-class="col-sm-1" input-class="col-sm-11"></por-image-registry>
|
||||
<por-image-registry
|
||||
model="formValues.RegistryModel"
|
||||
auto-complete="true"
|
||||
label-class="col-sm-1"
|
||||
input-class="col-sm-11"
|
||||
endpoint="endpoint"
|
||||
is-admin="isAdmin"
|
||||
check-rate-limits="true"
|
||||
set-validity="setPullImageValidity"
|
||||
>
|
||||
</por-image-registry>
|
||||
<!-- !image-and-registry -->
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Scheduling
|
||||
|
|
|
@ -3,7 +3,17 @@
|
|||
<rd-widget-header icon="fa-clone" title-text="Change container image"> </rd-widget-header>
|
||||
<rd-widget-body ng-if="!isUpdating">
|
||||
<form class="form-horizontal">
|
||||
<por-image-registry model="formValues.RegistryModel" auto-complete="true" label-class="col-sm-1" input-class="col-sm-11"></por-image-registry>
|
||||
<por-image-registry
|
||||
model="formValues.RegistryModel"
|
||||
auto-complete="true"
|
||||
label-class="col-sm-1"
|
||||
input-class="col-sm-11"
|
||||
endpoint="endpoint"
|
||||
is-admin="isAdmin"
|
||||
check-rate-limits="true"
|
||||
set-validity="setPullImageValidity"
|
||||
>
|
||||
</por-image-registry>
|
||||
</form>
|
||||
</rd-widget-body>
|
||||
<rd-widget-body ng-if="isUpdating">
|
||||
|
|
|
@ -85,6 +85,8 @@ angular.module('portainer.docker').controller('ServiceController', [
|
|||
NetworkService,
|
||||
endpoint
|
||||
) {
|
||||
$scope.endpoint = endpoint;
|
||||
|
||||
$scope.state = {
|
||||
updateInProgress: false,
|
||||
deletionInProgress: false,
|
||||
|
@ -532,6 +534,11 @@ angular.module('portainer.docker').controller('ServiceController', [
|
|||
});
|
||||
};
|
||||
|
||||
$scope.setPullImageValidity = setPullImageValidity;
|
||||
function setPullImageValidity(validity) {
|
||||
$scope.state.pullImageValidity = validity;
|
||||
}
|
||||
|
||||
$scope.updateService = function updateService(service) {
|
||||
let config = {};
|
||||
service, (config = buildChanges(service));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue