-
+
+ {#if server.tor}
+
+ {/if}
- {#if server.status === 'up'}
- Online
- {:else}
- Offline
- {/if}
+
diff --git a/web/src/routes/Service.svelte b/web/src/routes/Service.svelte
new file mode 100644
index 0000000..ca64cea
--- /dev/null
+++ b/web/src/routes/Service.svelte
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+ {#if healthy === undefined}
+
+ {:else}
+
+ {/if}
+
+
+
+
+
+
+
diff --git a/web/src/routes/api/health/[serviceName]/+server.ts b/web/src/routes/api/health/[serviceName]/+server.ts
new file mode 100644
index 0000000..c8c16e4
--- /dev/null
+++ b/web/src/routes/api/health/[serviceName]/+server.ts
@@ -0,0 +1,9 @@
+import { json, type RequestHandler } from '@sveltejs/kit';
+import { execa } from 'execa';
+
+export const GET: RequestHandler = async ({ params }) => {
+ const { stdout } = await execa('screen', ['-ls'], { shell: true });
+ const isRunning = stdout.includes(params.serviceName!);
+
+ return json({ healthy: isRunning });
+};
diff --git a/web/src/routes/login/+layout.svelte b/web/src/routes/login/+layout.svelte
index bd81c79..3962c68 100644
--- a/web/src/routes/login/+layout.svelte
+++ b/web/src/routes/login/+layout.svelte
@@ -1,6 +1,6 @@
diff --git a/web/src/routes/service/+page.server.ts b/web/src/routes/service/+page.server.ts
new file mode 100644
index 0000000..a92abbd
--- /dev/null
+++ b/web/src/routes/service/+page.server.ts
@@ -0,0 +1,6 @@
+import { redirect } from '@sveltejs/kit';
+import type { PageServerLoad } from './$types';
+
+export const load: PageServerLoad = async () => {
+ throw redirect(303, '/');
+};
diff --git a/web/src/routes/service/[serviceName]/+page.server.ts b/web/src/routes/service/[serviceName]/+page.server.ts
new file mode 100644
index 0000000..4a3a3d7
--- /dev/null
+++ b/web/src/routes/service/[serviceName]/+page.server.ts
@@ -0,0 +1,78 @@
+import { type Actions, error } from '@sveltejs/kit';
+import type { PageServerLoad } from './$types';
+import logger from '$lib/logger';
+import { execa } from 'execa';
+import { promises } from 'node:fs';
+
+const services: Record
= {
+ tor: {
+ name: 'Tor',
+ command: {
+ restart: 'screen -L -Logfile /var/vlogs/tor -dmS "tor" tor -f /etc/tor/torrc',
+ logs: 'logs tor',
+ },
+ },
+ redis: {
+ name: 'Redis',
+ command: {
+ restart:
+ 'screen -L -Logfile /var/vlogs/redis -dmS "redis" bash -c "redis-server --port 6479 --daemonize no --dir /data --appendonly yes"',
+ logs: 'logs redis',
+ },
+ },
+};
+
+interface Service {
+ name: string;
+ command: {
+ restart: string;
+ logs: string;
+ };
+}
+
+export const load: PageServerLoad = async ({ params }) => {
+ if (!params.serviceName || !services[params.serviceName]) {
+ throw error(404, 'Not Found');
+ }
+
+ return {
+ slug: params.serviceName,
+ title: services[params.serviceName].name,
+ };
+};
+
+export const actions: Actions = {
+ clearLogs: async ({ request, params }) => {
+ const { serviceName } = params;
+
+ try {
+ await promises.writeFile(`/var/vlogs/${serviceName}`, '');
+ return {};
+ } catch (e) {
+ logger.error(e);
+ throw error(500, 'Unhandled Exception');
+ }
+ },
+ logs: async ({ request, params }) => {
+ const { serviceName } = params;
+
+ try {
+ const { stdout } = await execa(services[serviceName!].command.logs, { shell: true });
+ return { logs: stdout };
+ } catch (e) {
+ logger.error(e);
+ throw error(500, 'Unhandled Exception');
+ }
+ },
+ restart: async ({ request, params }) => {
+ const { serviceName } = params;
+
+ try {
+ await execa(services[serviceName!].command.restart, { shell: true });
+ return {};
+ } catch (e) {
+ logger.error(e);
+ throw error(500, 'Unhandled Exception');
+ }
+ },
+};
diff --git a/web/src/routes/service/[serviceName]/+page.svelte b/web/src/routes/service/[serviceName]/+page.svelte
new file mode 100644
index 0000000..ad3935c
--- /dev/null
+++ b/web/src/routes/service/[serviceName]/+page.svelte
@@ -0,0 +1,88 @@
+
+
+
+
+
+ Logs
+
+
+
+ {#if !logs}
+
+
+
+ {/if}
+
+
+
+
+
+
+
diff --git a/web/src/routes/service/[serviceName]/Layout.svelte b/web/src/routes/service/[serviceName]/Layout.svelte
new file mode 100644
index 0000000..121b047
--- /dev/null
+++ b/web/src/routes/service/[serviceName]/Layout.svelte
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+