From 9f3732d35ba6f6d1dbd873891f0e38d600d66d4c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 20 Oct 2022 10:42:47 +0200 Subject: [PATCH] fix: service logs --- apps/api/src/lib.ts | 1 + apps/api/src/lib/services/handlers.ts | 24 ++++--- apps/api/src/lib/templates.ts | 34 +++++---- .../src/routes/api/v1/services/handlers.ts | 15 ++-- apps/api/src/routes/api/v1/services/index.ts | 3 +- apps/api/src/routes/api/v1/services/types.ts | 8 ++- .../applications/[id]/logs/index.svelte | 20 ++---- .../src/routes/services/[id]/__layout.svelte | 44 +++++------- .../routes/services/[id]/logs/index.svelte | 72 +++++++++---------- 9 files changed, 105 insertions(+), 116 deletions(-) diff --git a/apps/api/src/lib.ts b/apps/api/src/lib.ts index ef92db42f..2cd1303df 100644 --- a/apps/api/src/lib.ts +++ b/apps/api/src/lib.ts @@ -42,6 +42,7 @@ async function weblate(service: any) { `WEBLATE_SITE_DOMAIN@@@$$generate_domain`, `POSTGRES_USER@@@${postgresqlUser}`, `POSTGRES_DATABASE@@@${postgresqlDatabase}`, + `POSTGRES_DB@@@${postgresqlDatabase}`, `POSTGRES_HOST@@@$$id-postgres`, `POSTGRES_PORT@@@5432`, `REDIS_HOST@@@$$id-redis`, diff --git a/apps/api/src/lib/services/handlers.ts b/apps/api/src/lib/services/handlers.ts index c1b15aa1e..1170930d3 100644 --- a/apps/api/src/lib/services/handlers.ts +++ b/apps/api/src/lib/services/handlers.ts @@ -725,18 +725,22 @@ export async function startService(request: FastifyRequest) { } // Generate files for builds - if (template.services[service].build) { - if (template.services[service]?.extras?.files?.length > 0) { - let Dockerfile = ` - FROM ${template.services[service].image}` - for (const file of template.services[service].extras.files) { - const { source, destination, content } = file; - await fs.writeFile(source, content); - Dockerfile += ` - COPY ./${path.basename(source)} ${destination}` + if (template.services[service]?.extras?.files?.length > 0) { + if (!template.services[service].build) { + template.services[service].build = { + context: workdir, + dockerfile: `Dockerfile.${service}` } - await fs.writeFile(`${workdir}/Dockerfile.${service}`, Dockerfile); } + let Dockerfile = ` + FROM ${template.services[service].image}` + for (const file of template.services[service].extras.files) { + const { source, destination, content } = file; + await fs.writeFile(source, content); + Dockerfile += ` + COPY ./${path.basename(source)} ${destination}` + } + await fs.writeFile(`${workdir}/Dockerfile.${service}`, Dockerfile); } } const { volumeMounts } = persistentVolumes(id, persistentStorage, config) diff --git a/apps/api/src/lib/templates.ts b/apps/api/src/lib/templates.ts index 8c171875e..33d67c2f8 100644 --- a/apps/api/src/lib/templates.ts +++ b/apps/api/src/lib/templates.ts @@ -21,8 +21,8 @@ export default [ `WEBLATE_ADMIN_PASSWORD=$$secret_weblate_admin_password`, `POSTGRES_PASSWORD=$$secret_postgres_password`, `POSTGRES_USER=$$config_postgres_user`, - `POSTGRES_DATABASE=$$config_postgres_db`, - `POSTGRES_HOST=$$id-postgres`, + `POSTGRES_DATABASE=$$config_postgres_database`, + `POSTGRES_HOST=$$id-postgresql`, `POSTGRES_PORT=5432`, `REDIS_HOST=$$id-redis`, ], @@ -59,7 +59,7 @@ export default [ { "id": "$$config_weblate_site_domain", "name": "WEBLATE_SITE_DOMAIN", - "label": "Weblate domain", + "label": "Weblate Domain", "defaultValue": "$$generate_domain", "description": "", }, @@ -69,6 +69,9 @@ export default [ "label": "Weblate Admin Password", "defaultValue": "$$generate_password", "description": "", + "extras": { + "isVisibleOnUI": true, + } }, { "id": "$$config_postgres_user", @@ -81,16 +84,23 @@ export default [ "id": "$$secret_postgres_password", "name": "POSTGRES_PASSWORD", "label": "PostgreSQL Password", - "defaultValue": "", + "defaultValue": "$$generate_password", "description": "", }, { "id": "$$config_postgres_db", "name": "POSTGRES_DB", "label": "PostgreSQL Database", - "defaultValue": "hasura", + "defaultValue": "weblate", "description": "", }, + { + "id": "$$config_postgres_database", + "name": "POSTGRES_DATABASE", + "label": "PostgreSQL Database", + "defaultValue": "$$config_postgres_db", + "description": "" + }, ] }, { @@ -102,10 +112,6 @@ export default [ "services": { "$$id": { "name": "SearXNG", - "build": { - context: "$$workdir", - dockerfile: "Dockerfile.$$id" - }, "depends_on": [ "$$id-redis" ], @@ -511,10 +517,6 @@ export default [ "$$id-postgresql": { "name": "PostgreSQL", "documentation": "Official docs are [here](https://umami.is/docs/getting-started)", - "build": { - context: "$$workdir", - dockerfile: "Dockerfile.$$id-postgresql" - }, "depends_on": [], "image": "postgres:12-alpine", "volumes": [ @@ -1371,10 +1373,6 @@ export default [ "$$id-clickhouse": { "name": "Clickhouse", "documentation": "Taken from https://plausible.io/", - "build": { - context: "$$workdir", - dockerfile: "Dockerfile.$$id-clickhouse" - }, "volumes": [ '$$id-clickhouse-data:/var/lib/clickhouse', ], @@ -1455,7 +1453,7 @@ export default [ "defaultValue": "$$generate_password", "description": "This is the admin password. Please change it.", "extras": { - "isVisibleOnUI": true + "isVisibleOnUI": true, } }, { diff --git a/apps/api/src/routes/api/v1/services/handlers.ts b/apps/api/src/routes/api/v1/services/handlers.ts index e6d92a2f9..53a9a6df5 100644 --- a/apps/api/src/routes/api/v1/services/handlers.ts +++ b/apps/api/src/routes/api/v1/services/handlers.ts @@ -157,9 +157,9 @@ export async function parseAndFindServiceTemplates(service: any, workdir?: strin const { name, value } = setting const regex = new RegExp(`\\$\\$config_${name}\\"`, 'gi') if (service.fqdn && value === '$$generate_fqdn') { - parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regex, service.fqdn+ "\"")) + parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regex, service.fqdn + "\"")) } else if (service.fqdn && value === '$$generate_domain') { - parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regex, getDomain(service.fqdn)+ "\"")) + parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regex, getDomain(service.fqdn) + "\"")) } else { parsedTemplate = JSON.parse(JSON.stringify(parsedTemplate).replaceAll(regex, value + "\"")) @@ -363,7 +363,7 @@ export async function getServiceUsage(request: FastifyRequest) { } export async function getServiceLogs(request: FastifyRequest) { try { - const { id } = request.params; + const { id, containerId } = request.params; let { since = 0 } = request.query if (since !== 0) { since = day(since).unix(); @@ -374,10 +374,8 @@ export async function getServiceLogs(request: FastifyRequest) { }); if (destinationDockerId) { try { - // const found = await checkContainer({ dockerId, container: id }) - // if (found) { const { default: ansi } = await import('strip-ansi') - const { stdout, stderr } = await executeDockerCmd({ dockerId, command: `docker logs --since ${since} --tail 5000 --timestamps ${id}` }) + const { stdout, stderr } = await executeDockerCmd({ dockerId, command: `docker logs --since ${since} --tail 5000 --timestamps ${containerId}` }) const stripLogsStdout = stdout.toString().split('\n').map((l) => ansi(l)).filter((a) => a); const stripLogsStderr = stderr.toString().split('\n').map((l) => ansi(l)).filter((a) => a); const logs = stripLogsStderr.concat(stripLogsStdout) @@ -385,7 +383,10 @@ export async function getServiceLogs(request: FastifyRequest) { return { logs: sortedLogs } // } } catch (error) { - const { statusCode } = error; + const { statusCode, stderr } = error; + if (stderr.startsWith('Error: No such container')) { + return { logs: [], noContainer: true } + } if (statusCode === 404) { return { logs: [] diff --git a/apps/api/src/routes/api/v1/services/index.ts b/apps/api/src/routes/api/v1/services/index.ts index 546c7fd5c..65fb52f57 100644 --- a/apps/api/src/routes/api/v1/services/index.ts +++ b/apps/api/src/routes/api/v1/services/index.ts @@ -70,7 +70,8 @@ const root: FastifyPluginAsync = async (fastify): Promise => { fastify.post('/:id/configuration/destination', async (request, reply) => await saveServiceDestination(request, reply)); fastify.get('/:id/usage', async (request) => await getServiceUsage(request)); - fastify.get('/:id/logs', async (request) => await getServiceLogs(request)); + // fastify.get('/:id/logs', async (request) => await getServiceLogs(request)); + fastify.get('/:id/logs/:containerId', async (request) => await getServiceLogs(request)); fastify.post('/:id/start', async (request) => await startService(request)); fastify.post('/:id/:type/start', async (request) => await startService(request)); diff --git a/apps/api/src/routes/api/v1/services/types.ts b/apps/api/src/routes/api/v1/services/types.ts index 3de06fa57..4d54792ed 100644 --- a/apps/api/src/routes/api/v1/services/types.ts +++ b/apps/api/src/routes/api/v1/services/types.ts @@ -15,9 +15,13 @@ export interface SaveServiceDestination extends OnlyId { destinationId: string } } -export interface GetServiceLogs extends OnlyId { +export interface GetServiceLogs{ + Params: { + id: string, + containerId: string + }, Querystring: { - since: number + since: number, } } export interface SaveServiceSettings extends OnlyId { diff --git a/apps/ui/src/routes/applications/[id]/logs/index.svelte b/apps/ui/src/routes/applications/[id]/logs/index.svelte index 139f9ec21..790961399 100644 --- a/apps/ui/src/routes/applications/[id]/logs/index.svelte +++ b/apps/ui/src/routes/applications/[id]/logs/index.svelte @@ -1,10 +1,8 @@ -{#if template} -
- {#each Object.keys(template.services) as service} +
+
+
Service Logs
+
+
+
+ {#if template} + {#each Object.keys(template) as service} {/each} -
-{/if} + {/if} +
+ {#if selectedService}
{#if logs.length === 0} -
{$t('application.build.waiting_logs')}
+ {#if noContainer} +
Container not found / exited.
+ {/if} {:else}
- + {/if} +
+ - {#if loadLogsInterval} - - {/if}