From e69c81fe7a5f6394fc1614443f2663d0d3a83ea7 Mon Sep 17 00:00:00 2001 From: Yann Stepienik Date: Thu, 8 Jun 2023 20:55:16 +0100 Subject: [PATCH] [release] v0.7.0-unstable --- .../servapps/containers/docker-compose.jsx | 140 +++++++++++++++--- .../pages/servapps/containers/newService.jsx | 7 +- package.json | 2 +- src/docker/api_blueprint.go | 15 ++ 4 files changed, 142 insertions(+), 22 deletions(-) diff --git a/client/src/pages/servapps/containers/docker-compose.jsx b/client/src/pages/servapps/containers/docker-compose.jsx index 29c50a3..e9965c5 100644 --- a/client/src/pages/servapps/containers/docker-compose.jsx +++ b/client/src/pages/servapps/containers/docker-compose.jsx @@ -1,7 +1,7 @@ // material-ui import * as React from 'react'; -import { Alert, Button, Stack, Typography } from '@mui/material'; -import { WarningOutlined, PlusCircleOutlined, CopyOutlined, ExclamationCircleOutlined, SyncOutlined, UserOutlined, KeyOutlined, ArrowUpOutlined, FileZipOutlined } from '@ant-design/icons'; +import { Alert, Button, FormLabel, Stack, Typography } from '@mui/material'; +import { WarningOutlined, PlusCircleOutlined, CopyOutlined, ExclamationCircleOutlined, SyncOutlined, UserOutlined, KeyOutlined, ArrowUpOutlined, FileZipOutlined, ArrowDownOutlined } from '@ant-design/icons'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; @@ -63,20 +63,68 @@ const preStyle = { marginRight: '0', } -const DockerComposeImport = ({ refresh }) => { +const getHostnameFromName = (name) => { + return name.replace('/', '').replace(/_/g, '-').replace(/[^a-zA-Z0-9-]/g, '').toLowerCase().replace(/\s/g, '-') + '.' + window.location.origin.split('://')[1] +} + +const DockerComposeImport = ({ refresh, dockerComposeInit, installer, defaultName }) => { const [step, setStep] = useState(0); const [isLoading, setIsLoading] = useState(false); const [openModal, setOpenModal] = useState(false); - const [dockerCompose, setDockerCompose] = useState(''); + const [dockerCompose, setDockerCompose] = useState(dockerComposeInit || ''); const [service, setService] = useState({}); const [ymlError, setYmlError] = useState(''); + const [serviceName, setServiceName] = useState(defaultName || 'my-service'); + const [hostnames, setHostnames] = useState([]); useEffect(() => { + if(!openModal) { + return; + } + setYmlError(''); if (dockerCompose === '') { return; } - setYmlError(''); + let isJson = dockerCompose.trim().startsWith('{') && dockerCompose.trim().endsWith('}'); + + // if Json + if (isJson) { + try { + let doc = JSON.parse(dockerCompose); + + if(installer) { + doc = JSON.parse(dockerCompose.replace(/\{\{self\}\}/gi, serviceName)); + + // check hostnames for each service + let hostnames = []; + + if(doc.services) + Object.keys(doc.services).forEach((key) => { + if (doc.services[key].routes) { + let routeId = 0; + doc.services[key].routes.forEach((route) => { + if (route.useHost) { + let newRoute = Object.assign({}, route); + if(route.useHost === true) { + newRoute.host = getHostnameFromName(key + (routeId > 0 ? '-' + routeId : '')) + } + hostnames.push(newRoute); + } + }); + } + }); + + setHostnames(hostnames); + } + + setService(doc); + } catch (e) { + setYmlError(e.message); + } + } + else { + // if Yml let doc; let newService = {}; try { @@ -89,7 +137,6 @@ const DockerComposeImport = ({ refresh }) => { } } - // convert to the proper format if (doc.services) { Object.keys(doc.services).forEach((key) => { @@ -231,20 +278,51 @@ const DockerComposeImport = ({ refresh }) => { } setService(doc); - }, [dockerCompose]); + } + }, [openModal, dockerCompose]); + + useEffect(() => { + if(!openModal) { + return; + } + + try { + if (installer) { + let doc = JSON.parse(dockerCompose.replace(/\{\{self\}\}/gi, serviceName)); + + if(doc.services) + Object.keys(doc.services).forEach((key) => { + if (doc.services[key].routes) { + doc.services[key].routes.forEach((route, index) => { + doc.services[key].routes[index] = { + ...hostnames[index], + name: route.name, + description: route.description, + }; + }); + } + }); + + setService(doc); + } + } catch (e) { + setYmlError(e.message); + return; + } + }, [openModal, installer, serviceName, hostnames]); return <> - setOpenModal(false)}> - Import Docker Compose - + setOpenModal(false)} > + {installer ? "Installation" : "Import Compose File"} + - {step === 0 && + {step === 0 && !installer && <> }> - This is an experimental feature. It is recommended to use with caution. Please report any issue you find! + This is an experimental feature. It is recommended to use with caution. Please report any issue you find! { const file = e.target.files[0]; const reader = new FileReader(); @@ -261,7 +339,7 @@ const DockerComposeImport = ({ refresh }) => { setDockerCompose(e.target.value)} @@ -272,7 +350,29 @@ const DockerComposeImport = ({ refresh }) => { } }} rows={20}> - } + } + + {step === 0 && installer && <> +
+ {ymlError} +
+ {!ymlError && (<>Choose your service name + setServiceName(e.target.value)} /> + {hostnames.map((hostname, index) => { + return <> + Choose URL for {hostname.name} +
{hostname.description}
+ { + const newHostnames = [...hostnames]; + newHostnames[index].host = e.target.value; + setHostnames(newHostnames); + }} /> + + })} + )} +
} + {step === 1 && } @@ -284,8 +384,8 @@ const DockerComposeImport = ({ refresh }) => { setStep(0); setDockerCompose(''); setYmlError(''); - }}>Close - +