mirror of https://github.com/portainer/portainer
fix(UI) check image name when build image EE-3010 (#7409)
* EE-3010 check image name when build imagepull/7429/head
parent
f2d93654f5
commit
2574f223b4
|
@ -1,5 +1,6 @@
|
||||||
angular.module('portainer.docker').controller('BuildImageController', BuildImageController);
|
angular.module('portainer.docker').controller('BuildImageController', BuildImageController);
|
||||||
|
|
||||||
|
/* @ngInject */
|
||||||
function BuildImageController($scope, $async, $window, ModalService, BuildService, Notifications, HttpRequestHelper) {
|
function BuildImageController($scope, $async, $window, ModalService, BuildService, Notifications, HttpRequestHelper) {
|
||||||
$scope.state = {
|
$scope.state = {
|
||||||
BuildType: 'editor',
|
BuildType: 'editor',
|
||||||
|
@ -9,7 +10,7 @@ function BuildImageController($scope, $async, $window, ModalService, BuildServic
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.formValues = {
|
$scope.formValues = {
|
||||||
ImageNames: [{ Name: '' }],
|
ImageNames: [{ Name: '', Valid: false, Unique: true }],
|
||||||
UploadFile: null,
|
UploadFile: null,
|
||||||
DockerFileContent: '',
|
DockerFileContent: '',
|
||||||
URL: '',
|
URL: '',
|
||||||
|
@ -27,19 +28,38 @@ function BuildImageController($scope, $async, $window, ModalService, BuildServic
|
||||||
$scope.state.isEditorDirty = false;
|
$scope.state.isEditorDirty = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.checkName = function (name) {
|
$scope.checkName = function (index) {
|
||||||
const parts = name.split('/');
|
var item = $scope.formValues.ImageNames[index];
|
||||||
|
item.Valid = true;
|
||||||
|
item.Unique = true;
|
||||||
|
if (item.Name !== '') {
|
||||||
|
// Check unique
|
||||||
|
$scope.formValues.ImageNames.forEach((element, idx) => {
|
||||||
|
if (idx != index && element.Name == item.Name) {
|
||||||
|
item.Valid = false;
|
||||||
|
item.Unique = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!item.Valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Validation
|
||||||
|
const parts = item.Name.split('/');
|
||||||
const repository = parts[parts.length - 1];
|
const repository = parts[parts.length - 1];
|
||||||
const repositoryRegExp = RegExp('^[a-z0-9-_]{2,255}(:[A-Za-z0-9-_.]{1,128})?$');
|
const repositoryRegExp = RegExp('^[a-z0-9-_]{2,255}(:[A-Za-z0-9-_.]{1,128})?$');
|
||||||
return repositoryRegExp.test(repository);
|
item.Valid = repositoryRegExp.test(repository);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.addImageName = function () {
|
$scope.addImageName = function () {
|
||||||
$scope.formValues.ImageNames.push({ Name: '' });
|
$scope.formValues.ImageNames.push({ Name: '', Valid: false, Unique: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.removeImageName = function (index) {
|
$scope.removeImageName = function (index) {
|
||||||
$scope.formValues.ImageNames.splice(index, 1);
|
$scope.formValues.ImageNames.splice(index, 1);
|
||||||
|
for (var i = 0; i < $scope.formValues.ImageNames.length; i++) {
|
||||||
|
$scope.checkName(i);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function buildImageBasedOnBuildType(method, names) {
|
function buildImageBasedOnBuildType(method, names) {
|
||||||
|
@ -103,8 +123,7 @@ function BuildImageController($scope, $async, $window, ModalService, BuildServic
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (var i = 0; i < $scope.formValues.ImageNames.length; i++) {
|
for (var i = 0; i < $scope.formValues.ImageNames.length; i++) {
|
||||||
var item = $scope.formValues.ImageNames[i];
|
if (!$scope.formValues.ImageNames[i].Valid) {
|
||||||
if (!$scope.checkName(item.Name)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,26 +40,33 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="col-sm-12 form-inline" class="mt-2.5">
|
<div class="col-sm-12 form-inline" class="mt-2.5">
|
||||||
<div ng-repeat="item in formValues.ImageNames track by $index" class="mt-0.5">
|
<div ng-repeat="item in formValues.ImageNames track by $index" class="mt-1">
|
||||||
<!-- name-input -->
|
<!-- name-input -->
|
||||||
<div class="input-group col-sm-5 input-group-sm">
|
<div class="input-group col-sm-5 input-group-sm">
|
||||||
<span class="input-group-addon">name</span>
|
<span class="input-group-addon">name</span>
|
||||||
<input type="text" class="form-control" ng-model="item.Name" placeholder="e.g. my-image:my-tag" auto-focus />
|
<input type="text" class="form-control" ng-model="item.Name" ng-change="checkName($index)" placeholder="e.g. my-image:my-tag" auto-focus />
|
||||||
<span class="input-group-addon" ng-if="!checkName(item.Name)">
|
<span class="input-group-addon" ng-if="!item.Valid">
|
||||||
<pr-icon icon="'x'" mode="'danger'" feather="true"></pr-icon>
|
<pr-icon icon="'x'" mode="'danger'" feather="true"></pr-icon>
|
||||||
</span>
|
</span>
|
||||||
<span class="input-group-addon" ng-if="checkName(item.Name)">
|
<span class="input-group-addon" ng-if="item.Valid">
|
||||||
<pr-icon icon="'check'" mode="'success'" feather="true"></pr-icon>
|
<pr-icon icon="'check'" mode="'success'" feather="true"></pr-icon>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- !name-input -->
|
<!-- !name-input -->
|
||||||
<!-- actions -->
|
<!-- actions -->
|
||||||
<div class="input-group col-sm-2 input-group-sm">
|
<div class="input-group col-sm-2 input-group-sm">
|
||||||
<button class="btn btn-sm btn-danger" type="button" ng-click="removeImageName($index)">
|
<button class="btn btn-dangerlight btn-only-icon" type="button" ng-click="removeImageName($index)">
|
||||||
<pr-icon icon="'trash-2'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
|
<pr-icon icon="'trash-2'" feather="true"></pr-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<!-- !actions -->
|
<!-- !actions -->
|
||||||
|
<div class="small text-warning" ng-if="!item.Valid">
|
||||||
|
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||||
|
<span ng-if="!item.Unique">The image name must be unique</span>
|
||||||
|
<span ng-if="item.Unique"
|
||||||
|
>The image name must consist of between 2 and 255 lowercase alphanumeric characters, '_' or '-' (e.g. 'my-name', or 'abc-123').</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -204,7 +211,8 @@
|
||||||
ng-disabled="state.actionInProgress
|
ng-disabled="state.actionInProgress
|
||||||
|| (state.BuildType === 'upload' && (!formValues.UploadFile || !formValues.Path))
|
|| (state.BuildType === 'upload' && (!formValues.UploadFile || !formValues.Path))
|
||||||
|| (state.BuildType === 'url' && (!formValues.URL || !formValues.Path))
|
|| (state.BuildType === 'url' && (!formValues.URL || !formValues.Path))
|
||||||
|| (formValues.ImageNames.length === 0 || !validImageNames())"
|
|| (formValues.ImageNames.length === 0 || !validImageNames())
|
||||||
|
|| (formValues.DockerFileContent === '')"
|
||||||
ng-click="buildImage()"
|
ng-click="buildImage()"
|
||||||
button-spinner="state.actionInProgress"
|
button-spinner="state.actionInProgress"
|
||||||
>
|
>
|
||||||
|
|
Loading…
Reference in New Issue