diff --git a/front-end/src/dashboard/Container.js b/front-end/src/dashboard/Container.js index a034406..ba50d9a 100644 --- a/front-end/src/dashboard/Container.js +++ b/front-end/src/dashboard/Container.js @@ -1,92 +1,98 @@ -import React, {useState, useEffect} from 'react'; -import {useParams} from "react-router"; -import { w3cwebsocket as W3CWebSocket } from "websocket"; -import {Button, Typography} from "@material-ui/core"; -import {Terminal} from 'xterm'; -import 'xterm/css/xterm.css' -import Box from "@material-ui/core/Box"; -import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; - -function Container() { - const [container, setContainer] = useState({}); - const { jobUuid, id } = useParams(); - - useEffect(() => { - const protocol = window.location.protocol.replace('http', 'ws'); - const host = window.location.host - const client = new W3CWebSocket(`${protocol}//${host}/${jobUuid}/container/${id}/logs`); - const term = new Terminal(); - - function streamLogs() { - term.open(document.getElementById('terminal')); - client.onopen = () => client.send('logs'); - client.onmessage = function (event) { - term.writeln(event.data) - } - client.onerror = (error) => { - console.error(error) - } + + +const express = require('express') +const expressApp = express(); +const expressWs = require('express-ws')(expressApp); +const port = 3001; +const path = require('path'); +const Docker = require('dockerode'); +const { app } = expressWs; + +const FRONT_END_PATH = path.join(__dirname, '..', 'front-end', 'build') + +app.use(express.json()); + +app.use(express.static(FRONT_END_PATH)); + + +const setDocker = async function (req, res, next) { + let docker = new Docker({ protocol: 'ssh', host: `${req.params.jobUuid}.lan`, password: 'password', username: 'root'}); + //ping docker to see if connection is working + try { + await docker.ping(); + req.docker = docker; + next() + } catch (err) { + next(err) + } +} + + +app.get('/:jobUuid/containers', setDocker, (req, res, next) => { + req.docker.listContainers({}, (err, containers) => { + if (err) { + console.error(err); + next(err); + } else { + res.send(containers); } + }) +}); - streamLogs() - }, [id, jobUuid]); - - useEffect(() => { - async function fetchContainer() { - try { - const res = await fetch(`/${jobUuid}/container/${id}`) - const result = await res.json() - setContainer(result) - } catch (reason) { - console.error(reason) - } +app.get('/:jobUuid/container/:id', setDocker, (req, res, next) => { + req.docker.getContainer(req.params.id).inspect( {},(err, container) => { + if (err) { + console.error(err); + next(err); + } else { + res.send(container); } - fetchContainer() - }, [id, jobUuid]) - - return( - - - - - {(container && container.Id)? `Container: ${container.Id.substring(0, 11)}` : null} - {(container && container.Id)? container.Name: null} - - - - - { - (container && container.Id)? <> - - - Status: {container.State.Status} - - - - - Created at: {container.Created} - - - - - Started at: {container.State.StartedAt} - - - - : null - } - - - -
- - - - ); -} + }) +}); + +app.ws('/:jobUuid/container/:id/logs', async (ws, req) => { + let docker = new Docker({ protocol: 'ssh', host: `${req.params.jobUuid}.lan`, password: 'password', username: 'root'}); + + //ping docker to see if connection is working + try { + await docker.ping(); + } catch (err) { + ws.Close(); + } + + let container = docker.getContainer(req.params.id) + if(!container) { + ws.send('Could not find container.'); + } + + container.logs({ + follow: true, + stdout: true, + stderr: true + }, (err, logs) => { + if (err) { + console.error(err); + ws.Close(); + } else { + logs.on('data', chunk => { + let encodedLogs = Buffer.from(chunk, 'utf-8').toString(); + ws.send(encodedLogs); + }) + } + }) +}); + +app.get('*', function(req, res) { + res.sendFile('index.html', {root: FRONT_END_PATH}); +}); + +app.use(function (err, req, res) { + console.error(err.stack) + res.status(500).send({ + err : err.stack + }) +}) -export default Container; \ No newline at end of file +app.listen(port, () => { + console.log(`Docker plugin dashboard listening on http://localhost:${port}`) +}); \ No newline at end of file diff --git a/front-end/src/dashboard/Dashboard.js b/front-end/src/dashboard/Dashboard.js index 41317dc..75418ea 100644 --- a/front-end/src/dashboard/Dashboard.js +++ b/front-end/src/dashboard/Dashboard.js @@ -11,6 +11,7 @@ import {Link} from "react-router-dom"; import Box from '@material-ui/core/Box'; import {useParams} from "react-router-dom"; + function Dashboard() { const [containers, setContainers] = useState([]); const [page, setPage] = useState(0);