import Head from 'next/head' import Link from 'next/link' import styles from '/styles/Home.module.css' import { Service, CustomLink, EntryList, ServiceStatus, ServiceType, ServiceLocation } from '../interfaces/LinkTypes' import Dockerode from 'dockerode'; import { ReactElement, useEffect, useState } from 'react' import useSWR, { KeyedMutator } from 'swr'; const fetcher = (url: string) => fetch(url).then((res) => res.json()) //function Services(props: EntryList) { const Services = () => { const { serviceList, isLoading, isError } = useServices(); let content: ReactElement = <>; // TODO: look into asyncing this as well useStatus(serviceList); if (isError) { content =
Error Loading data
} else if (isLoading) { content =
Loading..
} else if (serviceList) { content =
{serviceList.map((item: Service) => (

{item.name}

{item.status}

{item.desc}

{item.warn}

))}
} return ( <> Neshura Servers

Service List

Lists all available Services, most likely up-to-date

{content} ) } function useStatus(serviceList: Service[] | undefined) { const { data, error } = useSWR('/api/containers', fetcher); if (data && serviceList) { serviceList.forEach((service: Service) => { getStatus(data, service); }) } else if (error) { console.log(error); } } function useServices(): { serviceList: Service[] | undefined, isLoading: boolean, isError: boolean } { const { data, error } = useSWR('/api/services', fetcher); return { serviceList: data, isLoading: !error && !data, isError: error }; } function getStatus(containers: Dockerode.ContainerInfo[], entry: Service) { // for now only the BRR7-4800U can be used with Docker, needs changing once more Servers are used // TODO: support multiple locations for docker if (entry.location === ServiceLocation.brr7_4800u) { // app in this context means any non-docker page if (entry.type === ServiceType.app) { fetch(entry.href) .then((data: Response) => { if (data.ok) { if (data.status == 200 || data.status == 301 || data.status == 302) { entry.status = ServiceStatus.online; } else { entry.status = ServiceStatus.offline; } } else { entry.status = ServiceStatus.offline; } }) .catch(error => { console.log(error); entry.status = ServiceStatus.error; }); } else if (entry.type === "docker") { entry.status = ServiceStatus.offline; // Loop over every found container and compare to the entry provided containers.forEach((element: Dockerode.ContainerInfo) => { element.Names.forEach((containerName: string) => { if (containerName.startsWith("/")) { containerName = containerName.substring(1); } if (containerName === entry.docker_container_name) { entry.status = ServiceStatus.online; } }); if (entry.docker_container_name == null) { console.log("MISSING DOCKER CONTAINER NAME FOR " + entry.name); entry.status = ServiceStatus.error; } }); } else { entry.status = ServiceStatus.error } } // for non-local locations pinging can be used to see if they're up else if (entry.location === ServiceLocation.other) { fetch(entry.href) .then((data) => { if (data.ok) { if (data.status == 200 || data.status == 301 || data.status == 302) { return (entry.status = ServiceStatus.online); } else (entry.status = ServiceStatus.offline); } else { entry.status = ServiceStatus.offline; } }) .catch((error) => { console.log(error); entry.status = ServiceStatus.error; }); } else { entry.status = ServiceStatus.error } return; } export default Services