From 707045071ad7987e740038646cd5a6592f4a0b7d Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 18 Feb 2021 14:53:32 +0200 Subject: [PATCH] added support for custom docker images --- content/pages/publishAlgo.json | 23 +++++++++++- src/@types/MetaData.d.ts | 3 ++ .../molecules/MetadataPreview.module.css | 2 +- .../pages/Publish/FormAlgoPublish.tsx | 36 +++++++++++++++++-- src/models/FormAlgoPublish.ts | 10 +++++- src/utils/metadata.ts | 34 +++++++++++++----- 6 files changed, 95 insertions(+), 13 deletions(-) diff --git a/content/pages/publishAlgo.json b/content/pages/publishAlgo.json index 28cb46dce..544182b9a 100644 --- a/content/pages/publishAlgo.json +++ b/content/pages/publishAlgo.json @@ -33,9 +33,30 @@ "placeholder": "e.g. python3.7", "help": "Please select a predefined image to run your algorithm.", "type": "select", - "options": ["NodeJS", "Python 3.7"], + "options": ["node:pre-defined", "python:pre-defined", "custom image"], "required": true }, + { + "name": "image", + "label": "Image URL", + "placeholder": "e.g. node or https://hub.docker.com/_/node ", + "help": "Provide the name of a docker image or the full url if you have it hosted in a 3rd party repo", + "required": false + }, + { + "name": "version", + "label": "Version", + "placeholder": "e.g. 10", + "help": "Provide the version for your image.", + "required": false + }, + { + "name": "entrypoint", + "label": "Entrypoint", + "placeholder": "e.g. python $ALGO", + "help": "Provide the entrypoint for your algorithm.", + "required": false + }, { "name": "algorithmPrivacy", "label": "Algorithm Privacy", diff --git a/src/@types/MetaData.d.ts b/src/@types/MetaData.d.ts index 9ae93bfca..76c3ca8fb 100644 --- a/src/@types/MetaData.d.ts +++ b/src/@types/MetaData.d.ts @@ -49,6 +49,9 @@ export interface AlgorithmPublishForm { algorithmPrivacy: boolean termsAndConditions: boolean // ---- optional fields ---- + image: string + version: string + entrypoint: string tags?: string } diff --git a/src/components/molecules/MetadataPreview.module.css b/src/components/molecules/MetadataPreview.module.css index 70cf4f43a..e1a14e9b6 100644 --- a/src/components/molecules/MetadataPreview.module.css +++ b/src/components/molecules/MetadataPreview.module.css @@ -17,7 +17,7 @@ display: grid; gap: var(--spacer); grid-template-columns: 1fr 1fr; - margin-bottom: var(--spacer/2); + margin-bottom: var(--spacer); } .previewTitle { diff --git a/src/components/pages/Publish/FormAlgoPublish.tsx b/src/components/pages/Publish/FormAlgoPublish.tsx index b7fb4c940..6ad2c240d 100644 --- a/src/components/pages/Publish/FormAlgoPublish.tsx +++ b/src/components/pages/Publish/FormAlgoPublish.tsx @@ -33,16 +33,48 @@ export default function FormPublish({ // setSubmitting(false) }, [setErrors, setTouched]) + function handleImageSelectChange(imageSelected: string) { + switch (imageSelected) { + case 'node:pre-defined': { + setFieldValue('dockerImage', imageSelected) + setFieldValue('image', 'node') + setFieldValue('version', '10') + setFieldValue('entrypoint', 'node $ALGO') + break + } + case 'python:pre-defined': { + setFieldValue('dockerImage', imageSelected) + setFieldValue('image', 'oceanprotocol/algo_dockers') + setFieldValue('version', 'python-panda') + setFieldValue('entrypoint', 'python $ALGO') + break + } + default: { + setFieldValue('dockerImage', imageSelected) + setFieldValue('image', '') + setFieldValue('version', '') + setFieldValue('entrypoint', '') + break + } + } + } + // Manually handle change events instead of using `handleChange` from Formik. // Workaround for default `validateOnChange` not kicking in function handleFieldChange( e: ChangeEvent, field: FormFieldProps ) { + console.log(field) const value = field.type === 'checkbox' ? !JSON.parse(e.target.value) : e.target.value - validateField(field.name) - setFieldValue(field.name, value) + if (field.name === 'dockerImage') { + validateField(field.name) + handleImageSelectChange(e.target.value) + } else { + validateField(field.name) + setFieldValue(field.name, value) + } } const resetFormAndClearStorage = (e: FormEvent) => { diff --git a/src/models/FormAlgoPublish.ts b/src/models/FormAlgoPublish.ts index 9d9acf368..826721026 100644 --- a/src/models/FormAlgoPublish.ts +++ b/src/models/FormAlgoPublish.ts @@ -11,8 +11,13 @@ export const validationSchema: Yup.SchemaOf = Yup.object() description: Yup.string().min(10).required('Required'), files: Yup.array().required('Required').nullable(), dockerImage: Yup.string() - .matches(/NodeJS|Python 3.7/g, { excludeEmptyString: true }) + .matches(/node:pre-defined|python:pre-defined|custom image/g, { + excludeEmptyString: true + }) .required('Required'), + image: Yup.string().required('Required'), + version: Yup.string().required('Required'), + entrypoint: Yup.string().required('Required'), author: Yup.string().required('Required'), termsAndConditions: Yup.boolean().required('Required'), // ---- optional fields ---- @@ -26,6 +31,9 @@ export const initialValues: Partial = { name: '', author: '', dockerImage: '', + image: '', + version: '', + entrypoint: '', files: '', description: '', algorithmPrivacy: false, diff --git a/src/utils/metadata.ts b/src/utils/metadata.ts index 58251e8a3..a1fa323ab 100644 --- a/src/utils/metadata.ts +++ b/src/utils/metadata.ts @@ -70,21 +70,29 @@ export function checkIfTimeoutInPredefinedValues( return false } -function getAlgoithComponent(selectedAlgorithm: string): MetadataAlgorithm { +function getAlgoithComponent( + image: string, + version: string, + entrypoint: string, + algorithmLanguace: string +): MetadataAlgorithm { return { - language: selectedAlgorithm === 'NodeJS' ? 'js' : 'py', + language: algorithmLanguace, format: 'docker-image', version: '0.1', container: { - entrypoint: - selectedAlgorithm === 'NodeJS' ? 'node $ALGO' : 'python $ALGO', - image: - selectedAlgorithm === 'NodeJS' ? 'node' : 'oceanprotocol/algo_dockers', - tag: selectedAlgorithm === 'NodeJS' ? '10' : 'python-panda' + entrypoint: entrypoint, + image: image, + tag: version } } } +function getAlgoithFileExtension(fileUrl: string): string { + const splitedFileUrl = fileUrl.split('.') + return splitedFileUrl[splitedFileUrl.length - 1] +} + export function transformPublishFormToMetadata( { name, @@ -127,13 +135,23 @@ export function transformPublishAlgorithmFormToMetadata( description, tags, dockerImage, + image, + version, + entrypoint, termsAndConditions, files }: Partial, ddo?: DDO ): MetadataMarket { const currentTime = toStringNoMS(new Date()) - const algorithm = getAlgoithComponent(dockerImage) + const fileUrl = typeof files !== 'string' && files[0].url + const algorithmLanguace = getAlgoithFileExtension(fileUrl) + const algorithm = getAlgoithComponent( + image, + version, + entrypoint, + algorithmLanguace + ) const metadata: MetadataMarket = { main: { ...AssetModel.main,