import express from 'express' import { WebSocketServer } from 'ws' import { createContainerPty } from './docker.js' import { runCommand } from './utils.js' const app = express() app.use(express.json()) app.get('/api/status', c => c.json(42)) app.get('/api/container/:uuid([a-zA-Z0-9]+)/exec/ls', async (req, res) => { const uuid = req.params.uuid try { const files = await runCommand('/bin/ls', ['exec', uuid, '/bin/ls']) res.json(files.trim().split('\n')) } catch (e) { res.json({ error: e.toString() }) } }) app.get('/api/container/:uuid([a-zA-Z0-9]+)/fs/*', async (req, res) => { const uuid = req.params.uuid const path = req.params[0] console.log('Getting', path) try { const content = await runCommand('docker', ['exec', uuid, '/bin/cat', '/' + path]) res.json(content) } catch (e) { res.json({ error: e.toString() }) } }) app.put('/api/container/:uuid([a-zA-Z0-9]+)/fs/*', async (req, res) => { const path = req.params[0] const content = req.body console.log(content) try { await runCommand('docker', ['exec', uuid, '/bin/sh', '-c', `cat - > "${path}"`], { stdin: content, }) res.json('ok') } catch (e) { res.json({ error: e.toString() }) } }) const server = app.listen(5432, () => { console.log('Starting API server on :5432...') }) const wss = new WebSocketServer({ server }) wss.on('connection', async (ws, req) => { const tag = req.url.split('/').at(-2) console.log(`Client connected to "${tag}"`) const container = await createContainerPty(tag, { onData(data) { ws.send( JSON.stringify({ type: 'pty', data, }) ) }, onExit(e) { ws.send( JSON.stringify({ type: 'destroyed', ...e, }) ) ws.close() }, }) ws.send( JSON.stringify({ type: 'created', id: container.id, }) ) ws.on('message', data => { container.pty.write(data) }) ws.on('close', () => { container.pty.kill() console.log(`Client disconnected`) }) })