[release] v0.7.0-unstable

This commit is contained in:
Yann Stepienik 2023-06-08 20:55:16 +01:00
parent 6c170e5145
commit e69c81fe7a
4 changed files with 142 additions and 22 deletions

View file

@ -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 <>
<Dialog open={openModal} onClose={() => setOpenModal(false)}>
<DialogTitle>Import Docker Compose</DialogTitle>
<DialogContent>
<Dialog open={openModal} onClose={() => setOpenModal(false)} >
<DialogTitle>{installer ? "Installation" : "Import Compose File"}</DialogTitle>
<DialogContent style={{width: '800px', maxWidth: '100%'}}>
<DialogContentText>
{step === 0 && <Stack spacing={2}>
{step === 0 && !installer && <><Stack spacing={2}>
<Alert severity="warning" icon={<WarningOutlined />}>
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!
</Alert>
<UploadButtons
accept='.yml,.yaml'
accept='.yml,.yaml,.json'
OnChange={(e) => {
const file = e.target.files[0];
const reader = new FileReader();
@ -261,7 +339,7 @@ const DockerComposeImport = ({ refresh }) => {
<TextField
multiline
placeholder='Paste your docker-compose.yml here or use the file upload button.'
placeholder='Paste your docker-compose.yml / cosmos-compose.json here or use the file upload button.'
fullWidth
value={dockerCompose}
onChange={(e) => setDockerCompose(e.target.value)}
@ -272,7 +350,29 @@ const DockerComposeImport = ({ refresh }) => {
}
}}
rows={20}></TextField>
</Stack>}
</Stack></>}
{step === 0 && installer && <><Stack spacing={2}>
<div style={{ color: 'red' }}>
{ymlError}
</div>
{!ymlError && (<><FormLabel>Choose your service name</FormLabel>
<TextField label="Service Name" value={serviceName} onChange={(e) => setServiceName(e.target.value)} />
{hostnames.map((hostname, index) => {
return <>
<FormLabel>Choose URL for {hostname.name}</FormLabel>
<div style={{ opacity: 0.9, fontSize: '0.8em', textDecoration: 'italic'}}
>{hostname.description}</div>
<TextField key={index} label="Hostname" value={hostname.host} onChange={(e) => {
const newHostnames = [...hostnames];
newHostnames[index].host = e.target.value;
setHostnames(newHostnames);
}} />
</>
})}
</>)}
</Stack></>}
{step === 1 && <Stack spacing={2}>
<NewDockerService service={service} refresh={refresh} />
</Stack>}
@ -284,8 +384,8 @@ const DockerComposeImport = ({ refresh }) => {
setStep(0);
setDockerCompose('');
setYmlError('');
}}>Close</Button>
<Button onClick={() => {
}}>Cancel</Button>
<Button disabled={!dockerCompose || ymlError} onClick={() => {
if (step === 0) {
setStep(1);
} else {
@ -301,10 +401,10 @@ const DockerComposeImport = ({ refresh }) => {
<ResponsiveButton
color="primary"
onClick={() => setOpenModal(true)}
variant="outlined"
startIcon={<ArrowUpOutlined />}
variant={(installer ? "contained" : "outlined")}
startIcon={(installer ? <ArrowDownOutlined /> : <ArrowUpOutlined />)}
>
Import Docker Compose
{installer ? 'Install' : 'Import Compose File'}
</ResponsiveButton>
</>;
};

View file

@ -91,6 +91,7 @@ const NewDockerService = ({service, refresh}) => {
variant="contained"
color="primary"
fullWidth
className='shinyButton'
loading={log.length && !isDone}
startIcon={<PlusCircleOutlined />}
>Create</LoadingButton>}
@ -110,7 +111,11 @@ const NewDockerService = ({service, refresh}) => {
}
</Stack>}
<pre style={preStyle} ref={preRef}>
{!log.length && JSON.stringify(service, false ,2)}
{!log.length && `
# You are about to create the following service(s):
${JSON.stringify(service, false ,2)}`
}
{log.map((l) => {
return <div>{tryParseProgressLog(l)}</div>
})}

View file

@ -1,6 +1,6 @@
{
"name": "cosmos-server",
"version": "0.6.4",
"version": "0.7.0-unstable",
"description": "",
"main": "test-server.js",
"bugs": {

View file

@ -379,6 +379,21 @@ func CreateService(serviceRequest DockerServiceCreateRequest, OnLog func(string)
Tty: container.Tty,
OpenStdin: container.StdinOpen,
}
// check if there's an empty TZ env, if so, replace it with the host's TZ
if containerConfig.Env != nil {
for i, env := range containerConfig.Env {
if strings.HasPrefix(env, "TZ=") {
if strings.TrimPrefix(env, "TZ=") == "" {
if os.Getenv("TZ") != "" {
containerConfig.Env[i] = "TZ=" + os.Getenv("TZ")
} else {
containerConfig.Env = append(containerConfig.Env[:i], containerConfig.Env[i+1:]...)
}
}
}
}
}
if container.Command != "" {
containerConfig.Cmd = strings.Fields(container.Command)