From 3ffcd8edd9ca75010862d9dbe7393b3bfd8bf1ff Mon Sep 17 00:00:00 2001 From: Dillon Shook Date: Sat, 4 Jan 2025 21:26:35 -0500 Subject: [PATCH 1/3] Goaccess fixes for handling initial state with missing directories --- src/routes/user/system/SystemRouter.ts | 136 ++++++++++++------------- src/user/system/CaptainManager.ts | 3 + 2 files changed, 70 insertions(+), 69 deletions(-) diff --git a/src/routes/user/system/SystemRouter.ts b/src/routes/user/system/SystemRouter.ts index b42cb2493..8dd616eb3 100644 --- a/src/routes/user/system/SystemRouter.ts +++ b/src/routes/user/system/SystemRouter.ts @@ -7,7 +7,6 @@ import BaseApi from '../../../api/BaseApi' import DockerApi from '../../../docker/DockerApi' import DockerUtils from '../../../docker/DockerUtils' import InjectionExtractor from '../../../injection/InjectionExtractor' -import { IAppDef } from '../../../models/AppDefinition' import { AutomatedCleanupConfigsCleaner } from '../../../models/AutomatedCleanupConfigs' import CaptainManager from '../../../user/system/CaptainManager' import VersionManager from '../../../user/system/VersionManager' @@ -360,82 +359,81 @@ router.get('/goaccess/:appName/files', async function (req, res, next) { appName ) - let appDefinition: IAppDef | undefined = undefined + try { + const appDefinition = await dataStore + .getAppsDataStore() + .getAppDefinition(appName) - return Promise.resolve() - .then(function () { - // Ensure a valid appName parameter - return dataStore.getAppsDataStore().getAppDefinition(appName) - }) - .then(function (data) { - appDefinition = data - return fs.readdir(directoryPath) - }) - .then(function (files) { - return Promise.all( - files - // Make sure to only return the generated reports and not folders or the live report - // That will be added back later - .filter( - (f) => f.endsWith('.html') && !f.endsWith('Live.html') - ) - .map((file) => { - return fs - .stat(path.join(directoryPath, file)) - .then(function (fileStats) { - return { - name: file, - time: fileStats.mtime, - } - }) - }) - ) - }) - .then(function (linkData) { - const baseUrl = `/user/system/goaccess/` + let files: string[] = [] - const baseApi = new BaseApi( - ApiStatusCodes.STATUS_OK, - 'GoAccess info retrieved' - ) - const linkList = linkData.map((d) => { - const { domainName, fileName } = - loadBalanceManager.parseLogPath(d.name) - return { - domainName, - name: fileName, - lastModifiedTime: d.time, - url: baseUrl + `${appName}/files/${d.name}`, - } - }) + try { + files = await fs.readdir(directoryPath) + } catch { + Logger.d('No goaccess logs found') + } - // Add in the live report for all sites even if it might not exist yet since they're dynamic - const allDomains = [ - `${appName}.${dataStore.getRootDomain()}`, - ...appDefinition!.customDomain.map((d) => d.publicDomain), - ] - for (const domain of allDomains) { - const name = - loadBalanceManager.getLogName(appName, domain) + - '--Live.html' - linkList.push({ - domainName: domain, - name, - lastModifiedTime: new Date(), - url: baseUrl + `${appName}/files/${name}`, + const linkData = await Promise.all( + files + // Make sure to only return the generated reports and not folders or the live report + // That will be added back later + .filter((f) => f.endsWith('.html') && !f.endsWith('Live.html')) + .map((file) => { + return fs + .stat(path.join(directoryPath, file)) + .then(function (fileStats) { + return { + name: file, + time: fileStats.mtime, + } + }) }) - } + ) + + const baseUrl = `/user/system/goaccess/` - linkList.sort( - (a, b) => - b.lastModifiedTime.getTime() - a.lastModifiedTime.getTime() + const baseApi = new BaseApi( + ApiStatusCodes.STATUS_OK, + 'GoAccess info retrieved' + ) + const linkList = linkData.map((d) => { + const { domainName, fileName } = loadBalanceManager.parseLogPath( + d.name ) + return { + domainName, + name: fileName, + lastModifiedTime: d.time, + url: baseUrl + `${appName}/files/${d.name}`, + } + }) - baseApi.data = linkList + // Add in the live report for all sites even if it might not exist yet since they're dynamic + const allDomains = [ + `${appName}.${dataStore.getRootDomain()}`, + ...appDefinition!.customDomain.map((d) => d.publicDomain), + ] + for (const domain of allDomains) { + const name = + loadBalanceManager.getLogName(appName, domain) + '--Live.html' + linkList.push({ + domainName: domain, + name, + lastModifiedTime: new Date(), + url: baseUrl + `${appName}/files/${name}`, + }) + } - res.send(baseApi) - }) - .catch(ApiStatusCodes.createCatcher(res)) + linkList.sort( + (a, b) => + b.lastModifiedTime.getTime() - a.lastModifiedTime.getTime() + ) + + baseApi.data = linkList + + res.send(baseApi) + } catch (e) { + ApiStatusCodes.createCatcher(res)(e) + } }) router.get('/goaccess/:appName/files/:file', async function (req, res, next) { diff --git a/src/user/system/CaptainManager.ts b/src/user/system/CaptainManager.ts index 244615ec8..a2053b846 100644 --- a/src/user/system/CaptainManager.ts +++ b/src/user/system/CaptainManager.ts @@ -145,6 +145,9 @@ class CaptainManager { .then(function () { return fs.ensureFile(CaptainConstants.baseNginxConfigPath) }) + .then(function () { + return fs.ensureDir(CaptainConstants.nginxSharedLogsPathOnHost) + }) .then(function () { return fs.ensureDir(CaptainConstants.registryPathOnHost) }) From 22e8074bfc947c5182015e0f6e3f507d4402deda Mon Sep 17 00:00:00 2001 From: Dillon Shook Date: Sun, 5 Jan 2025 09:59:23 -0500 Subject: [PATCH 2/3] Undo refactor --- src/routes/user/system/SystemRouter.ts | 139 +++++++++++++------------ 1 file changed, 72 insertions(+), 67 deletions(-) diff --git a/src/routes/user/system/SystemRouter.ts b/src/routes/user/system/SystemRouter.ts index 8dd616eb3..d9dd4a882 100644 --- a/src/routes/user/system/SystemRouter.ts +++ b/src/routes/user/system/SystemRouter.ts @@ -7,6 +7,7 @@ import BaseApi from '../../../api/BaseApi' import DockerApi from '../../../docker/DockerApi' import DockerUtils from '../../../docker/DockerUtils' import InjectionExtractor from '../../../injection/InjectionExtractor' +import { IAppDef } from '../../../models/AppDefinition' import { AutomatedCleanupConfigsCleaner } from '../../../models/AutomatedCleanupConfigs' import CaptainManager from '../../../user/system/CaptainManager' import VersionManager from '../../../user/system/VersionManager' @@ -359,81 +360,85 @@ router.get('/goaccess/:appName/files', async function (req, res, next) { appName ) - try { - const appDefinition = await dataStore - .getAppsDataStore() - .getAppDefinition(appName) + let appDefinition: IAppDef | undefined = undefined - let files: string[] = [] - - try { - files = await fs.readdir(directoryPath) - } catch { - Logger.d('No goaccess logs found') - } - - const linkData = await Promise.all( - files - // Make sure to only return the generated reports and not folders or the live report - // That will be added back later - .filter((f) => f.endsWith('.html') && !f.endsWith('Live.html')) - .map((file) => { - return fs - .stat(path.join(directoryPath, file)) - .then(function (fileStats) { - return { - name: file, - time: fileStats.mtime, - } - }) - }) - ) - - const baseUrl = `/user/system/goaccess/` - - const baseApi = new BaseApi( - ApiStatusCodes.STATUS_OK, - 'GoAccess info retrieved' - ) - const linkList = linkData.map((d) => { - const { domainName, fileName } = loadBalanceManager.parseLogPath( - d.name + return Promise.resolve() + .then(function () { + // Ensure a valid appName parameter + return dataStore.getAppsDataStore().getAppDefinition(appName) + }) + .then(function (data) { + appDefinition = data + return fs.readdir(directoryPath).catch((e) => { + Logger.d('No goaccess logs found') + return [] + }) + }) + .then(function (files) { + return Promise.all( + files + // Make sure to only return the generated reports and not folders or the live report + // That will be added back later + .filter( + (f) => f.endsWith('.html') && !f.endsWith('Live.html') + ) + .map((file) => { + return fs + .stat(path.join(directoryPath, file)) + .then(function (fileStats) { + return { + name: file, + time: fileStats.mtime, + } + }) + }) ) - return { - domainName, - name: fileName, - lastModifiedTime: d.time, - url: baseUrl + `${appName}/files/${d.name}`, - } }) + .then(function (linkData) { + const baseUrl = `/user/system/goaccess/` - // Add in the live report for all sites even if it might not exist yet since they're dynamic - const allDomains = [ - `${appName}.${dataStore.getRootDomain()}`, - ...appDefinition!.customDomain.map((d) => d.publicDomain), - ] - for (const domain of allDomains) { - const name = - loadBalanceManager.getLogName(appName, domain) + '--Live.html' - linkList.push({ - domainName: domain, - name, - lastModifiedTime: new Date(), - url: baseUrl + `${appName}/files/${name}`, + const baseApi = new BaseApi( + ApiStatusCodes.STATUS_OK, + 'GoAccess info retrieved' + ) + const linkList = linkData.map((d) => { + const { domainName, fileName } = + loadBalanceManager.parseLogPath(d.name) + return { + domainName, + name: fileName, + lastModifiedTime: d.time, + url: baseUrl + `${appName}/files/${d.name}`, + } }) - } - linkList.sort( - (a, b) => - b.lastModifiedTime.getTime() - a.lastModifiedTime.getTime() - ) + // Add in the live report for all sites even if it might not exist yet since they're dynamic + const allDomains = [ + `${appName}.${dataStore.getRootDomain()}`, + ...appDefinition!.customDomain.map((d) => d.publicDomain), + ] + for (const domain of allDomains) { + const name = + loadBalanceManager.getLogName(appName, domain) + + '--Live.html' + linkList.push({ + domainName: domain, + name, + lastModifiedTime: new Date(), + url: baseUrl + `${appName}/files/${name}`, + }) + } - baseApi.data = linkList + linkList.sort( + (a, b) => + b.lastModifiedTime.getTime() - a.lastModifiedTime.getTime() + ) - res.send(baseApi) - } catch (e) { - ApiStatusCodes.createCatcher(res)(e) - } + baseApi.data = linkList + + res.send(baseApi) + }) + .catch((e) => ApiStatusCodes.createCatcher(res)(e)) }) router.get('/goaccess/:appName/files/:file', async function (req, res, next) { From ce0911efffdeabe801699562f389d320a47d8154 Mon Sep 17 00:00:00 2001 From: Dillon Shook Date: Sun, 5 Jan 2025 10:00:21 -0500 Subject: [PATCH 3/3] Don't need to call it actually --- src/routes/user/system/SystemRouter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/user/system/SystemRouter.ts b/src/routes/user/system/SystemRouter.ts index d9dd4a882..3f1a1179a 100644 --- a/src/routes/user/system/SystemRouter.ts +++ b/src/routes/user/system/SystemRouter.ts @@ -438,7 +438,7 @@ router.get('/goaccess/:appName/files', async function (req, res, next) { res.send(baseApi) }) - .catch((e) => ApiStatusCodes.createCatcher(res)(e)) + .catch(ApiStatusCodes.createCatcher(res)) }) router.get('/goaccess/:appName/files/:file', async function (req, res, next) {