[release] version 0.5.0-unstable12
This commit is contained in:
parent
467f84187f
commit
68fd353181
|
@ -268,6 +268,54 @@ function pullImage(imageName, onProgress, ifMissing) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateContainerImage(containerName, onProgress) {
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const containerNameEncoded = encodeURIComponent(containerName);
|
||||||
|
|
||||||
|
return fetch(`/cosmos/api/servapps/${containerNameEncoded}/manage/update`, requestOptions)
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The response body is a ReadableStream. This code reads the stream and passes chunks to the callback.
|
||||||
|
const reader = response.body.getReader();
|
||||||
|
|
||||||
|
// Read the stream and pass chunks to the callback as they arrive
|
||||||
|
return new ReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
function read() {
|
||||||
|
return reader.read().then(({ done, value }) => {
|
||||||
|
if (done) {
|
||||||
|
controller.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Decode the UTF-8 text
|
||||||
|
let text = new TextDecoder().decode(value);
|
||||||
|
// Split by lines in case there are multiple lines in one chunk
|
||||||
|
let lines = text.split('\n');
|
||||||
|
for (let line of lines) {
|
||||||
|
if (line) {
|
||||||
|
// Call the progress callback
|
||||||
|
onProgress(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
controller.enqueue(value);
|
||||||
|
return read();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return read();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function autoUpdate(id, toggle) {
|
function autoUpdate(id, toggle) {
|
||||||
return wrap(fetch('/cosmos/api/servapps/' + id + '/auto-update/'+toggle, {
|
return wrap(fetch('/cosmos/api/servapps/' + id + '/auto-update/'+toggle, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
@ -299,4 +347,5 @@ export {
|
||||||
createService,
|
createService,
|
||||||
pullImage,
|
pullImage,
|
||||||
autoUpdate,
|
autoUpdate,
|
||||||
|
updateContainerImage,
|
||||||
};
|
};
|
|
@ -53,7 +53,7 @@ const LogsInModal = ({title, request, OnSuccess, OnError, closeAnytime, initialL
|
||||||
|
|
||||||
if(preRef.current)
|
if(preRef.current)
|
||||||
preRef.current.scrollTop = preRef.current.scrollHeight;
|
preRef.current.scrollTop = preRef.current.scrollHeight;
|
||||||
|
|
||||||
if (newlog.includes('[OPERATION SUCCEEDED]')) {
|
if (newlog.includes('[OPERATION SUCCEEDED]')) {
|
||||||
setDone(true);
|
setDone(true);
|
||||||
setOpenModal(false);
|
setOpenModal(false);
|
||||||
|
|
|
@ -21,9 +21,9 @@ const GetActions = ({
|
||||||
const doTo = (action) => {
|
const doTo = (action) => {
|
||||||
setIsUpdating(true);
|
setIsUpdating(true);
|
||||||
|
|
||||||
if(action === 'pull') {
|
if(action === 'update') {
|
||||||
setPullRequest(() => ((cb) => {
|
setPullRequest(() => ((cb) => {
|
||||||
API.docker.pullImage(image, cb, true)
|
API.docker.updateContainerImage(Id, cb, true)
|
||||||
}));
|
}));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ const GetActions = ({
|
||||||
{
|
{
|
||||||
t: 'Update Available',
|
t: 'Update Available',
|
||||||
if: ['update_available'],
|
if: ['update_available'],
|
||||||
e: <IconButton className="shinyButton" color='primary' onClick={() => {doTo('pull')}} size={isMiniMobile ? 'medium' : 'large'}>
|
e: <IconButton className="shinyButton" color='primary' onClick={() => {doTo('update')}} size={isMiniMobile ? 'medium' : 'large'}>
|
||||||
<UpCircleOutlined />
|
<UpCircleOutlined />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
},
|
},
|
||||||
|
@ -113,12 +113,11 @@ const GetActions = ({
|
||||||
request={pullRequest}
|
request={pullRequest}
|
||||||
title="Updating ServeApp..."
|
title="Updating ServeApp..."
|
||||||
OnSuccess={() => {
|
OnSuccess={() => {
|
||||||
doTo('update')
|
refreshServeApps();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!isUpdating && actions.filter((action) => {
|
{!isUpdating && actions.filter((action) => {
|
||||||
updateAvailable = true;
|
|
||||||
return action.if.includes(state) || (updateAvailable && action.if.includes('update_available'));
|
return action.if.includes(state) || (updateAvailable && action.if.includes('update_available'));
|
||||||
}).map((action) => {
|
}).map((action) => {
|
||||||
return <Tooltip title={action.t}>{action.e}</Tooltip>
|
return <Tooltip title={action.t}>{action.e}</Tooltip>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "cosmos-server",
|
"name": "cosmos-server",
|
||||||
"version": "0.5.0-unstable11",
|
"version": "0.5.0-unstable12",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "test-server.js",
|
"main": "test-server.js",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|
|
@ -3,8 +3,9 @@ package docker
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/azukaar/cosmos-server/src/utils"
|
"github.com/azukaar/cosmos-server/src/utils"
|
||||||
|
|
||||||
|
@ -69,14 +70,47 @@ func ManageContainerRoute(w http.ResponseWriter, req *http.Request) {
|
||||||
case "recreate":
|
case "recreate":
|
||||||
_, err = EditContainer(container.ID, container)
|
_, err = EditContainer(container.ID, container)
|
||||||
case "update":
|
case "update":
|
||||||
pull, errPull := DockerClient.ImagePull(DockerContext, imagename, doctype.ImagePullOptions{})
|
out, errPull := DockerClient.ImagePull(DockerContext, imagename, doctype.ImagePullOptions{})
|
||||||
if errPull != nil {
|
if errPull != nil {
|
||||||
utils.Error("Docker Pull", errPull)
|
utils.Error("Docker Pull", errPull)
|
||||||
utils.HTTPError(w, "Cannot pull new image", http.StatusBadRequest, "DS004")
|
utils.HTTPError(w, "Cannot pull new image", http.StatusBadRequest, "DS004")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
io.Copy(os.Stdout, pull)
|
defer out.Close()
|
||||||
|
|
||||||
|
// Enable streaming of response by setting appropriate headers
|
||||||
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
|
w.Header().Set("Transfer-Encoding", "chunked")
|
||||||
|
|
||||||
|
flusher, ok := w.(http.Flusher)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
utils.Error("Container Update - Cannot stream response", nil)
|
||||||
|
utils.HTTPError(w, "Cannot stream response", http.StatusInternalServerError, "DS004")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for image pull to finish
|
||||||
|
scanner := bufio.NewScanner(out)
|
||||||
|
for scanner.Scan() {
|
||||||
|
utils.Log(scanner.Text())
|
||||||
|
fmt.Fprintf(w, scanner.Text() + "\n")
|
||||||
|
flusher.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.Log("Container Update - Image pulled " + imagename)
|
||||||
|
|
||||||
_, err = EditContainer(container.ID, container)
|
_, err = EditContainer(container.ID, container)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
utils.Error("Container Update - EditContainer", err)
|
||||||
|
utils.HTTPError(w, "[OPERATION FAILED] Cannot recreate container", http.StatusBadRequest, "DS004")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(w, "[OPERATION SUCCEEDED]")
|
||||||
|
flusher.Flush()
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
utils.HTTPError(w, "Invalid action", http.StatusBadRequest, "DS003")
|
utils.HTTPError(w, "Invalid action", http.StatusBadRequest, "DS003")
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue