From 1d10c66a224ac11a9dcc2b37fa139b4a77acb3b7 Mon Sep 17 00:00:00 2001 From: Yann Stepienik Date: Mon, 15 May 2023 20:23:06 +0100 Subject: [PATCH] [release] version 0.5.0-unstable7 --- .../pages/config/users/containerPicker.jsx | 39 +++++++------ client/src/pages/servapps/actionBar.jsx | 4 +- .../servapps/containers/newServiceForm.jsx | 56 ++++++++++++++++++- client/src/pages/servapps/servapps.jsx | 10 +++- package.json | 2 +- src/CRON.go | 9 +++ src/configapi/get.go | 1 + src/docker/docker.go | 44 +++++++++++++++ src/utils/utils.go | 2 + 9 files changed, 142 insertions(+), 25 deletions(-) diff --git a/client/src/pages/config/users/containerPicker.jsx b/client/src/pages/config/users/containerPicker.jsx index b9a345d..3ad49bd 100644 --- a/client/src/pages/config/users/containerPicker.jsx +++ b/client/src/pages/config/users/containerPicker.jsx @@ -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) ? (<> Container Port (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) => } @@ -245,21 +251,18 @@ export function CosmosContainerPicker({formik, nameOnly, lockTarget, TargetConta {targetResult.port == '' && targetResult.port == 0 && Please select a port } - ) : ''} - - {(portsOptions) ? (<> - Container Protocol (use HTTP if unsure) - { - targetResult.protocol = event.target.value && event.target.value.toLowerCase() - formik.setFieldValue(name, getTarget()) - }} - /> - ) : ''} + + Container Protocol (use HTTP if unsure) + { + targetResult.protocol = event.target.value && event.target.value.toLowerCase() + formik.setFieldValue(name, getTarget()) + }} + /> Result Target Preview { 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 {action.e} diff --git a/client/src/pages/servapps/containers/newServiceForm.jsx b/client/src/pages/servapps/containers/newServiceForm.jsx index d62f9bd..8587ebd 100644 --- a/client/src/pages/servapps/containers/newServiceForm.jsx +++ b/client/src/pages/servapps/containers/newServiceForm.jsx @@ -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={} - disabled={currentTab === 3} + disabled={currentTab === 4} onClick={() => { setCurrentTab(currentTab + 1); setMaxTab(Math.max(currentTab + 1, maxTab)); @@ -100,6 +109,8 @@ const NewDockerServiceForm = () => { + console.log(containerInfo) + return
@@ -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()} }, + { + title: 'URL', + disabled: maxTab < 1, + children: { + const newValues = { + ...containerInfo, + Route: newRoute, + } + setContainerInfo(newValues); + }} + up={() => {}} + down={() => {}} + deleteRoute={() => {}} + noControls + lockTarget + />{nav()} + }, { title: 'Network', disabled: maxTab < 1, @@ -204,7 +254,7 @@ const NewDockerServiceForm = () => { }, { title: 'Storage', - disabled: maxTab < 2, + disabled: maxTab < 1, children: { console.log(values) const newValues = { @@ -225,7 +275,7 @@ const NewDockerServiceForm = () => { }, { title: 'Review & Start', - disabled: maxTab < 3, + disabled: maxTab < 1, children: {nav()} } ]} />} diff --git a/client/src/pages/servapps/servapps.jsx b/client/src/pages/servapps/servapps.jsx index 96e04e4..7e6fab1 100644 --- a/client/src/pages/servapps/servapps.jsx +++ b/client/src/pages/servapps/servapps.jsx @@ -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 = () => { {/* */} - + diff --git a/package.json b/package.json index e1580ff..fe8be2a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmos-server", - "version": "0.5.0-unstable6", + "version": "0.5.0-unstable7", "description": "", "main": "test-server.js", "bugs": { diff --git a/src/CRON.go b/src/CRON.go index d5d7ab8..0457c25 100644 --- a/src/CRON.go +++ b/src/CRON.go @@ -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() + }() } \ No newline at end of file diff --git a/src/configapi/get.go b/src/configapi/get.go index 9d3ce77..69c7cef 100644 --- a/src/configapi/get.go +++ b/src/configapi/get.go @@ -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) diff --git a/src/docker/docker.go b/src/docker/docker.go index bc62cfa..040b061 100644 --- a/src/docker/docker.go +++ b/src/docker/docker.go @@ -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 +} diff --git a/src/utils/utils.go b/src/utils/utils.go index 70226c3..de603c4 100644 --- a/src/utils/utils.go +++ b/src/utils/utils.go @@ -26,6 +26,8 @@ var NewVersionAvailable = false var NeedsRestart = false +var UpdateAvailable = map[string]bool{} + var DefaultConfig = Config{ LoggingLevel: "INFO", NewInstall: true,