Skip to content

Commit

Permalink
GUI Issue #3733: Run confirmation modal - tool isAllowedWarning (#3740)…
Browse files Browse the repository at this point in the history
…, backported to stage/0.16/uat
  • Loading branch information
AleksandrGorodetskii authored and rodichenko committed Oct 17, 2024
1 parent 7cdaa26 commit de8cde3
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 96 deletions.
10 changes: 5 additions & 5 deletions client/src/components/main/home/panels/PersonalToolsPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import {
getLimitMountsParameterValue,
getLimitMountsStorages
} from '../../../../utils/limit-mounts/get-limit-mounts-storages';
import checkToolVersionSizeErrors from '../../../runs/utilities/check-tool-version-size-errors';
import checkToolVersionErrors from '../../../runs/utilities/check-tool-version-errors';

const findGroupByNameSelector = (name) => (group) => {
return group.name.toLowerCase() === name.toLowerCase();
Expand Down Expand Up @@ -577,7 +577,7 @@ export default class PersonalToolsPanel extends React.Component {
this.props.preferences,
tool.platform
);
const versionSizeErrors = await checkToolVersionSizeErrors(
const versionErrors = await checkToolVersionErrors(
this.state.runToolInfo.payload.dockerImage,
this.props.preferences,
this.props.dockerRegistries
Expand All @@ -587,7 +587,7 @@ export default class PersonalToolsPanel extends React.Component {
runToolInfo: {
...this.state.runToolInfo,
permissionErrors,
versionSizeErrors,
versionErrors,
payload: {
...this.state.runToolInfo.payload,
params
Expand Down Expand Up @@ -875,7 +875,7 @@ export default class PersonalToolsPanel extends React.Component {
this.state.runToolInfo.permissionErrors.length > 0
) ||
this.runCapabilitiesError ||
this.state.runToolInfo?.versionSizeErrors?.hard ||
this.state.runToolInfo?.versionErrors?.size?.hard ||
this.state.pending
}
onClick={this.runToolWithDefaultSettings}
Expand All @@ -894,7 +894,7 @@ export default class PersonalToolsPanel extends React.Component {
{
this.state.runToolInfo &&
<RunConfirmation
versionSizeErrors={this.state.runToolInfo.versionSizeErrors}
versionErrors={this.state.runToolInfo.versionErrors}
cloudRegions={
this.props.awsRegions.loaded
? (this.props.awsRegions.value || []).map(r => r)
Expand Down
42 changes: 29 additions & 13 deletions client/src/components/runs/actions/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import {
storageMatchesIdentifiers
} from '../../../utils/limit-mounts/get-limit-mounts-storages';
import RunModal from '../../main/RunModal';
import checkToolVersionSizeErrors from '../utilities/check-tool-version-size-errors';
import checkToolVersionErrors from '../utilities/check-tool-version-errors';

// Mark class with @submitsRun if it may launch pipelines / tools
export const submitsRun = (...opts) => {
Expand Down Expand Up @@ -424,7 +424,7 @@ function runFn (
component = element;
};
const hide = message.loading('Checking tool size...', 0);
const sizeErrors = await checkToolVersionSizeErrors(
const versionErrors = await checkToolVersionErrors(
payload.dockerImage,
stores.preferences,
stores.dockerRegistries
Expand All @@ -433,7 +433,7 @@ function runFn (
RunModal.open({
title: null,
width: '50%',
okDisabled: sizeErrors.hard,
okDisabled: versionErrors.size.hard,
content: (
<RunSpotConfirmationWithPrice
runInfo={{
Expand All @@ -445,7 +445,7 @@ function runFn (
}}
ref={ref}
warning={warning}
versionSizeErrors={sizeErrors}
versionErrors={versionErrors}
instanceType={payload.instanceType}
hddSize={payload.hddSize}
isSpot={payload.isSpot}
Expand Down Expand Up @@ -582,10 +582,14 @@ export class RunConfirmation extends React.Component {

static propTypes = {
warning: PropTypes.string,
versionSizeErrors: PropTypes.shape({
soft: PropTypes.bool,
hard: PropTypes.bool
versionErrors: PropTypes.shape({
size: PropTypes.shape({
soft: PropTypes.bool,
hard: PropTypes.bool
}),
allowedWarning: PropTypes.string
}),
allowedWarning: PropTypes.string,
isSpot: PropTypes.bool,
cloudRegionId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
cloudRegions: PropTypes.array,
Expand Down Expand Up @@ -869,10 +873,19 @@ export class RunConfirmation extends React.Component {
};

render () {
const {versionSizeErrors} = this.props;
const {soft, hard} = versionSizeErrors || {};
const {size, allowedWarning} = this.props.versionErrors || {};
const {soft, hard} = size || {};
return (
<div>
{allowedWarning ? (
<Alert
style={{marginBottom: 4}}
key="allowed-warning"
type="warning"
showIcon
message={allowedWarning}
/>
) : null}
{!hard && soft ? (
<Alert
style={{marginBottom: 4}}
Expand Down Expand Up @@ -1244,9 +1257,12 @@ export class RunConfirmation extends React.Component {
@observer
class RunSpotConfirmationWithPrice extends React.Component {
static propTypes = {
versionSizeErrors: PropTypes.shape({
soft: PropTypes.bool,
hard: PropTypes.bool
versionErrors: PropTypes.shape({
size: PropTypes.shape({
soft: PropTypes.bool,
hard: PropTypes.bool
}),
allowedWarning: PropTypes.string
}),
warning: PropTypes.string,
isSpot: PropTypes.bool,
Expand Down Expand Up @@ -1417,7 +1433,7 @@ class RunSpotConfirmationWithPrice extends React.Component {
<Row>
<RunConfirmation
warning={this.props.warning}
versionSizeErrors={this.props.versionSizeErrors}
versionErrors={this.props.versionErrors}
onChangePriceType={this.onChangeSpotType}
isSpot={this.props.isSpot}
isCluster={this.props.isCluster}
Expand Down
136 changes: 136 additions & 0 deletions client/src/components/runs/utilities/check-tool-version-errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* Copyright 2017-2024 EPAM Systems, Inc. (https://www.epam.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import LoadToolInfo from '../../../models/tools/LoadToolInfo';
import LoadToolVersionSettings from '../../../models/tools/LoadToolVersionSettings';

function getTool (dockerImage, dockerRegistries) {
if (!dockerImage) {
return Promise.resolve(null);
} else {
return new Promise((resolve) => {
dockerRegistries.fetchIfNeededOrWait()
.then(() => {
const {registries = []} = dockerRegistries.value;
for (let r = 0; r < registries.length; r++) {
const {groups = []} = registries[r];
for (let g = 0; g < groups.length; g++) {
const {tools = []} = groups[g];
for (let t = 0; t < tools.length; t++) {
const image = `${registries[r].path}/${tools[t].image}`.toLowerCase();
if (dockerImage.toLowerCase() === image) {
resolve(tools[t]);
return;
}
}
}
}
resolve(null);
})
.catch(() => resolve(null));
});
}
};

async function getToolVersion (tool, version) {
const toolInfo = new LoadToolInfo(tool.id);
await toolInfo.fetch();
const {versions = []} = toolInfo?.value || {};
return versions.find(v => v.version === version);
}

async function getToolVersionSettings (tool, version) {
const toolSettings = new LoadToolVersionSettings(tool.id);
await toolSettings.fetch();
return (toolSettings.value || []).find(v => v.version === version);
};

function getToolSizeErrors (versionSettings, preferences) {
if (versionSettings) {
const {size} = versionSettings;
const {soft = 0, hard = 0} = preferences.launchToolSizeLimits || {};
return {
soft: soft ? size > soft : false,
hard: hard ? size > hard : false
};
}
}

function getToolAllowedWarning (currentVersion, preferences) {
if (!currentVersion?.scanResult?.toolOSVersion) {
return;
}
const replacePlaceholders = (string = '') => {
let result = string;
const {distribution, version} = currentVersion.scanResult.toolOSVersion;
if (/{os}/i.test(result)) {
result = result.replace(/{os}/ig, `${distribution} ${version}`);
}
if (/{distribution}/i.test(result)) {
result = result.replace(/{distribution}/ig, `${distribution}`);
}
if (/{version}/i.test(result)) {
result = result.replace(/{version}/ig, `${version}`);
}
return result;
};
const {isAllowedWarning} = currentVersion.scanResult.toolOSVersion;
return isAllowedWarning && !!preferences.toolOSWarningText
? replacePlaceholders(preferences.toolOSWarningText)
: undefined;
}

export default async function checkToolVersionErrors (
docker = '',
preferences,
dockerRegistries
) {
let warnings = {
size: {
soft: undefined,
hard: undefined
},
allowedWarning: undefined
};
if (!docker) {
return warnings;
}
const [r, g, iv] = docker.split('/');
const [i, version] = iv.split(':');
const dockerImage = [r, g, i].join('/');
const tool = await getTool(dockerImage, dockerRegistries);
if (!tool) {
return warnings;
}
await Promise.all([
preferences?.fetchIfNeededOrWait(),
dockerRegistries?.fetchIfNeededOrWait()
]);
const [currentVersion, versionSettings] = await Promise.all([
getToolVersion(tool, version),
getToolVersionSettings(tool, version)
]);
const allowedWarning = getToolAllowedWarning(currentVersion, preferences);
const size = getToolSizeErrors(versionSettings, preferences);
if (allowedWarning || size) {
warnings = {
...warnings,
...(size ? {size} : {}),
...(allowedWarning ? {allowedWarning} : {})
};
}
return warnings;
};

This file was deleted.

4 changes: 4 additions & 0 deletions client/src/models/preferences/PreferencesLoad.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ class PreferencesLoad extends Remote {
return [];
}

get toolOSWarningText () {
return this.getPreferenceValue('ui.tools.os.with.warning');
}

@computed
get allowCommitToOtherPersonalGroups () {
const value = this.getPreferenceValue('commit.allow.other.personal.group');
Expand Down

0 comments on commit de8cde3

Please sign in to comment.