diff --git a/.gitignore b/.gitignore index cb934cd76..500cd6776 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ dist client apps/api/db/*.db local-serve -apps/api/db/migration.db-journal \ No newline at end of file +apps/api/db/migration.db-journal +apps/api/core* \ No newline at end of file diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index dac8d34ef..00865adca 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -161,7 +161,7 @@ async function initServer() { } catch (error) { } try { const isOlder = compareVersions('3.8.1', version); - if (isOlder === -1) { + if (isOlder === 1) { await prisma.build.updateMany({ where: { status: { in: ['running', 'queued'] } }, data: { status: 'failed' } }); } } catch (error) { } diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index bb65fb77d..dc3b0d41d 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -4,7 +4,7 @@ import fs from 'fs/promises'; import yaml from 'js-yaml'; import { copyBaseConfigurationFiles, makeLabelForStandaloneApplication, saveBuildLog, setDefaultConfiguration } from '../lib/buildPacks/common'; -import { createDirectories, decrypt, defaultComposeConfiguration, executeDockerCmd, getDomain, prisma } from '../lib/common'; +import { createDirectories, decrypt, defaultComposeConfiguration, executeDockerCmd, getDomain, prisma, decryptApplication } from '../lib/common'; import * as importers from '../lib/importers'; import * as buildpacks from '../lib/buildPacks'; @@ -27,7 +27,7 @@ import * as buildpacks from '../lib/buildPacks'; const th = throttle(async () => { try { - const queuedBuilds = await prisma.build.findMany({ where: { status: 'queued' }, orderBy: { createdAt: 'asc' } }); + const queuedBuilds = await prisma.build.findMany({ where: { status: { in: ['queued', 'running'] } }, orderBy: { createdAt: 'asc' } }); const { concurrentBuilds } = await prisma.setting.findFirst({}) if (queuedBuilds.length > 0) { parentPort.postMessage({ deploying: true }); @@ -37,68 +37,72 @@ import * as buildpacks from '../lib/buildPacks'; for (const queueBuild of queuedBuilds) { actions.push(async () => { - const application = await prisma.application.findUnique({ where: { id: queueBuild.applicationId }, include: { destinationDocker: true, gitSource: { include: { githubApp: true, gitlabApp: true } }, persistentStorage: true, secrets: true, settings: true, teams: true } }) - const { id: buildId, type, sourceBranch = null, pullmergeRequestId = null, forceRebuild } = queueBuild - const { - id: applicationId, - repository, - name, - destinationDocker, - destinationDockerId, - gitSource, - configHash, - fqdn, - projectId, - secrets, - phpModules, - settings, - persistentStorage, - pythonWSGI, - pythonModule, - pythonVariable, - denoOptions, - exposePort, - baseImage, - baseBuildImage, - deploymentType, - } = application - let { - branch, - buildPack, - port, - installCommand, - buildCommand, - startCommand, - baseDirectory, - publishDirectory, - dockerFileLocation, - denoMainFile - } = application - const currentHash = crypto - .createHash('sha256') - .update( - JSON.stringify({ - pythonWSGI, - pythonModule, - pythonVariable, - deploymentType, - denoOptions, - baseImage, - baseBuildImage, - buildPack, - port, - exposePort, - installCommand, - buildCommand, - startCommand, - secrets, - branch, - repository, - fqdn - }) - ) - .digest('hex'); + let application = await prisma.application.findUnique({ where: { id: queueBuild.applicationId }, include: { destinationDocker: true, gitSource: { include: { githubApp: true, gitlabApp: true } }, persistentStorage: true, secrets: true, settings: true, teams: true } }) + let { id: buildId, type, sourceBranch = null, pullmergeRequestId = null, forceRebuild } = queueBuild + application = decryptApplication(application) try { + if (queueBuild.status === 'running') { + await saveBuildLog({ line: 'Building halted, restarting...', buildId, applicationId: application.id }); + } + const { + id: applicationId, + repository, + name, + destinationDocker, + destinationDockerId, + gitSource, + configHash, + fqdn, + projectId, + secrets, + phpModules, + settings, + persistentStorage, + pythonWSGI, + pythonModule, + pythonVariable, + denoOptions, + exposePort, + baseImage, + baseBuildImage, + deploymentType, + } = application + let { + branch, + buildPack, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory, + dockerFileLocation, + denoMainFile + } = application + const currentHash = crypto + .createHash('sha256') + .update( + JSON.stringify({ + pythonWSGI, + pythonModule, + pythonVariable, + deploymentType, + denoOptions, + baseImage, + baseBuildImage, + buildPack, + port, + exposePort, + installCommand, + buildCommand, + startCommand, + secrets, + branch, + repository, + fqdn + }) + ) + .digest('hex'); const { debug } = settings; if (concurrency === 1) { await prisma.build.updateMany({ @@ -258,7 +262,6 @@ import * as buildpacks from '../lib/buildPacks'; ]; if (secrets.length > 0) { secrets.forEach((secret) => { - secret.value = decrypt(secret.value) if (pullmergeRequestId) { if (secret.isPRMRSecret) { envs.push(`${secret.name}=${secret.value}`); @@ -353,13 +356,16 @@ import * as buildpacks from '../lib/buildPacks'; where: { id: buildId, status: { in: ['queued', 'running'] } }, data: { status: 'failed' } }); - await saveBuildLog({ line: error, buildId, applicationId }); + await saveBuildLog({ line: error, buildId, applicationId: application.id }); } }); + } + await pAll.default(actions, { concurrency }) } } catch (error) { + console.log(error) } finally { } }) diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index e73093d08..d6e30aa03 100644 --- a/apps/api/src/lib/common.ts +++ b/apps/api/src/lib/common.ts @@ -19,7 +19,7 @@ import * as serviceFields from './serviceFields' import { saveBuildLog } from './buildPacks/common'; import { scheduler } from './scheduler'; -export const version = '3.8.3'; +export const version = '3.8.4'; export const isDev = process.env.NODE_ENV === 'development'; const algorithm = 'aes-256-ctr'; @@ -1977,6 +1977,12 @@ export async function cleanupDockerStorage(dockerId, lowDiskSpace, force) { } catch (error) { //console.log(error); } + // Cleanup build caches + try { + await executeDockerCmd({ dockerId, command: `docker builder prune -a -f` }) + } catch (error) { + //console.log(error); + } } } @@ -2022,3 +2028,27 @@ export function defaultComposeConfiguration(network: string): any { } } } +export function decryptApplication(application: any) { + if (application) { + if (application?.gitSource?.githubApp?.clientSecret) { + application.gitSource.githubApp.clientSecret = decrypt(application.gitSource.githubApp.clientSecret) || null; + } + if (application?.gitSource?.githubApp?.webhookSecret) { + application.gitSource.githubApp.webhookSecret = decrypt(application.gitSource.githubApp.webhookSecret) || null; + } + if (application?.gitSource?.githubApp?.privateKey) { + application.gitSource.githubApp.privateKey = decrypt(application.gitSource.githubApp.privateKey) || null; + } + if (application?.gitSource?.gitlabApp?.appSecret) { + application.gitSource.gitlabApp.appSecret = decrypt(application.gitSource.gitlabApp.appSecret) || null; + } + if (application?.secrets.length > 0) { + application.secrets = application.secrets.map((s: any) => { + s.value = decrypt(s.value) || null + return s; + }); + } + + return application; + } +} \ No newline at end of file diff --git a/apps/api/src/routes/api/v1/applications/handlers.ts b/apps/api/src/routes/api/v1/applications/handlers.ts index 26b0d2bb9..cb0bf38fe 100644 --- a/apps/api/src/routes/api/v1/applications/handlers.ts +++ b/apps/api/src/routes/api/v1/applications/handlers.ts @@ -451,6 +451,7 @@ export async function deployApplication(request: FastifyRequest, reply: FastifyRep }); const team = await prisma.team.findUnique({ where: { id }, include: { permissions: true } }); const invitations = await prisma.teamInvitation.findMany({ where: { teamId: team.id } }); + const { teams } = await prisma.user.findUnique({ where: { id: userId }, include: { teams: true } }) return { + currentTeam: teamId, team, + teams, permissions, invitations }; @@ -275,10 +278,10 @@ export async function inviteToTeam(request: FastifyRequest, reply: if (!userFound) { throw { message: `No user found with '${email}' email address.` - }; + }; } const uid = userFound.id; - if (uid === userId) { + if (uid === userId) { throw { message: `Invitation to yourself? Whaaaaat?` }; diff --git a/apps/api/src/routes/api/v1/sources/handlers.ts b/apps/api/src/routes/api/v1/sources/handlers.ts index 8a1c19987..f363b6ff9 100644 --- a/apps/api/src/routes/api/v1/sources/handlers.ts +++ b/apps/api/src/routes/api/v1/sources/handlers.ts @@ -9,7 +9,7 @@ export async function listSources(request: FastifyRequest) { try { const teamId = request.user?.teamId; const sources = await prisma.gitSource.findMany({ - where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } }, + where: { teams: { some: { id: teamId === '0' ? undefined : teamId } }, githubApp: { gitSource: { forPublic: false } } }, include: { teams: true, githubApp: true, gitlabApp: true } }); return { diff --git a/apps/api/src/routes/webhooks/github/handlers.ts b/apps/api/src/routes/webhooks/github/handlers.ts index 275a72979..106311c5c 100644 --- a/apps/api/src/routes/webhooks/github/handlers.ts +++ b/apps/api/src/routes/webhooks/github/handlers.ts @@ -146,7 +146,7 @@ export async function gitHubEvents(request: FastifyRequest): Promi message: 'Queued. Thank you!' }; } else if (githubEvent === 'pull_request') { - const pullmergeRequestId = body.number; + const pullmergeRequestId = body.number.toString(); const pullmergeRequestAction = body.action; const sourceBranch = body.pull_request.head.ref.includes('/') ? body.pull_request.head.ref.split('/')[2] : body.pull_request.head.ref; if (!allowedActions.includes(pullmergeRequestAction)) { diff --git a/apps/ui/src/lib/components/Usage.svelte b/apps/ui/src/lib/components/Usage.svelte index a461f8419..0e7630370 100644 --- a/apps/ui/src/lib/components/Usage.svelte +++ b/apps/ui/src/lib/components/Usage.svelte @@ -86,8 +86,8 @@
-

Hardware Details

-
+

Hardware Details

+
{#if $appSession.teamId === '0'}
-
-
-
Memory
+
+
-
Total
+
Total Memory
{(usage?.memory.totalMemMb).toFixed(0)}MB
-
Used
+
Used Memory
{(usage?.memory.usedMemMb).toFixed(0)}MB
-
Free
+
Free Memory
{usage?.memory.freeMemPercentage}%
-
-
CPU
+
+
-
Total
+
Total CPU
{usage?.cpu.count}
-
Usage
+
CPU Usage
{usage?.cpu.usage}%
@@ -147,24 +146,23 @@
{usage?.cpu.load}
-
-
Disk
+
-
Total
+
Total Disk
{usage?.disk.totalGb}GB
-
Used
+
Used Disk
{usage?.disk.usedGb}GB
-
Free
+
Free Disk
{usage?.disk.freePercentage}%
diff --git a/apps/ui/src/lib/components/svg/applications/Docker.svelte b/apps/ui/src/lib/components/svg/applications/Docker.svelte index ea1787bd9..74ba0ebf0 100644 --- a/apps/ui/src/lib/components/svg/applications/Docker.svelte +++ b/apps/ui/src/lib/components/svg/applications/Docker.svelte @@ -3,7 +3,7 @@ - + diff --git a/apps/ui/src/lib/components/svg/services/Ghost.svelte b/apps/ui/src/lib/components/svg/services/Ghost.svelte index 567ab69bc..d01ab2e3f 100644 --- a/apps/ui/src/lib/components/svg/services/Ghost.svelte +++ b/apps/ui/src/lib/components/svg/services/Ghost.svelte @@ -4,6 +4,6 @@ ghost logo diff --git a/apps/ui/src/lib/components/svg/services/Hasura.svelte b/apps/ui/src/lib/components/svg/services/Hasura.svelte index aaac145ca..51a427ccd 100644 --- a/apps/ui/src/lib/components/svg/services/Hasura.svelte +++ b/apps/ui/src/lib/components/svg/services/Hasura.svelte @@ -3,7 +3,7 @@ diff --git a/apps/ui/src/lib/components/svg/services/Moodle.svelte b/apps/ui/src/lib/components/svg/services/Moodle.svelte index ad8aec880..a52ddc6f7 100644 --- a/apps/ui/src/lib/components/svg/services/Moodle.svelte +++ b/apps/ui/src/lib/components/svg/services/Moodle.svelte @@ -3,6 +3,6 @@ moodle logo diff --git a/apps/ui/src/lib/components/svg/services/N8n.svelte b/apps/ui/src/lib/components/svg/services/N8n.svelte index 04b2e8216..da7ab2b88 100644 --- a/apps/ui/src/lib/components/svg/services/N8n.svelte +++ b/apps/ui/src/lib/components/svg/services/N8n.svelte @@ -3,7 +3,7 @@ diff --git a/apps/ui/src/lib/components/svg/services/NocoDB.svelte b/apps/ui/src/lib/components/svg/services/NocoDB.svelte index ba93c4f78..fcaac6a96 100644 --- a/apps/ui/src/lib/components/svg/services/NocoDB.svelte +++ b/apps/ui/src/lib/components/svg/services/NocoDB.svelte @@ -4,6 +4,6 @@ nocodb logo diff --git a/apps/ui/src/lib/components/svg/services/Umami.svelte b/apps/ui/src/lib/components/svg/services/Umami.svelte index e1c9b1e67..7faeca3fb 100644 --- a/apps/ui/src/lib/components/svg/services/Umami.svelte +++ b/apps/ui/src/lib/components/svg/services/Umami.svelte @@ -7,7 +7,7 @@ xmlns="http://www.w3.org/2000/svg" viewBox="0 0 856.000000 856.000000" preserveAspectRatio="xMidYMid meet" - class={isAbsolute ? 'w-10 h-10 absolute top-0 left-0 -m-5' : 'w-8 mx-auto'} + class={isAbsolute ? 'w-10 h-10 absolute top-0 left-0 -m-5' : 'w-8 h-8 mx-auto'} > Created by potrace 1.11, written by Peter Selinger 2001-2013 - +
{$t('index.dashboard')}
-