From 035224b02bd855638b9a2a727252f2661e476a8b Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Mon, 27 Jun 2022 23:38:54 +0200 Subject: [PATCH] :sparkles: add start/stop/restart feature on containers --- src/components/Docker/ContainerActionBar.tsx | 68 +++++++++++++------- src/components/Docker/DockerDrawer.tsx | 28 ++++---- src/pages/api/docker/container/[id].tsx | 38 +++++++++-- 3 files changed, 93 insertions(+), 41 deletions(-) diff --git a/src/components/Docker/ContainerActionBar.tsx b/src/components/Docker/ContainerActionBar.tsx index 90bfe4596..474732619 100644 --- a/src/components/Docker/ContainerActionBar.tsx +++ b/src/components/Docker/ContainerActionBar.tsx @@ -4,6 +4,7 @@ import { IconCheck, IconPlayerPlay, IconPlayerStop, + IconRefresh, IconRotateClockwise, IconX, } from '@tabler/icons'; @@ -12,10 +13,10 @@ import Dockerode from 'dockerode'; function sendNotification(action: string, containerId: string, containerName: string) { showNotification({ - id: 'load-data', + id: containerId, loading: true, title: `${action}ing container ${containerName}`, - message: 'Your password is being checked...', + message: undefined, autoClose: false, disallowClose: true, }); @@ -23,19 +24,19 @@ function sendNotification(action: string, containerId: string, containerName: st setTimeout(() => { if (res.data.success === true) { updateNotification({ - id: 'load-data', - title: 'Container restarted', - message: 'Your container was successfully restarted', + id: containerId, + title: `Container ${containerName} ${action}ed`, + message: `Your container was successfully ${action}ed`, icon: , autoClose: 2000, }); } if (res.data.success === false) { updateNotification({ - id: 'load-data', + id: containerId, color: 'red', - title: 'There was an error restarting your container.', - message: 'Your container has encountered issues while restarting.', + title: 'There was an error with your container.', + message: undefined, icon: , autoClose: 2000, }); @@ -44,39 +45,58 @@ function sendNotification(action: string, containerId: string, containerName: st }); } -function restart(container: Dockerode.ContainerInfo) { - sendNotification('restart', container.Id, container.Names[0]); -} -function stop(container: Dockerode.ContainerInfo) { - console.log('stoping container', container.Id); -} -function start(container: Dockerode.ContainerInfo) { - console.log('starting container', container.Id); -} - export interface ContainerActionBarProps { selected: Dockerode.ContainerInfo[]; + reload: () => void; } -export default function ContainerActionBar(props: ContainerActionBarProps) { - const { selected } = props; +export default function ContainerActionBar({ selected, reload }: ContainerActionBarProps) { return ( - - + ); } diff --git a/src/components/Docker/DockerDrawer.tsx b/src/components/Docker/DockerDrawer.tsx index c6742f55c..8e07dda66 100644 --- a/src/components/Docker/DockerDrawer.tsx +++ b/src/components/Docker/DockerDrawer.tsx @@ -33,6 +33,12 @@ export default function DockerDrawer(props: any) { const [containers, setContainers] = useState([]); const { classes, cx } = useStyles(); const [selection, setSelection] = useState([]); + function reload() { + axios.get('/api/docker/containers').then((res) => { + setContainers(res.data); + }); + } + const toggleRow = (container: Docker.ContainerInfo) => setSelection((current) => current.includes(container) ? current.filter((c) => c !== container) : [...current, container] @@ -43,9 +49,7 @@ export default function DockerDrawer(props: any) { ); useEffect(() => { - axios.get('/api/docker/containers').then((res) => { - setContainers(res.data); - }); + reload(); }, []); const rows = containers.map((element) => { const selected = selection.includes(element); @@ -62,15 +66,15 @@ export default function DockerDrawer(props: any) { {element.Image} - {element.Ports.slice(-3).map((port) => ( - - {port.PrivatePort}:{port.PublicPort} - - ))} + {element.Ports.sort((a, b) => a.PrivatePort - b.PrivatePort) + .slice(-3) + .map((port) => ( + + {port.PrivatePort}:{port.PublicPort} + + ))} {element.Ports.length > 3 && ( - - {element.Ports.length - 3} more - + {element.Ports.length - 3} more )} @@ -85,7 +89,7 @@ export default function DockerDrawer(props: any) { <> setOpened(false)} padding="xl" size="full"> - + diff --git a/src/pages/api/docker/container/[id].tsx b/src/pages/api/docker/container/[id].tsx index 5e6c7d54c..dd7c2fa65 100644 --- a/src/pages/api/docker/container/[id].tsx +++ b/src/pages/api/docker/container/[id].tsx @@ -29,11 +29,39 @@ async function Get(req: NextApiRequest, res: NextApiResponse) { }); } }); - if (action === 'restart') { - await container.restart(); - return res.status(200).json({ - success: true, - }); + + switch (action) { + case 'start': + container.start((err, data) => { + if (err) { + res.status(500).json({ + message: err, + }); + } + }); + break; + case 'stop': + container.stop((err, data) => { + if (err) { + res.status(500).json({ + message: err, + }); + } + }); + break; + case 'restart': + container.restart((err, data) => { + if (err) { + res.status(500).json({ + message: err, + }); + } + }); + break; + default: + res.status(400).json({ + message: 'Invalid action', + }); } return res.status(200).json({ success: true,
your docker containers