[release] v0.4.0-unstable6

This commit is contained in:
Yann Stepienik 2023-05-08 12:38:27 +01:00
parent 6a8e97b242
commit 08d7dbbe4e
14 changed files with 93 additions and 29 deletions

View file

@ -66,3 +66,7 @@
.darken { .darken {
filter: brightness(0.5); filter: brightness(0.5);
} }
.MuiAlert-icon {
align-items: center;
}

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { IconButton, Tooltip } from '@mui/material'; import { IconButton, Tooltip } from '@mui/material';
import { CloseSquareOutlined, DeleteOutlined, PauseCircleOutlined, PlaySquareOutlined, ReloadOutlined, RollbackOutlined, StopOutlined, UpCircleOutlined } from '@ant-design/icons'; import { CheckCircleOutlined, CloseSquareOutlined, DeleteOutlined, PauseCircleOutlined, PlaySquareOutlined, ReloadOutlined, RollbackOutlined, StopOutlined, UpCircleOutlined } from '@ant-design/icons';
import * as API from '../../api'; import * as API from '../../api';
const GetActions = ({ const GetActions = ({
@ -9,6 +9,8 @@ const GetActions = ({
refreshServeApps, refreshServeApps,
setIsUpdatingId setIsUpdatingId
}) => { }) => {
const [confirmDelete, setConfirmDelete] = React.useState(false);
const doTo = (action) => { const doTo = (action) => {
setIsUpdatingId(Id, true); setIsUpdatingId(Id, true);
API.docker.manageContainer(Id, action).then((res) => { API.docker.manageContainer(Id, action).then((res) => {
@ -76,8 +78,12 @@ const GetActions = ({
{ {
t: 'Delete', t: 'Delete',
if: ['exited', 'created'], if: ['exited', 'created'],
e: <IconButton onClick={() => {doTo('remove')}} color="error" size='large'> e: <IconButton onClick={() => {
<DeleteOutlined /> if(confirmDelete) doTo('remove')
else setConfirmDelete(true);
}} color="error" size='large'>
{confirmDelete ? <CheckCircleOutlined />
: <DeleteOutlined />}
</IconButton> </IconButton>
} }
]; ];

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Formik } from 'formik'; import { Formik } from 'formik';
import { Button, Stack, Grid, MenuItem, TextField, IconButton, FormHelperText, CircularProgress, useTheme } from '@mui/material'; import { Button, Stack, Grid, MenuItem, TextField, IconButton, FormHelperText, CircularProgress, useTheme, Alert } from '@mui/material';
import MainCard from '../../../components/MainCard'; import MainCard from '../../../components/MainCard';
import { CosmosCheckbox, CosmosFormDivider, CosmosInputText, CosmosSelect } import { CosmosCheckbox, CosmosFormDivider, CosmosInputText, CosmosSelect }
from '../../config/users/formShortcuts'; from '../../config/users/formShortcuts';
@ -12,13 +12,6 @@ import { NetworksColumns } from '../networks';
import NewNetworkButton from '../createNetwork'; import NewNetworkButton from '../createNetwork';
const NetworkContainerSetup = ({ config, containerInfo, refresh }) => { const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
const restartPolicies = [
['no', 'No Restart'],
['always', 'Always Restart'],
['on-failure', 'Restart On Failure'],
['unless-stopped', 'Restart Unless Stopped'],
];
const [networks, setNetworks] = React.useState([]); const [networks, setNetworks] = React.useState([]);
const theme = useTheme(); const theme = useTheme();
const isDark = theme.palette.mode === 'dark'; const isDark = theme.palette.mode === 'dark';
@ -40,13 +33,13 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
const connect = (network) => { const connect = (network) => {
setNetworks(null); setNetworks(null);
return API.docker.attachNetwork(containerInfo.Id, network).then(() => { return API.docker.attachNetwork(containerInfo.Name.replace('/', ''), network).then(() => {
refreshAll(); refreshAll();
}); });
} }
const disconnect = (network) => { const disconnect = (network) => {
return API.docker.detachNetwork(containerInfo.Id, network).then(() => { return API.docker.detachNetwork(containerInfo.Name.replace('/', ''), network).then(() => {
refreshAll(); refreshAll();
}); });
} }
@ -94,18 +87,20 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
.then((res) => { .then((res) => {
setStatus({ success: true }); setStatus({ success: true });
setSubmitting(false); setSubmitting(false);
refresh && refresh();
} }
).catch((err) => { ).catch((err) => {
setStatus({ success: false }); setStatus({ success: false });
setErrors({ submit: err.message }); setErrors({ submit: err.message });
setSubmitting(false); setSubmitting(false);
refresh && refresh();
}); });
}} }}
> >
{(formik) => ( {(formik) => (
<form noValidate onSubmit={formik.handleSubmit}> <form noValidate onSubmit={formik.handleSubmit}>
<Stack spacing={2}> <Stack spacing={2}>
<MainCard title={'Exposed Ports'}> <MainCard title={'Ports'}>
<Grid container spacing={4}> <Grid container spacing={4}>
<Grid item xs={12}> <Grid item xs={12}>
{formik.values.ports.map((port, idx) => ( {formik.values.ports.map((port, idx) => (
@ -209,7 +204,30 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
</Grid> </Grid>
</Grid> </Grid>
</MainCard> </MainCard>
<MainCard title={'Connected Networks'}> <MainCard title={'Networks'}>
<Stack spacing={2}>
{networks && <Stack spacing={2}>
{Object.keys(containerInfo.NetworkSettings.Networks).map((networkName) => {
const network = networks.find((n) => n.Name === networkName);
if (!network) {
return <Alert severity="error">
You are connected to a network that has been removed: <strong>{networkName}</strong>.
Either re-create it or
<Button
style={{ marginLeft: '10px' }}
variant="outlined"
color="primary"
onClick={() => {
disconnect(networkName);
}}
>
Disconnect It
</Button>
</Alert>
}
})}
</Stack>}
{networks && <PrettyTableView {networks && <PrettyTableView
data={networks} data={networks}
buttons={[ buttons={[
@ -252,6 +270,7 @@ const NetworkContainerSetup = ({ config, containerInfo, refresh }) => {
</center> </center>
</div> </div>
)} )}
</Stack>
</MainCard> </MainCard>
</Stack> </Stack>
</form> </form>

View file

@ -8,7 +8,7 @@ import { DeleteOutlined, PlusCircleOutlined } from '@ant-design/icons';
import * as API from '../../../api'; import * as API from '../../../api';
import { LoadingButton } from '@mui/lab'; import { LoadingButton } from '@mui/lab';
const DockerContainerSetup = ({config, containerInfo}) => { const DockerContainerSetup = ({config, containerInfo, refresh}) => {
const restartPolicies = [ const restartPolicies = [
['no', 'No Restart'], ['no', 'No Restart'],
['always', 'Always Restart'], ['always', 'Always Restart'],
@ -66,6 +66,7 @@ const DockerContainerSetup = ({config, containerInfo}) => {
.then((res) => { .then((res) => {
setStatus({ success: true }); setStatus({ success: true });
setSubmitting(false); setSubmitting(false);
refresh && refresh();
} }
).catch((err) => { ).catch((err) => {
setStatus({ success: false }); setStatus({ success: false });

View file

@ -24,16 +24,16 @@ const VolumeContainerSetup = ({ config, containerInfo, refresh }) => {
const isDark = theme.palette.mode === 'dark'; const isDark = theme.palette.mode === 'dark';
React.useEffect(() => { React.useEffect(() => {
API.docker.networkList().then((res) => { API.docker.volumeList().then((res) => {
setVolumes(res.data); setVolumes(res.data.Volumes);
}); });
}, []); }, []);
const refreshAll = () => { const refreshAll = () => {
setVolumes(null); setVolumes(null);
refresh().then(() => { refresh().then(() => {
API.docker.networkList().then((res) => { API.docker.volumeList().then((res) => {
setVolumes(res.data); setVolumes(res.data.Volumes);
}); });
}); });
}; };
@ -75,11 +75,13 @@ const VolumeContainerSetup = ({ config, containerInfo, refresh }) => {
.then((res) => { .then((res) => {
setStatus({ success: true }); setStatus({ success: true });
setSubmitting(false); setSubmitting(false);
refresh && refresh();
} }
).catch((err) => { ).catch((err) => {
setStatus({ success: false }); setStatus({ success: false });
setErrors({ submit: err.message }); setErrors({ submit: err.message });
setSubmitting(false); setSubmitting(false);
refresh && refresh();
}); });
}} }}
> >
@ -193,7 +195,6 @@ const VolumeContainerSetup = ({ config, containerInfo, refresh }) => {
{ {
title: '', title: '',
field: (r) => { field: (r) => {
console.log(r);
return (<Button return (<Button
variant="outlined" variant="outlined"
color="primary" color="primary"
@ -208,7 +209,7 @@ const VolumeContainerSetup = ({ config, containerInfo, refresh }) => {
} }
]} ]}
/>} />}
{!volumes && (<div style={{ height: '550px' }}> {!volumes && (<div style={{ height: '100px' }}>
<center> <center>
<br /> <br />
<CircularProgress /> <CircularProgress />

View file

@ -106,6 +106,9 @@ const NetworkManagementList = () => {
API.docker.networkDelete(r.Id).then(() => { API.docker.networkDelete(r.Id).then(() => {
refresh(); refresh();
setIsLoading(false); setIsLoading(false);
}).catch(() => {
setIsLoading(false);
refresh();
}); });
} else { } else {
setTryDelete(r.Id); setTryDelete(r.Id);

View file

@ -152,7 +152,7 @@ const ServeApps = () => {
<Grid2 container spacing={2}> <Grid2 container spacing={2}>
{serveApps && serveApps.filter(app => search.length < 2 || app.Names[0].toLowerCase().includes(search.toLowerCase())).map((app) => { {serveApps && serveApps.filter(app => search.length < 2 || app.Names[0].toLowerCase().includes(search.toLowerCase())).map((app) => {
return <Grid2 style={gridAnim} xs={12} sm={6} md={6} lg={6} xl={4}> return <Grid2 style={gridAnim} xs={12} sm={6} md={6} lg={6} xl={4} key={app.Id} item>
<Item> <Item>
<Stack justifyContent='space-around' direction="column" spacing={2} padding={2} divider={<Divider orientation="horizontal" flexItem />}> <Stack justifyContent='space-around' direction="column" spacing={2} padding={2} divider={<Divider orientation="horizontal" flexItem />}>
<Stack direction="column" spacing={0} alignItems="flex-start"> <Stack direction="column" spacing={0} alignItems="flex-start">

View file

@ -99,6 +99,9 @@ const VolumeManagementList = () => {
API.docker.volumeDelete(r.Name).then(() => { API.docker.volumeDelete(r.Name).then(() => {
refresh(); refresh();
setIsLoading(false); setIsLoading(false);
}).catch(() => {
setIsLoading(false);
refresh();
}); });
} else { } else {
setTryDelete(r.Name); setTryDelete(r.Name);

View file

@ -1,6 +1,6 @@
{ {
"name": "cosmos-server", "name": "cosmos-server",
"version": "0.4.0-unstable5", "version": "0.4.0-unstable6",
"description": "", "description": "",
"main": "test-server.js", "main": "test-server.js",
"bugs": { "bugs": {

View file

@ -25,11 +25,19 @@ func ManageContainerRoute(w http.ResponseWriter, req *http.Request) {
return return
} }
vars := mux.Vars(req) vars := mux.Vars(req)
containerName := utils.Sanitize(vars["containerId"]) containerName := utils.Sanitize(vars["containerId"])
// stop, start, restart, kill, remove, pause, unpause, recreate // stop, start, restart, kill, remove, pause, unpause, recreate
action := utils.Sanitize(vars["action"]) action := utils.Sanitize(vars["action"])
if os.Getenv("HOSTNAME") != "" && (action == "recreate" || action == "update") && containerName == os.Getenv("HOSTNAME") {
utils.Error("ManageContainer - cannot recreate/update self", nil)
utils.HTTPError(w, "Cannot recreate/update self", http.StatusBadRequest, "DS003")
return
}
utils.Log("ManageContainer " + containerName) utils.Log("ManageContainer " + containerName)
if req.Method == "GET" { if req.Method == "GET" {

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"net/http" "net/http"
"os"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/azukaar/cosmos-server/src/utils" "github.com/azukaar/cosmos-server/src/utils"
@ -157,6 +158,12 @@ func DetachNetwork(w http.ResponseWriter, req *http.Request) {
return return
} }
if os.Getenv("HOSTNAME") != "" && networkID == "bridge" && containerID == os.Getenv("HOSTNAME") {
utils.Error("DetachNetwork - Cannot disconnect self from bridge", nil)
utils.HTTPError(w, "Cannot disconnect self from bridge", http.StatusBadRequest, "DS003")
return
}
err := DockerClient.NetworkDisconnect(context.Background(), networkID, containerID, true) err := DockerClient.NetworkDisconnect(context.Background(), networkID, containerID, true)
if err != nil { if err != nil {
utils.Error("DetachNetwork: Error while detaching network", err) utils.Error("DetachNetwork: Error while detaching network", err)

View file

@ -3,6 +3,7 @@ package docker
import ( import (
"net/http" "net/http"
"encoding/json" "encoding/json"
"os"
"github.com/azukaar/cosmos-server/src/utils" "github.com/azukaar/cosmos-server/src/utils"
@ -18,6 +19,12 @@ func SecureContainerRoute(w http.ResponseWriter, req *http.Request) {
containerName := utils.Sanitize(vars["containerId"]) containerName := utils.Sanitize(vars["containerId"])
status := utils.Sanitize(vars["status"]) status := utils.Sanitize(vars["status"])
if os.Getenv("HOSTNAME") != "" && containerName == os.Getenv("HOSTNAME") {
utils.Error("SecureContainerRoute - Cannot force secure self", nil)
utils.HTTPError(w, "Cannot force secure self", http.StatusBadRequest, "DS003")
return
}
if(req.Method == "GET") { if(req.Method == "GET") {
container, err := DockerClient.ContainerInspect(DockerContext, containerName) container, err := DockerClient.ContainerInspect(DockerContext, containerName)
if err != nil { if err != nil {

View file

@ -3,6 +3,7 @@ package docker
import ( import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"os"
"github.com/azukaar/cosmos-server/src/utils" "github.com/azukaar/cosmos-server/src/utils"
containerType "github.com/docker/docker/api/types/container" containerType "github.com/docker/docker/api/types/container"
@ -38,6 +39,12 @@ func UpdateContainerRoute(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req) vars := mux.Vars(req)
containerName := utils.Sanitize(vars["containerId"]) containerName := utils.Sanitize(vars["containerId"])
if os.Getenv("HOSTNAME") != "" && containerName == os.Getenv("HOSTNAME") {
utils.Error("SecureContainerRoute - Cannot update self", nil)
utils.HTTPError(w, "Cannot update self", http.StatusBadRequest, "DS003")
return
}
container, err := DockerClient.ContainerInspect(DockerContext, containerName) container, err := DockerClient.ContainerInspect(DockerContext, containerName)
if err != nil { if err != nil {
utils.Error("UpdateContainer", err) utils.Error("UpdateContainer", err)

View file

@ -25,11 +25,9 @@ func main() {
docker.BootstrapAllContainersFromTags() docker.BootstrapAllContainersFromTags()
version, err := docker.DockerClient.ServerVersion(context.Background()) version, err := docker.DockerClient.ServerVersion(context.Background())
if err != nil { if err == nil {
panic(err) utils.Log("Docker API version: " + version.APIVersion)
} }
utils.Log("Docker API version: " + version.APIVersion)
StartServer() StartServer()
} }