[release] version 0.5.0-unstable7

This commit is contained in:
Yann Stepienik 2023-05-15 20:23:06 +01:00
parent 5545163768
commit 1d10c66a22
9 changed files with 142 additions and 25 deletions

View file

@ -78,6 +78,8 @@ export function CosmosContainerPicker({formik, nameOnly, lockTarget, TargetConta
})
setPortsOptions(portsTemp)
console.log(targetResult)
if(targetResult.port == '') {
targetResult.port = '80'
@ -117,6 +119,7 @@ export function CosmosContainerPicker({formik, nameOnly, lockTarget, TargetConta
}
const onContainerChange = (newContainer) => {
console.log(newContainer)
if(loading) return;
targetResult.container = newContainer.Names[0]
targetResult.containerObject = newContainer
@ -155,7 +158,7 @@ export function CosmosContainerPicker({formik, nameOnly, lockTarget, TargetConta
}
if (targetResult.container !== 'null') {
postContainerChange(res.data.find((container) => container.Names[0] === targetResult.container))
postContainerChange(res.data.find((container) => container.Names[0] === targetResult.container) || targetResult.containerObject)
}
})();
@ -220,7 +223,6 @@ export function CosmosContainerPicker({formik, nameOnly, lockTarget, TargetConta
)}
/>}
{!nameOnly && <>
{(portsOptions) ? (<>
<InputLabel htmlFor={name + "-port"}>Container Port</InputLabel>
<Autocomplete
className="px-2 my-2"
@ -228,8 +230,12 @@ export function CosmosContainerPicker({formik, nameOnly, lockTarget, TargetConta
name={name + "-port"}
id={name + "-port"}
value={targetResult.port}
options={portsOptions.map((option) => (option))}
options={((portsOptions && portsOptions.length) ? portsOptions : [])}
placeholder='Select a port'
onBlur={(event) => {
targetResult.port = event.target.value || '';
formik.setFieldValue(name, getTarget())
}}
freeSolo
filterOptions={(x) => x} // disable filtering
getOptionLabel={(option) => '' + option}
@ -237,7 +243,7 @@ export function CosmosContainerPicker({formik, nameOnly, lockTarget, TargetConta
return ('' + option) === value
}}
onChange={(event, newValue) => {
targetResult.port = newValue
targetResult.port = newValue || '';
formik.setFieldValue(name, getTarget())
}}
renderInput={(params) => <TextField {...params} />}
@ -245,21 +251,18 @@ export function CosmosContainerPicker({formik, nameOnly, lockTarget, TargetConta
{targetResult.port == '' && targetResult.port == 0 && <FormHelperText error id="standard-weight-helper-text-name-login">
Please select a port
</FormHelperText>}
</>) : ''}
{(portsOptions) ? (<>
<InputLabel htmlFor={name + "-protocol"}>Container Protocol (use HTTP if unsure)</InputLabel>
<TextField
type="text"
name={name + "-protocol"}
defaultValue={targetResult.protocol}
onChange={(event) => {
targetResult.protocol = event.target.value && event.target.value.toLowerCase()
formik.setFieldValue(name, getTarget())
}}
/>
</>) : ''}
<InputLabel htmlFor={name + "-protocol"}>Container Protocol (use HTTP if unsure)</InputLabel>
<TextField
type="text"
name={name + "-protocol"}
defaultValue={targetResult.protocol}
onChange={(event) => {
targetResult.protocol = event.target.value && event.target.value.toLowerCase()
formik.setFieldValue(name, getTarget())
}}
/>
<InputLabel htmlFor={name}>Result Target Preview</InputLabel>
<TextField

View file

@ -7,7 +7,8 @@ const GetActions = ({
Id,
state,
refreshServeApps,
setIsUpdatingId
setIsUpdatingId,
updateAvailable
}) => {
const [confirmDelete, setConfirmDelete] = React.useState(false);
const isMiniMobile = useMediaQuery((theme) => theme.breakpoints.down('xsm'));
@ -93,7 +94,6 @@ const GetActions = ({
];
return actions.filter((action) => {
let updateAvailable = false;
return action.if.includes(state) ?? (updateAvailable && action.if.includes('update_available'));
}).map((action) => {
return <Tooltip title={action.t}>{action.e}</Tooltip>

View file

@ -18,12 +18,20 @@ import NetworkContainerSetup from './network';
import VolumeContainerSetup from './volumes';
import DockerTerminal from './terminal';
import NewDockerService from './newService';
import RouteManagement from '../../config/routes/routeman';
const getHostnameFromName = (name) => {
return name.replace('/', '').replace(/_/g, '-').replace(/[^a-zA-Z0-9-]/g, '').toLowerCase().replace(/\s/g, '-') + '.' + window.location.origin.split('://')[1]
}
const NewDockerServiceForm = () => {
const [currentTab, setCurrentTab] = React.useState(0);
const [maxTab, setMaxTab] = React.useState(0);
const [containerInfo, setContainerInfo] = React.useState({
Name: '',
Names: [],
Ports: [], // fake for contianerPicker
Route: null,
Config: {
Env: [],
Labels: {},
@ -64,6 +72,7 @@ const NewDockerServiceForm = () => {
acc[cur] = {};
return acc;
}, {}),
Routes: [containerInfo.Route]
}
},
}
@ -90,7 +99,7 @@ const NewDockerServiceForm = () => {
variant="contained"
fullWidth
endIcon={<ArrowRightOutlined />}
disabled={currentTab === 3}
disabled={currentTab === 4}
onClick={() => {
setCurrentTab(currentTab + 1);
setMaxTab(Math.max(currentTab + 1, maxTab));
@ -100,6 +109,8 @@ const NewDockerServiceForm = () => {
</Button>
</Stack>
console.log(containerInfo)
return <div>
<Stack spacing={1}>
<Stack direction="row" spacing={1} alignItems="center">
@ -119,6 +130,7 @@ const NewDockerServiceForm = () => {
const newValues = {
...containerInfo,
Name: values.name,
Names: [values.name],
Config: {
...containerInfo.Config,
Image: values.image,
@ -149,6 +161,44 @@ const NewDockerServiceForm = () => {
setContainerInfo(newValues);
}}/>{nav()}</Stack>
},
{
title: 'URL',
disabled: maxTab < 1,
children: <Stack spacing={2}><RouteManagement TargetContainer={containerInfo}
routeConfig={{
Target: "http://"+containerInfo.Name.replace('/', '') + ":",
Mode: "SERVAPP",
Name: containerInfo.Name.replace('/', ''),
Description: "Expose " + containerInfo.Name.replace('/', '') + " to the internet",
UseHost: true,
Host: getHostnameFromName(containerInfo.Name),
UsePathPrefix: false,
PathPrefix: '',
CORSOrigin: '',
StripPathPrefix: false,
AuthEnabled: false,
Timeout: 14400000,
ThrottlePerMinute: 10000,
BlockCommonBots: true,
SmartShield: {
Enabled: true,
}
}}
routeNames={[]}
setRouteConfig={(newRoute) => {
const newValues = {
...containerInfo,
Route: newRoute,
}
setContainerInfo(newValues);
}}
up={() => {}}
down={() => {}}
deleteRoute={() => {}}
noControls
lockTarget
/>{nav()}</Stack>
},
{
title: 'Network',
disabled: maxTab < 1,
@ -204,7 +254,7 @@ const NewDockerServiceForm = () => {
},
{
title: 'Storage',
disabled: maxTab < 2,
disabled: maxTab < 1,
children: <Stack spacing={2}><VolumeContainerSetup newContainer containerInfo={containerInfo} OnChange={(values) => {
console.log(values)
const newValues = {
@ -225,7 +275,7 @@ const NewDockerServiceForm = () => {
},
{
title: 'Review & Start',
disabled: maxTab < 3,
disabled: maxTab < 1,
children: <Stack spacing={2}><NewDockerService service={service} />{nav()}</Stack>
}
]} />}

View file

@ -39,6 +39,7 @@ const ServeApps = () => {
const [isUpdating, setIsUpdating] = useState({});
const [search, setSearch] = useState("");
const [config, setConfig] = useState(null);
const [updatesAvailable, setUpdatesAvailable] = useState(null);
const [openModal, setOpenModal] = useState(false);
const [newRoute, setNewRoute] = useState(null);
const [submitErrors, setSubmitErrors] = useState([]);
@ -50,6 +51,7 @@ const ServeApps = () => {
});
API.config.get().then((res) => {
setConfig(res.data);
setUpdatesAvailable(res.updates);
});
setIsUpdating({});
};
@ -190,7 +192,13 @@ const ServeApps = () => {
{/* <Button variant="contained" size="small" onClick={() => {}}>
Update
</Button> */}
<GetActions Id={app.Names[0].replace('/', '')} state={app.State} setIsUpdatingId={setIsUpdatingId} refreshServeApps={refreshServeApps} />
<GetActions
Id={app.Names[0].replace('/', '')}
state={app.State}
setIsUpdatingId={setIsUpdatingId}
refreshServeApps={refreshServeApps}
updateAvailable={updatesAvailable[app.Names[0]]}
/>
</Stack>
</Stack>
<Stack margin={1} direction="column" spacing={1} alignItems="flex-start">

View file

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

View file

@ -4,6 +4,7 @@ import (
"io/ioutil"
"net/http"
"github.com/azukaar/cosmos-server/src/utils"
"github.com/azukaar/cosmos-server/src/docker"
"os"
"path/filepath"
"encoding/json"
@ -96,9 +97,17 @@ func checkVersion() {
}
}
func checkUpdatesAvailable() {
utils.UpdateAvailable = docker.CheckUpdatesAvailable()
}
func CRON() {
go func() {
gocron.Every(1).Day().At("00:00").Do(checkVersion)
<-gocron.Start()
}()
go func() {
gocron.Every(6).Hours().Do(checkUpdatesAvailable)
<-gocron.Start()
}()
}

View file

@ -39,6 +39,7 @@ func ConfigApiGet(w http.ResponseWriter, req *http.Request) {
json.NewEncoder(w).Encode(map[string]interface{}{
"status": "OK",
"data": config,
"updates": utils.UpdateAvailable,
})
} else {
utils.Error("SettingGet: Method not allowed" + req.Method, nil)

View file

@ -6,6 +6,7 @@ import (
"time"
"fmt"
"bufio"
"strings"
"github.com/azukaar/cosmos-server/src/utils"
"github.com/docker/docker/client"
@ -312,3 +313,46 @@ func Test() error {
return nil
}
func CheckUpdatesAvailable() map[string]bool {
result := make(map[string]bool)
// for each containers
containers, err := ListContainers()
if err != nil {
utils.Error("CheckUpdatesAvailable", err)
return result
}
for _, container := range containers {
utils.Log("Checking for updates for " + container.Image)
rc, err := DockerClient.ImagePull(DockerContext, container.Image, types.ImagePullOptions{})
if err != nil {
utils.Error("CheckUpdatesAvailable", err)
continue
}
scanner := bufio.NewScanner(rc)
defer rc.Close()
for scanner.Scan() {
newStr := scanner.Text()
// Check if a download has started
if strings.Contains(newStr, "\"status\":\"Pulling fs layer\"") {
utils.Log("Updates available for " + container.Image)
result[container.Names[0]] = true
rc.Close()
break
} else if strings.Contains(newStr, "\"status\":\"Status: Image is up to date\"") {
utils.Log("No updates available for " + container.Image)
rc.Close()
break
}
}
}
return result
}

View file

@ -26,6 +26,8 @@ var NewVersionAvailable = false
var NeedsRestart = false
var UpdateAvailable = map[string]bool{}
var DefaultConfig = Config{
LoggingLevel: "INFO",
NewInstall: true,