diff --git a/src/@utils/docker.ts b/src/@utils/docker.ts index a94dd0a6b..cf514f746 100644 --- a/src/@utils/docker.ts +++ b/src/@utils/docker.ts @@ -1,11 +1,21 @@ import { LoggerInstance } from '@oceanprotocol/lib' import axios from 'axios' +import isUrl from 'is-url-superb' import { toast } from 'react-toastify' -export async function getContainerChecksum( +export interface dockerContainerInfo { + exists: boolean + checksum: string +} + +async function getDockerHubImageChecksum( image: string, tag: string -): Promise { +): Promise { + const containerInfo: dockerContainerInfo = { + exists: false, + checksum: null + } try { const response = await axios.post( `https://dockerhub-proxy.oceanprotocol.com`, @@ -20,16 +30,54 @@ export async function getContainerChecksum( response.data.status !== 'success' ) { toast.error( - 'Could not fetch docker hub image info. Please input the container checksum manually' + 'Could not fetch docker hub image info. Please check container image and tag and try again' ) - return null + return containerInfo } - return response.data.result.checksum + containerInfo.exists = true + containerInfo.checksum = response.data.result.checksum + return containerInfo } catch (error) { LoggerInstance.error(error.message) toast.error( - 'Could not fetch docker hub image info. Please input the container checksum manually' + 'Could not fetch docker hub image info. Please check container image and tag and try again' ) - return null + return containerInfo } } + +async function validateContainerImageUrl( + imageURL: string +): Promise { + const containerInfo: dockerContainerInfo = { + exists: false, + checksum: null + } + try { + const response = await axios.head(imageURL) + if (!response || response.status !== 200) { + toast.error( + 'Could not fetch docker image info. Please check URL and try again' + ) + return containerInfo + } + containerInfo.exists = true + return containerInfo + } catch (error) { + LoggerInstance.error(error.message) + toast.error( + 'Could not fetch docker image info. Please check URL and try again' + ) + return containerInfo + } +} + +export async function getContainerChecksum( + dockerImage: string, + tag: string +): Promise { + const isValid = isUrl(dockerImage) + ? await validateContainerImageUrl(dockerImage) + : await getDockerHubImageChecksum(dockerImage, tag) + return isValid +} diff --git a/src/components/@shared/FormFields/ContainerInput/index.tsx b/src/components/@shared/FormFields/ContainerInput/index.tsx index 379d66cc3..5c93e1056 100644 --- a/src/components/@shared/FormFields/ContainerInput/index.tsx +++ b/src/components/@shared/FormFields/ContainerInput/index.tsx @@ -26,16 +26,21 @@ export default function ContainerInput(props: InputProps): ReactElement { const parsedContainerValue = container?.split(':') const imageNname = parsedContainerValue?.slice(0, -1).join(':') const tag = - parsedContainerValue.length > 1 ? parsedContainerValue?.at(-1) : '' - setFieldValue('metadata.dockerImageCustom', imageNname) - setFieldValue('metadata.dockerImageCustomTag', tag) - const checksum = await getContainerChecksum(imageNname, tag) - if (checksum) { - setFieldValue('metadata.dockerImageCustomChecksum', checksum) - helpersChecksum.setTouched(false) - setIsValid(true) + parsedContainerValue?.length > 1 ? parsedContainerValue?.at(-1) : '' + const containerInfo = await getContainerChecksum(imageNname, tag) + if (containerInfo.exists) { + setFieldValue('metadata.dockerImageCustom', imageNname) + setFieldValue('metadata.dockerImageCustomTag', tag) + setChecked(true) + if (containerInfo.checksum) { + setFieldValue( + 'metadata.dockerImageCustomChecksum', + containerInfo.checksum + ) + helpersChecksum.setTouched(false) + setIsValid(true) + } } - setChecked(true) } catch (error) { setFieldError(`${field.name}[0].url`, error.message) LoggerInstance.error(error.message) diff --git a/src/components/Publish/_utils.ts b/src/components/Publish/_utils.ts index cca072b60..77c53b0fc 100644 --- a/src/components/Publish/_utils.ts +++ b/src/components/Publish/_utils.ts @@ -41,7 +41,9 @@ async function getAlgorithmContainerPreset( const preset = algorithmContainerPresets.find( (preset) => `${preset.image}:${preset.tag}` === dockerImage ) - preset.checksum = await getContainerChecksum(preset.image, preset.tag) + preset.checksum = await ( + await getContainerChecksum(preset.image, preset.tag) + ).checksum return preset }