diff --git a/src/ImageRunModal.jsx b/src/ImageRunModal.jsx index d69559166..41b17d99c 100644 --- a/src/ImageRunModal.jsx +++ b/src/ImageRunModal.jsx @@ -2,6 +2,7 @@ import React from 'react'; import { Button } from "@patternfly/react-core/dist/esm/components/Button"; import { Checkbox } from "@patternfly/react-core/dist/esm/components/Checkbox"; import { Form, FormGroup } from "@patternfly/react-core/dist/esm/components/Form"; +import { FormHelper } from "cockpit-components-form-helper.jsx"; import { FormSelect, FormSelectOption } from "@patternfly/react-core/dist/esm/components/FormSelect"; import { Grid, GridItem } from "@patternfly/react-core/dist/esm/layouts/Grid"; import { Modal } from "@patternfly/react-core/dist/esm/components/Modal"; @@ -261,7 +262,7 @@ export class ImageRunModal extends React.Component { }; async onCreateClicked(runImage = false) { - if (!this.validateForm()) + if (!await this.validateForm()) return; const Dialogs = this.context; @@ -593,8 +594,17 @@ export class ImageRunModal extends React.Component { return Object.keys(validationFailed).length == 0; }; - validateForm = () => { - const { publish, volumes, env } = this.state; + async validateContainerName(containerName) { + try { + await client.containerExists(this.isSystem(), containerName); + } catch (error) { + return; + } + return _("Name already in use"); + } + + async validateForm() { + const { publish, volumes, env, containerName } = this.state; const validationFailed = { }; const publishValidation = publish.map(a => { @@ -628,10 +638,12 @@ export class ImageRunModal extends React.Component { if (Object.keys(envValidation).length > 0) validationFailed.env = envValidation; + validationFailed.containerName = await this.validateContainerName(containerName); + this.setState({ validationFailed }); return this.isFormValid(validationFailed); - }; + } render() { const Dialogs = this.context; @@ -691,8 +703,16 @@ export class ImageRunModal extends React.Component { utils.validationClear(dialogValues.validationFailed, "containerName", (value) => this.onValueChanged("validationFailed", value))} + onBlur={async () => { + const delta = await this.validateContainerName(dialogValues.containerName); + if (delta) + this.onValueChanged("validationFailed", { ...dialogValues.validationFailed, containerName: delta }); + }} value={dialogValues.containerName} onChange={(_, value) => this.onValueChanged('containerName', value)} /> + {_("Details")}} className="pf-v5-c-form pf-m-horizontal"> diff --git a/src/client.js b/src/client.js index 572056243..41df29d27 100644 --- a/src/client.js +++ b/src/client.js @@ -179,3 +179,5 @@ export const pruneUnusedImages = system => podmanJson("libpod/images/prune?all=t export const imageHistory = (system, id) => podmanJson(`libpod/images/${id}/history`, "GET", {}, system); export const imageExists = (system, id) => podmanCall("libpod/images/" + id + "/exists", "GET", {}, system); + +export const containerExists = (system, id) => podmanCall("libpod/containers/" + id + "/exists", "GET", {}, system);