From 54a09958d5529ecba74f775c3c78d3842757bb36 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 24 Aug 2022 11:16:49 +0200 Subject: [PATCH 01/32] fix: never stop deplyo queue --- apps/api/src/lib/scheduler.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/api/src/lib/scheduler.ts b/apps/api/src/lib/scheduler.ts index 5d8a57844..ad2dde568 100644 --- a/apps/api/src/lib/scheduler.ts +++ b/apps/api/src/lib/scheduler.ts @@ -15,7 +15,6 @@ const options: any = { if (message.pending === 0 && message.size === 0) { if (message.caller === 'autoUpdater') { if (!scheduler.workers.has('autoUpdater')) { - await scheduler.stop('deployApplication'); await scheduler.run('autoUpdater') } } From f379519d40e3a63ea72b9ca2263bfb3c099f0ede Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 24 Aug 2022 14:50:34 +0200 Subject: [PATCH 02/32] chore: version++ --- apps/api/src/lib/common.ts | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index e77dc995c..bb920b7ed 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.1'; +export const version = '3.8.2'; export const isDev = process.env.NODE_ENV === 'development'; const algorithm = 'aes-256-ctr'; diff --git a/package.json b/package.json index 9d6fd9250..d3f808b2b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "coolify", "description": "An open-source & self-hostable Heroku / Netlify alternative.", - "version": "3.8.1", + "version": "3.8.2", "license": "Apache-2.0", "repository": "github:coollabsio/coolify", "scripts": { From 01e71958b28a03ee5e5342381733f12f874d9bd9 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 10:04:46 +0200 Subject: [PATCH 03/32] fix: build queue system --- apps/api/package.json | 10 +- .../migration.sql | 29 + .../migration.sql | 24 + apps/api/prisma/schema.prisma | 4 + apps/api/src/index.ts | 31 +- apps/api/src/jobs/cleanupStorage.ts | 4 +- apps/api/src/jobs/deployApplication-old.ts | 366 +++++++++ apps/api/src/jobs/deployApplication.ts | 694 +++++++++--------- apps/api/src/lib/buildPacks/common.ts | 2 +- apps/api/src/lib/common.ts | 17 +- apps/api/src/lib/scheduler.ts | 20 +- .../routes/api/v1/applications/handlers.ts | 21 +- .../src/routes/webhooks/github/handlers.ts | 17 +- .../src/routes/webhooks/gitlab/handlers.ts | 16 +- apps/ui/package.json | 12 +- .../routes/applications/[id]/__layout.svelte | 13 +- .../applications/[id]/logs/build.svelte | 2 +- pnpm-lock.yaml | 386 +++------- 18 files changed, 915 insertions(+), 753 deletions(-) create mode 100644 apps/api/prisma/migrations/20220825064811_concurrent_build_settings/migration.sql create mode 100644 apps/api/prisma/migrations/20220825072007_build_queue_improvements/migration.sql create mode 100644 apps/api/src/jobs/deployApplication-old.ts diff --git a/apps/api/package.json b/apps/api/package.json index b5dcb5823..f9766c5b5 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -27,7 +27,7 @@ "bcryptjs": "2.4.3", "bree": "9.1.2", "cabin": "9.1.2", - "compare-versions": "4.1.3", + "compare-versions": "4.1.4", "cuid": "2.1.8", "dayjs": "1.11.5", "dockerode": "3.3.4", @@ -43,17 +43,17 @@ "jsonwebtoken": "8.5.1", "node-forge": "1.3.1", "node-os-utils": "1.3.7", - "p-queue": "7.3.0", + "p-all": "4.0.0", "public-ip": "6.0.1", "ssh-config": "4.1.6", "strip-ansi": "7.0.1", "unique-names-generator": "4.7.1" }, "devDependencies": { - "@types/node": "18.7.11", + "@types/node": "18.7.13", "@types/node-os-utils": "1.3.0", - "@typescript-eslint/eslint-plugin": "5.34.0", - "@typescript-eslint/parser": "5.34.0", + "@typescript-eslint/eslint-plugin": "5.35.1", + "@typescript-eslint/parser": "5.35.1", "esbuild": "0.15.5", "eslint": "8.22.0", "eslint-config-prettier": "8.5.0", diff --git a/apps/api/prisma/migrations/20220825064811_concurrent_build_settings/migration.sql b/apps/api/prisma/migrations/20220825064811_concurrent_build_settings/migration.sql new file mode 100644 index 000000000..1535c2bf7 --- /dev/null +++ b/apps/api/prisma/migrations/20220825064811_concurrent_build_settings/migration.sql @@ -0,0 +1,29 @@ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Setting" ( + "id" TEXT NOT NULL PRIMARY KEY, + "fqdn" TEXT, + "isRegistrationEnabled" BOOLEAN NOT NULL DEFAULT false, + "dualCerts" BOOLEAN NOT NULL DEFAULT false, + "minPort" INTEGER NOT NULL DEFAULT 9000, + "maxPort" INTEGER NOT NULL DEFAULT 9100, + "proxyPassword" TEXT NOT NULL, + "proxyUser" TEXT NOT NULL, + "proxyHash" TEXT, + "isAutoUpdateEnabled" BOOLEAN NOT NULL DEFAULT false, + "isDNSCheckEnabled" BOOLEAN NOT NULL DEFAULT true, + "DNSServers" TEXT, + "isTraefikUsed" BOOLEAN NOT NULL DEFAULT true, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + "ipv4" TEXT, + "ipv6" TEXT, + "arch" TEXT, + "concurrentBuilds" INTEGER NOT NULL DEFAULT 1 +); +INSERT INTO "new_Setting" ("DNSServers", "arch", "createdAt", "dualCerts", "fqdn", "id", "ipv4", "ipv6", "isAutoUpdateEnabled", "isDNSCheckEnabled", "isRegistrationEnabled", "isTraefikUsed", "maxPort", "minPort", "proxyHash", "proxyPassword", "proxyUser", "updatedAt") SELECT "DNSServers", "arch", "createdAt", "dualCerts", "fqdn", "id", "ipv4", "ipv6", "isAutoUpdateEnabled", "isDNSCheckEnabled", "isRegistrationEnabled", "isTraefikUsed", "maxPort", "minPort", "proxyHash", "proxyPassword", "proxyUser", "updatedAt" FROM "Setting"; +DROP TABLE "Setting"; +ALTER TABLE "new_Setting" RENAME TO "Setting"; +CREATE UNIQUE INDEX "Setting_fqdn_key" ON "Setting"("fqdn"); +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON; diff --git a/apps/api/prisma/migrations/20220825072007_build_queue_improvements/migration.sql b/apps/api/prisma/migrations/20220825072007_build_queue_improvements/migration.sql new file mode 100644 index 000000000..78c51fc15 --- /dev/null +++ b/apps/api/prisma/migrations/20220825072007_build_queue_improvements/migration.sql @@ -0,0 +1,24 @@ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Build" ( + "id" TEXT NOT NULL PRIMARY KEY, + "type" TEXT NOT NULL, + "applicationId" TEXT, + "destinationDockerId" TEXT, + "gitSourceId" TEXT, + "githubAppId" TEXT, + "gitlabAppId" TEXT, + "commit" TEXT, + "pullmergeRequestId" TEXT, + "forceRebuild" BOOLEAN NOT NULL DEFAULT false, + "sourceBranch" TEXT, + "branch" TEXT, + "status" TEXT DEFAULT 'queued', + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL +); +INSERT INTO "new_Build" ("applicationId", "branch", "commit", "createdAt", "destinationDockerId", "gitSourceId", "githubAppId", "gitlabAppId", "id", "status", "type", "updatedAt") SELECT "applicationId", "branch", "commit", "createdAt", "destinationDockerId", "gitSourceId", "githubAppId", "gitlabAppId", "id", "status", "type", "updatedAt" FROM "Build"; +DROP TABLE "Build"; +ALTER TABLE "new_Build" RENAME TO "Build"; +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON; diff --git a/apps/api/prisma/schema.prisma b/apps/api/prisma/schema.prisma index 02440300b..dfa7ae26b 100644 --- a/apps/api/prisma/schema.prisma +++ b/apps/api/prisma/schema.prisma @@ -27,6 +27,7 @@ model Setting { ipv4 String? ipv6 String? arch String? + concurrentBuilds Int @default(1) } model User { @@ -197,6 +198,9 @@ model Build { githubAppId String? gitlabAppId String? commit String? + pullmergeRequestId String? + forceRebuild Boolean @default(false) + sourceBranch String? branch String? status String? @default("queued") createdAt DateTime @default(now()) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 18864dd6e..3f4876c94 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -5,7 +5,7 @@ import env from '@fastify/env'; import cookie from '@fastify/cookie'; import path, { join } from 'path'; import autoLoad from '@fastify/autoload'; -import { asyncExecShell, isDev, listSettings, prisma, version } from './lib/common'; +import { asyncExecShell, asyncSleep, isDev, listSettings, prisma, version } from './lib/common'; import { scheduler } from './lib/scheduler'; import axios from 'axios'; import compareVersions from 'compare-versions'; @@ -104,14 +104,16 @@ fastify.listen({ port, host }, async (err: any, address: any) => { } console.log(`Coolify's API is listening on ${host}:${port}`); await initServer(); - await scheduler.start('deployApplication'); - await scheduler.start('cleanupStorage'); await scheduler.start('cleanupPrismaEngines'); await scheduler.start('checkProxies'); - // Check if no build is running + setInterval(async () => { + if (!scheduler.workers.has('deployApplication')) { + scheduler.run('deployApplication'); + } + }, 2000) - // Check for update + // Check for update & if no build is running setInterval(async () => { const { isAutoUpdateEnabled } = await prisma.setting.findFirst(); if (isAutoUpdateEnabled) { @@ -128,8 +130,8 @@ fastify.listen({ port, host }, async (err: any, address: any) => { const latestVersion = versions['coolify'].main.version; const isUpdateAvailable = compareVersions(latestVersion, currentVersion); if (isUpdateAvailable === 1) { - if (scheduler.workers.has('deployApplication')) { - scheduler.workers.get('deployApplication').postMessage("status:autoUpdater"); + if (!scheduler.workers.has('deployApplication')) { + await scheduler.run('autoUpdater') } } } @@ -137,16 +139,11 @@ fastify.listen({ port, host }, async (err: any, address: any) => { // Cleanup storage setInterval(async () => { - if (scheduler.workers.has('deployApplication')) { - scheduler.workers.get('deployApplication').postMessage("status:cleanupStorage"); + if (!scheduler.workers.has('deployApplication') && !scheduler.workers.has('cleanupStorage')) { + await scheduler.run('cleanupStorage') } }, isDev ? 5000 : 60000 * 10) - scheduler.on('worker deleted', async (name) => { - if (name === 'autoUpdater' || name === 'cleanupStorage') { - if (!scheduler.workers.has('deployApplication')) await scheduler.start('deployApplication'); - } - }); await getArch(); await getIPAddress(); }); @@ -170,6 +167,12 @@ async function initServer() { try { await asyncExecShell(`docker network create --attachable coolify`); } catch (error) { } + try { + const isOlder = compareVersions('3.8.1', version); + if (isOlder === -1) { + await prisma.build.updateMany({ where: { status: { in: ['running', 'queued'] } }, data: { status: 'failed' } }); + } + } catch (error) { } } async function getArch() { try { diff --git a/apps/api/src/jobs/cleanupStorage.ts b/apps/api/src/jobs/cleanupStorage.ts index 97683ac2d..4740c1df8 100644 --- a/apps/api/src/jobs/cleanupStorage.ts +++ b/apps/api/src/jobs/cleanupStorage.ts @@ -1,5 +1,5 @@ import { parentPort } from 'node:worker_threads'; -import { asyncExecShell, cleanupDockerStorage, executeDockerCmd, isDev, prisma, version } from '../lib/common'; +import { asyncExecShell, cleanupDockerStorage, executeDockerCmd, isDev, prisma } from '../lib/common'; (async () => { if (parentPort) { @@ -9,7 +9,7 @@ import { asyncExecShell, cleanupDockerStorage, executeDockerCmd, isDev, prisma, if (enginesDone.has(destination.engine) || enginesDone.has(destination.remoteIpAddress)) return if (destination.engine) enginesDone.add(destination.engine) if (destination.remoteIpAddress) enginesDone.add(destination.remoteIpAddress) - + let lowDiskSpace = false; try { let stdout = null diff --git a/apps/api/src/jobs/deployApplication-old.ts b/apps/api/src/jobs/deployApplication-old.ts new file mode 100644 index 000000000..93d358fe3 --- /dev/null +++ b/apps/api/src/jobs/deployApplication-old.ts @@ -0,0 +1,366 @@ +import { parentPort } from 'node:worker_threads'; +import crypto from 'crypto'; +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 * as importers from '../lib/importers'; +import * as buildpacks from '../lib/buildPacks'; + +(async () => { + if (parentPort) { + const concurrency = 1 + const PQueue = await import('p-queue'); + const queue = new PQueue.default({ concurrency }); + parentPort.on('message', async (message) => { + if (parentPort) { + if (message === 'error') throw new Error('oops'); + if (message === 'cancel') { + parentPort.postMessage('cancelled'); + return; + } + if (message === 'status:autoUpdater') { + parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'autoUpdater' }); + return; + } + if (message === 'status:cleanupStorage') { + parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'cleanupStorage' }); + return; + } + if (message === 'action:flushQueue') { + queue.clear() + return; + } + + await queue.add(async () => { + const { + id: applicationId, + repository, + name, + destinationDocker, + destinationDockerId, + gitSource, + build_id: buildId, + configHash, + fqdn, + projectId, + secrets, + phpModules, + type, + pullmergeRequestId = null, + sourceBranch = null, + settings, + persistentStorage, + pythonWSGI, + pythonModule, + pythonVariable, + denoOptions, + exposePort, + baseImage, + baseBuildImage, + deploymentType, + forceRebuild + } = message + let { + branch, + buildPack, + port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory, + dockerFileLocation, + denoMainFile + } = message + 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'); + try { + const { debug } = settings; + if (concurrency === 1) { + await prisma.build.updateMany({ + where: { + status: { in: ['queued', 'running'] }, + id: { not: buildId }, + applicationId, + createdAt: { lt: new Date(new Date().getTime() - 10 * 1000) } + }, + data: { status: 'failed' } + }); + } + let imageId = applicationId; + let domain = getDomain(fqdn); + const volumes = + persistentStorage?.map((storage) => { + return `${applicationId}${storage.path.replace(/\//gi, '-')}:${buildPack !== 'docker' ? '/app' : '' + }${storage.path}`; + }) || []; + // Previews, we need to get the source branch and set subdomain + if (pullmergeRequestId) { + branch = sourceBranch; + domain = `${pullmergeRequestId}.${domain}`; + imageId = `${applicationId}-${pullmergeRequestId}`; + } + + let deployNeeded = true; + let destinationType; + + if (destinationDockerId) { + destinationType = 'docker'; + } + if (destinationType === 'docker') { + await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } }); + const { workdir, repodir } = await createDirectories({ repository, buildId }); + const configuration = await setDefaultConfiguration(message); + + buildPack = configuration.buildPack; + port = configuration.port; + installCommand = configuration.installCommand; + startCommand = configuration.startCommand; + buildCommand = configuration.buildCommand; + publishDirectory = configuration.publishDirectory; + baseDirectory = configuration.baseDirectory; + dockerFileLocation = configuration.dockerFileLocation; + denoMainFile = configuration.denoMainFile; + const commit = await importers[gitSource.type]({ + applicationId, + debug, + workdir, + repodir, + githubAppId: gitSource.githubApp?.id, + gitlabAppId: gitSource.gitlabApp?.id, + customPort: gitSource.customPort, + repository, + branch, + buildId, + apiUrl: gitSource.apiUrl, + htmlUrl: gitSource.htmlUrl, + projectId, + deployKeyId: gitSource.gitlabApp?.deployKeyId || null, + privateSshKey: decrypt(gitSource.gitlabApp?.privateSshKey) || null, + forPublic: gitSource.forPublic + }); + if (!commit) { + throw new Error('No commit found?'); + } + let tag = commit.slice(0, 7); + if (pullmergeRequestId) { + tag = `${commit.slice(0, 7)}-${pullmergeRequestId}`; + } + + try { + await prisma.build.update({ where: { id: buildId }, data: { commit } }); + } catch (err) { + console.log(err); + } + + if (!pullmergeRequestId) { + + if (configHash !== currentHash) { + deployNeeded = true; + if (configHash) { + await saveBuildLog({ line: 'Configuration changed.', buildId, applicationId }); + } + } else { + deployNeeded = false; + } + } else { + deployNeeded = true; + } + + let imageFound = false; + try { + await executeDockerCmd({ + dockerId: destinationDocker.id, + command: `docker image inspect ${applicationId}:${tag}` + }) + imageFound = true; + } catch (error) { + // + } + await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage); + + if (forceRebuild) deployNeeded = true + if (!imageFound || deployNeeded) { + // if (true) { + if (buildpacks[buildPack]) + await buildpacks[buildPack]({ + dockerId: destinationDocker.id, + buildId, + applicationId, + domain, + name, + type, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + publishDirectory, + debug, + commit, + tag, + workdir, + port: exposePort ? `${exposePort}:${port}` : port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + phpModules, + pythonWSGI, + pythonModule, + pythonVariable, + dockerFileLocation, + denoMainFile, + denoOptions, + baseImage, + baseBuildImage, + deploymentType + }); + else { + await saveBuildLog({ line: `Build pack ${buildPack} not found`, buildId, applicationId }); + throw new Error(`Build pack ${buildPack} not found.`); + } + } else { + await saveBuildLog({ line: 'Build image already available - no rebuild required.', buildId, applicationId }); + } + try { + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker stop -t 0 ${imageId}` }) + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker rm ${imageId}` }) + } catch (error) { + // + } + const envs = [ + `PORT=${port}` + ]; + if (secrets.length > 0) { + secrets.forEach((secret) => { + if (pullmergeRequestId) { + if (secret.isPRMRSecret) { + envs.push(`${secret.name}=${secret.value}`); + } + } else { + if (!secret.isPRMRSecret) { + envs.push(`${secret.name}=${secret.value}`); + } + } + }); + } + await fs.writeFile(`${workdir}/.env`, envs.join('\n')); + const labels = makeLabelForStandaloneApplication({ + applicationId, + fqdn, + name, + type, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + port: exposePort ? `${exposePort}:${port}` : port, + commit, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory + }); + let envFound = false; + try { + envFound = !!(await fs.stat(`${workdir}/.env`)); + } catch (error) { + // + } + try { + await saveBuildLog({ line: 'Deployment started.', buildId, applicationId }); + const composeVolumes = volumes.map((volume) => { + return { + [`${volume.split(':')[0]}`]: { + name: volume.split(':')[0] + } + }; + }); + const composeFile = { + version: '3.8', + services: { + [imageId]: { + image: `${applicationId}:${tag}`, + container_name: imageId, + volumes, + env_file: envFound ? [`${workdir}/.env`] : [], + labels, + depends_on: [], + expose: [port], + ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), + // logging: { + // driver: 'fluentd', + // }, + ...defaultComposeConfiguration(destinationDocker.network), + } + }, + networks: { + [destinationDocker.network]: { + external: true + } + }, + volumes: Object.assign({}, ...composeVolumes) + }; + await fs.writeFile(`${workdir}/docker-compose.yml`, yaml.dump(composeFile)); + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose --project-directory ${workdir} up -d` }) + await saveBuildLog({ line: 'Deployment successful!', buildId, applicationId }); + } catch (error) { + await saveBuildLog({ line: error, buildId, applicationId }); + await prisma.build.updateMany({ + where: { id: message.build_id, status: { in: ['queued', 'running'] } }, + data: { status: 'failed' } + }); + throw new Error(error); + } + await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId }); + await prisma.build.update({ where: { id: message.build_id }, data: { status: 'success' } }); + if (!pullmergeRequestId) await prisma.application.update({ + where: { id: applicationId }, + data: { configHash: currentHash } + }); + } + + } + catch (error) { + await prisma.build.updateMany({ + where: { id: message.build_id, status: { in: ['queued', 'running'] } }, + data: { status: 'failed' } + }); + await saveBuildLog({ line: error, buildId, applicationId }); + } finally { + await prisma.$disconnect(); + } + }); + await prisma.$disconnect(); + } + }); + } else process.exit(0); +})(); diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index 93d358fe3..261f8bd32 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -10,357 +10,353 @@ import * as buildpacks from '../lib/buildPacks'; (async () => { if (parentPort) { - const concurrency = 1 - const PQueue = await import('p-queue'); - const queue = new PQueue.default({ concurrency }); parentPort.on('message', async (message) => { - if (parentPort) { - if (message === 'error') throw new Error('oops'); - if (message === 'cancel') { - parentPort.postMessage('cancelled'); - return; - } - if (message === 'status:autoUpdater') { - parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'autoUpdater' }); - return; - } - if (message === 'status:cleanupStorage') { - parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'cleanupStorage' }); - return; - } - if (message === 'action:flushQueue') { - queue.clear() - return; - } - - await queue.add(async () => { - const { - id: applicationId, - repository, - name, - destinationDocker, - destinationDockerId, - gitSource, - build_id: buildId, - configHash, - fqdn, - projectId, - secrets, - phpModules, - type, - pullmergeRequestId = null, - sourceBranch = null, - settings, - persistentStorage, - pythonWSGI, - pythonModule, - pythonVariable, - denoOptions, - exposePort, - baseImage, - baseBuildImage, - deploymentType, - forceRebuild - } = message - let { - branch, - buildPack, - port, - installCommand, - buildCommand, - startCommand, - baseDirectory, - publishDirectory, - dockerFileLocation, - denoMainFile - } = message - 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'); - try { - const { debug } = settings; - if (concurrency === 1) { - await prisma.build.updateMany({ - where: { - status: { in: ['queued', 'running'] }, - id: { not: buildId }, - applicationId, - createdAt: { lt: new Date(new Date().getTime() - 10 * 1000) } - }, - data: { status: 'failed' } - }); - } - let imageId = applicationId; - let domain = getDomain(fqdn); - const volumes = - persistentStorage?.map((storage) => { - return `${applicationId}${storage.path.replace(/\//gi, '-')}:${buildPack !== 'docker' ? '/app' : '' - }${storage.path}`; - }) || []; - // Previews, we need to get the source branch and set subdomain - if (pullmergeRequestId) { - branch = sourceBranch; - domain = `${pullmergeRequestId}.${domain}`; - imageId = `${applicationId}-${pullmergeRequestId}`; - } - - let deployNeeded = true; - let destinationType; - - if (destinationDockerId) { - destinationType = 'docker'; - } - if (destinationType === 'docker') { - await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } }); - const { workdir, repodir } = await createDirectories({ repository, buildId }); - const configuration = await setDefaultConfiguration(message); - - buildPack = configuration.buildPack; - port = configuration.port; - installCommand = configuration.installCommand; - startCommand = configuration.startCommand; - buildCommand = configuration.buildCommand; - publishDirectory = configuration.publishDirectory; - baseDirectory = configuration.baseDirectory; - dockerFileLocation = configuration.dockerFileLocation; - denoMainFile = configuration.denoMainFile; - const commit = await importers[gitSource.type]({ - applicationId, - debug, - workdir, - repodir, - githubAppId: gitSource.githubApp?.id, - gitlabAppId: gitSource.gitlabApp?.id, - customPort: gitSource.customPort, - repository, - branch, - buildId, - apiUrl: gitSource.apiUrl, - htmlUrl: gitSource.htmlUrl, - projectId, - deployKeyId: gitSource.gitlabApp?.deployKeyId || null, - privateSshKey: decrypt(gitSource.gitlabApp?.privateSshKey) || null, - forPublic: gitSource.forPublic - }); - if (!commit) { - throw new Error('No commit found?'); - } - let tag = commit.slice(0, 7); - if (pullmergeRequestId) { - tag = `${commit.slice(0, 7)}-${pullmergeRequestId}`; - } - - try { - await prisma.build.update({ where: { id: buildId }, data: { commit } }); - } catch (err) { - console.log(err); - } - - if (!pullmergeRequestId) { - - if (configHash !== currentHash) { - deployNeeded = true; - if (configHash) { - await saveBuildLog({ line: 'Configuration changed.', buildId, applicationId }); - } - } else { - deployNeeded = false; - } - } else { - deployNeeded = true; - } - - let imageFound = false; - try { - await executeDockerCmd({ - dockerId: destinationDocker.id, - command: `docker image inspect ${applicationId}:${tag}` - }) - imageFound = true; - } catch (error) { - // - } - await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage); - - if (forceRebuild) deployNeeded = true - if (!imageFound || deployNeeded) { - // if (true) { - if (buildpacks[buildPack]) - await buildpacks[buildPack]({ - dockerId: destinationDocker.id, - buildId, - applicationId, - domain, - name, - type, - pullmergeRequestId, - buildPack, - repository, - branch, - projectId, - publishDirectory, - debug, - commit, - tag, - workdir, - port: exposePort ? `${exposePort}:${port}` : port, - installCommand, - buildCommand, - startCommand, - baseDirectory, - secrets, - phpModules, - pythonWSGI, - pythonModule, - pythonVariable, - dockerFileLocation, - denoMainFile, - denoOptions, - baseImage, - baseBuildImage, - deploymentType - }); - else { - await saveBuildLog({ line: `Build pack ${buildPack} not found`, buildId, applicationId }); - throw new Error(`Build pack ${buildPack} not found.`); - } - } else { - await saveBuildLog({ line: 'Build image already available - no rebuild required.', buildId, applicationId }); - } - try { - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker stop -t 0 ${imageId}` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker rm ${imageId}` }) - } catch (error) { - // - } - const envs = [ - `PORT=${port}` - ]; - if (secrets.length > 0) { - secrets.forEach((secret) => { - if (pullmergeRequestId) { - if (secret.isPRMRSecret) { - envs.push(`${secret.name}=${secret.value}`); - } - } else { - if (!secret.isPRMRSecret) { - envs.push(`${secret.name}=${secret.value}`); - } - } - }); - } - await fs.writeFile(`${workdir}/.env`, envs.join('\n')); - const labels = makeLabelForStandaloneApplication({ - applicationId, - fqdn, - name, - type, - pullmergeRequestId, - buildPack, - repository, - branch, - projectId, - port: exposePort ? `${exposePort}:${port}` : port, - commit, - installCommand, - buildCommand, - startCommand, - baseDirectory, - publishDirectory - }); - let envFound = false; - try { - envFound = !!(await fs.stat(`${workdir}/.env`)); - } catch (error) { - // - } - try { - await saveBuildLog({ line: 'Deployment started.', buildId, applicationId }); - const composeVolumes = volumes.map((volume) => { - return { - [`${volume.split(':')[0]}`]: { - name: volume.split(':')[0] - } - }; - }); - const composeFile = { - version: '3.8', - services: { - [imageId]: { - image: `${applicationId}:${tag}`, - container_name: imageId, - volumes, - env_file: envFound ? [`${workdir}/.env`] : [], - labels, - depends_on: [], - expose: [port], - ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), - // logging: { - // driver: 'fluentd', - // }, - ...defaultComposeConfiguration(destinationDocker.network), - } - }, - networks: { - [destinationDocker.network]: { - external: true - } - }, - volumes: Object.assign({}, ...composeVolumes) - }; - await fs.writeFile(`${workdir}/docker-compose.yml`, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose --project-directory ${workdir} up -d` }) - await saveBuildLog({ line: 'Deployment successful!', buildId, applicationId }); - } catch (error) { - await saveBuildLog({ line: error, buildId, applicationId }); - await prisma.build.updateMany({ - where: { id: message.build_id, status: { in: ['queued', 'running'] } }, - data: { status: 'failed' } - }); - throw new Error(error); - } - await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId }); - await prisma.build.update({ where: { id: message.build_id }, data: { status: 'success' } }); - if (!pullmergeRequestId) await prisma.application.update({ - where: { id: applicationId }, - data: { configHash: currentHash } - }); - } - - } - catch (error) { - await prisma.build.updateMany({ - where: { id: message.build_id, status: { in: ['queued', 'running'] } }, - data: { status: 'failed' } - }); - await saveBuildLog({ line: error, buildId, applicationId }); - } finally { - await prisma.$disconnect(); - } - }); - await prisma.$disconnect(); + if (message === 'error') throw new Error('oops'); + if (message === 'cancel') { + parentPort.postMessage('cancelled'); + process.exit(0); } }); + try { + parentPort.postMessage({ deploying: true }); + const queuedBuilds = await prisma.build.findMany({ where: { status: 'queued' }, orderBy: { createdAt: 'asc' } }); + const { concurrentBuilds } = await prisma.setting.findFirst({}) + if (queuedBuilds.length > 0) { + const concurrency = concurrentBuilds; + const pAll = await import('p-all'); + const actions = [] + + 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'); + try { + const { debug } = settings; + if (concurrency === 1) { + await prisma.build.updateMany({ + where: { + status: { in: ['queued', 'running'] }, + id: { not: buildId }, + applicationId, + createdAt: { lt: new Date(new Date().getTime() - 10 * 1000) } + }, + data: { status: 'failed' } + }); + } + let imageId = applicationId; + let domain = getDomain(fqdn); + const volumes = + persistentStorage?.map((storage) => { + return `${applicationId}${storage.path.replace(/\//gi, '-')}:${buildPack !== 'docker' ? '/app' : '' + }${storage.path}`; + }) || []; + // Previews, we need to get the source branch and set subdomain + if (pullmergeRequestId) { + branch = sourceBranch; + domain = `${pullmergeRequestId}.${domain}`; + imageId = `${applicationId}-${pullmergeRequestId}`; + } + + let deployNeeded = true; + let destinationType; + + if (destinationDockerId) { + destinationType = 'docker'; + } + if (destinationType === 'docker') { + await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } }); + const { workdir, repodir } = await createDirectories({ repository, buildId }); + const configuration = await setDefaultConfiguration(application); + + buildPack = configuration.buildPack; + port = configuration.port; + installCommand = configuration.installCommand; + startCommand = configuration.startCommand; + buildCommand = configuration.buildCommand; + publishDirectory = configuration.publishDirectory; + baseDirectory = configuration.baseDirectory; + dockerFileLocation = configuration.dockerFileLocation; + denoMainFile = configuration.denoMainFile; + const commit = await importers[gitSource.type]({ + applicationId, + debug, + workdir, + repodir, + githubAppId: gitSource.githubApp?.id, + gitlabAppId: gitSource.gitlabApp?.id, + customPort: gitSource.customPort, + repository, + branch, + buildId, + apiUrl: gitSource.apiUrl, + htmlUrl: gitSource.htmlUrl, + projectId, + deployKeyId: gitSource.gitlabApp?.deployKeyId || null, + privateSshKey: decrypt(gitSource.gitlabApp?.privateSshKey) || null, + forPublic: gitSource.forPublic + }); + if (!commit) { + throw new Error('No commit found?'); + } + let tag = commit.slice(0, 7); + if (pullmergeRequestId) { + tag = `${commit.slice(0, 7)}-${pullmergeRequestId}`; + } + + try { + await prisma.build.update({ where: { id: buildId }, data: { commit } }); + } catch (err) { + console.log(err); + } + + if (!pullmergeRequestId) { + if (configHash !== currentHash) { + deployNeeded = true; + if (configHash) { + await saveBuildLog({ line: 'Configuration changed.', buildId, applicationId }); + } + } else { + deployNeeded = false; + } + } else { + deployNeeded = true; + } + + let imageFound = false; + try { + await executeDockerCmd({ + dockerId: destinationDocker.id, + command: `docker image inspect ${applicationId}:${tag}` + }) + imageFound = true; + } catch (error) { + // + } + await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage); + + if (forceRebuild) deployNeeded = true + if (!imageFound || deployNeeded) { + // if (true) { + if (buildpacks[buildPack]) + await buildpacks[buildPack]({ + dockerId: destinationDocker.id, + buildId, + applicationId, + domain, + name, + type, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + publishDirectory, + debug, + commit, + tag, + workdir, + port: exposePort ? `${exposePort}:${port}` : port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + phpModules, + pythonWSGI, + pythonModule, + pythonVariable, + dockerFileLocation, + denoMainFile, + denoOptions, + baseImage, + baseBuildImage, + deploymentType + }); + else { + await saveBuildLog({ line: `Build pack ${buildPack} not found`, buildId, applicationId }); + throw new Error(`Build pack ${buildPack} not found.`); + } + } else { + await saveBuildLog({ line: 'Build image already available - no rebuild required.', buildId, applicationId }); + } + try { + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker stop -t 0 ${imageId}` }) + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker rm ${imageId}` }) + } catch (error) { + // + } + const envs = [ + `PORT=${port}` + ]; + if (secrets.length > 0) { + secrets.forEach((secret) => { + if (pullmergeRequestId) { + if (secret.isPRMRSecret) { + envs.push(`${secret.name}=${secret.value}`); + } + } else { + if (!secret.isPRMRSecret) { + envs.push(`${secret.name}=${secret.value}`); + } + } + }); + } + await fs.writeFile(`${workdir}/.env`, envs.join('\n')); + const labels = makeLabelForStandaloneApplication({ + applicationId, + fqdn, + name, + type, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + port: exposePort ? `${exposePort}:${port}` : port, + commit, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory + }); + let envFound = false; + try { + envFound = !!(await fs.stat(`${workdir}/.env`)); + } catch (error) { + // + } + try { + await saveBuildLog({ line: 'Deployment started.', buildId, applicationId }); + const composeVolumes = volumes.map((volume) => { + return { + [`${volume.split(':')[0]}`]: { + name: volume.split(':')[0] + } + }; + }); + const composeFile = { + version: '3.8', + services: { + [imageId]: { + image: `${applicationId}:${tag}`, + container_name: imageId, + volumes, + env_file: envFound ? [`${workdir}/.env`] : [], + labels, + depends_on: [], + expose: [port], + ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), + // logging: { + // driver: 'fluentd', + // }, + ...defaultComposeConfiguration(destinationDocker.network), + } + }, + networks: { + [destinationDocker.network]: { + external: true + } + }, + volumes: Object.assign({}, ...composeVolumes) + }; + await fs.writeFile(`${workdir}/docker-compose.yml`, yaml.dump(composeFile)); + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose --project-directory ${workdir} up -d` }) + await saveBuildLog({ line: 'Deployment successful!', buildId, applicationId }); + } catch (error) { + await saveBuildLog({ line: error, buildId, applicationId }); + await prisma.build.updateMany({ + where: { id: buildId, status: { in: ['queued', 'running'] } }, + data: { status: 'failed' } + }); + throw new Error(error); + } + await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId }); + await prisma.build.update({ where: { id: buildId }, data: { status: 'success' } }); + if (!pullmergeRequestId) await prisma.application.update({ + where: { id: applicationId }, + data: { configHash: currentHash } + }); + } + } + catch (error) { + await prisma.build.updateMany({ + where: { id: buildId, status: { in: ['queued', 'running'] } }, + data: { status: 'failed' } + }); + await saveBuildLog({ line: error, buildId, applicationId }); + } + }); + } + + await pAll.default(actions, { concurrency }) + } + + } catch (error) { + process.exit(0); + + } finally { + await prisma.$disconnect(); + process.exit(0); + } } else process.exit(0); })(); diff --git a/apps/api/src/lib/buildPacks/common.ts b/apps/api/src/lib/buildPacks/common.ts index b463a91db..c66477a0b 100644 --- a/apps/api/src/lib/buildPacks/common.ts +++ b/apps/api/src/lib/buildPacks/common.ts @@ -553,7 +553,7 @@ export async function buildImage({ await executeDockerCmd({ debug, buildId, applicationId, dockerId, command: `docker build --progress plain -f ${workdir}/${dockerFile} -t ${cache} ${workdir}` }) const { status } = await prisma.build.findUnique({ where: { id: buildId } }) if (status === 'canceled') { - throw new Error('Build canceled.') + throw new Error('Deployment canceled.') } if (isCache) { await saveBuildLog({ line: `Building cache image successful.`, buildId, applicationId }); diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index bb920b7ed..5d48c3f3b 100644 --- a/apps/api/src/lib/common.ts +++ b/apps/api/src/lib/common.ts @@ -93,7 +93,6 @@ export const asyncExecShellStream = async ({ debug, buildId, applicationId, comm const { execaCommand } = await import('execa') const subprocess = execaCommand(command, { env: { DOCKER_BUILDKIT: "1", DOCKER_HOST: engine } }) if (debug) { - await saveBuildLog({ line: `=========================`, buildId, applicationId }); subprocess.stdout.on('data', async (data) => { const stdout = data.toString(); const array = stdout.split('\n') @@ -123,7 +122,6 @@ export const asyncExecShellStream = async ({ debug, buildId, applicationId, comm } subprocess.on('exit', async (code) => { await asyncSleep(1000); - await saveBuildLog({ line: `=========================`, buildId, applicationId }); if (code === 0) { resolve(code) } else { @@ -1871,7 +1869,7 @@ export async function stopBuild(buildId, applicationId) { let count = 0; await new Promise(async (resolve, reject) => { const { destinationDockerId, status } = await prisma.build.findFirst({ where: { id: buildId } }); - const { engine, id: dockerId } = await prisma.destinationDocker.findFirst({ where: { id: destinationDockerId } }); + const { id: dockerId } = await prisma.destinationDocker.findFirst({ where: { id: destinationDockerId } }); const interval = setInterval(async () => { try { if (status === 'failed' || status === 'canceled') { @@ -1881,10 +1879,10 @@ export async function stopBuild(buildId, applicationId) { if (count > 15) { clearInterval(interval); if (scheduler.workers.has('deployApplication')) { - scheduler.workers.get('deployApplication').postMessage("action:flushQueue") + scheduler.workers.get('deployApplication').postMessage('cancel') } - await cleanupDB(buildId); - return reject(new Error('Build canceled')); + await cleanupDB(buildId, applicationId); + return reject(new Error('Deployment canceled.')); } const { stdout: buildContainers } = await executeDockerCmd({ dockerId, command: `docker container ls --filter "label=coolify.buildId=${buildId}" --format '{{json .}}'` }) if (buildContainers) { @@ -1896,9 +1894,9 @@ export async function stopBuild(buildId, applicationId) { await removeContainer({ id, dockerId }); clearInterval(interval); if (scheduler.workers.has('deployApplication')) { - scheduler.workers.get('deployApplication').postMessage("action:flushQueue") + scheduler.workers.get('deployApplication').postMessage('cancel') } - await cleanupDB(buildId); + await cleanupDB(buildId, applicationId); return resolve(); } } @@ -1909,11 +1907,12 @@ export async function stopBuild(buildId, applicationId) { }); } -async function cleanupDB(buildId: string) { +async function cleanupDB(buildId: string, applicationId: string) { const data = await prisma.build.findUnique({ where: { id: buildId } }); if (data?.status === 'queued' || data?.status === 'running') { await prisma.build.update({ where: { id: buildId }, data: { status: 'canceled' } }); } + await saveBuildLog({ line: 'Deployment canceled.', buildId, applicationId }); } export function convertTolOldVolumeNames(type) { diff --git a/apps/api/src/lib/scheduler.ts b/apps/api/src/lib/scheduler.ts index ad2dde568..6c233d050 100644 --- a/apps/api/src/lib/scheduler.ts +++ b/apps/api/src/lib/scheduler.ts @@ -9,27 +9,17 @@ Bree.extend(TSBree); const options: any = { defaultExtension: 'js', - logger: false, + logger: new Cabin(), workerMessageHandler: async ({ name, message }) => { - if (name === 'deployApplication') { - if (message.pending === 0 && message.size === 0) { - if (message.caller === 'autoUpdater') { - if (!scheduler.workers.has('autoUpdater')) { - await scheduler.run('autoUpdater') - } - } - if (message.caller === 'cleanupStorage') { - if (!scheduler.workers.has('cleanupStorage')) { - await scheduler.run('cleanupStorage') - } - } - + if (name === 'deployApplication' && message?.deploying) { + if (scheduler.workers.has('autoUpdater') || scheduler.workers.has('cleanupStorage')) { + scheduler.workers.get('deployApplication').postMessage('cancel') } } }, jobs: [ { - name: 'deployApplication' + name: 'deployApplication', }, { name: 'cleanupStorage', diff --git a/apps/api/src/routes/api/v1/applications/handlers.ts b/apps/api/src/routes/api/v1/applications/handlers.ts index 2abf30b3a..26b0d2bb9 100644 --- a/apps/api/src/routes/api/v1/applications/handlers.ts +++ b/apps/api/src/routes/api/v1/applications/handlers.ts @@ -75,7 +75,6 @@ export async function getApplicationStatus(request: FastifyRequest) { isExited = await isContainerExited(application.destinationDocker.id, id); } return { - isQueueActive: scheduler.workers.has('deployApplication'), isRunning, isExited, }; @@ -453,6 +452,8 @@ export async function deployApplication(request: FastifyRequest): Promi type: 'webhook_commit' } }); - scheduler.workers.get('deployApplication').postMessage({ - build_id: buildId, - type: 'webhook_commit', - ...applicationFound - }); - return { message: 'Queued. Thank you!' }; @@ -183,6 +177,8 @@ export async function gitHubEvents(request: FastifyRequest): Promi await prisma.build.create({ data: { id: buildId, + pullmergeRequestId, + sourceBranch, applicationId: applicationFound.id, destinationDockerId: applicationFound.destinationDocker.id, gitSourceId: applicationFound.gitSource.id, @@ -192,14 +188,7 @@ export async function gitHubEvents(request: FastifyRequest): Promi type: 'webhook_pr' } }); - scheduler.workers.get('deployApplication').postMessage({ - build_id: buildId, - type: 'webhook_pr', - ...applicationFound, - sourceBranch, - pullmergeRequestId - }); - + return { message: 'Queued. Thank you!' }; diff --git a/apps/api/src/routes/webhooks/gitlab/handlers.ts b/apps/api/src/routes/webhooks/gitlab/handlers.ts index 0e7f8ec5d..df848e45c 100644 --- a/apps/api/src/routes/webhooks/gitlab/handlers.ts +++ b/apps/api/src/routes/webhooks/gitlab/handlers.ts @@ -89,12 +89,6 @@ export async function gitLabEvents(request: FastifyRequest) { } }); - scheduler.workers.get('deployApplication').postMessage({ - build_id: buildId, - type: 'webhook_commit', - ...applicationFound - }); - return { message: 'Queued. Thank you!' }; @@ -141,6 +135,8 @@ export async function gitLabEvents(request: FastifyRequest) { await prisma.build.create({ data: { id: buildId, + pullmergeRequestId, + sourceBranch, applicationId: applicationFound.id, destinationDockerId: applicationFound.destinationDocker.id, gitSourceId: applicationFound.gitSource.id, @@ -150,14 +146,6 @@ export async function gitLabEvents(request: FastifyRequest) { type: 'webhook_mr' } }); - scheduler.workers.get('deployApplication').postMessage({ - build_id: buildId, - type: 'webhook_mr', - ...applicationFound, - sourceBranch, - pullmergeRequestId - }); - return { message: 'Queued. Thank you!' }; diff --git a/apps/ui/package.json b/apps/ui/package.json index 0a64124f0..ddff33ffd 100644 --- a/apps/ui/package.json +++ b/apps/ui/package.json @@ -14,20 +14,20 @@ "format": "prettier --write --plugin-search-dir=. ." }, "devDependencies": { - "@playwright/test": "1.24.2", + "@playwright/test": "1.25.1", "@sveltejs/kit": "1.0.0-next.405", "@types/js-cookie": "3.0.2", - "@typescript-eslint/eslint-plugin": "5.33.0", - "@typescript-eslint/parser": "5.33.0", + "@typescript-eslint/eslint-plugin": "5.35.1", + "@typescript-eslint/parser": "5.35.1", "autoprefixer": "10.4.8", - "eslint": "8.21.0", + "eslint": "8.22.0", "eslint-config-prettier": "8.5.0", "eslint-plugin-svelte3": "4.0.0", "postcss": "8.4.16", "prettier": "2.7.1", "prettier-plugin-svelte": "2.7.0", "svelte": "3.49.0", - "svelte-check": "2.8.0", + "svelte-check": "2.8.1", "svelte-preprocess": "4.10.7", "tailwindcss": "3.1.8", "tailwindcss-scrollbar": "0.1.0", @@ -39,7 +39,7 @@ "dependencies": { "@sveltejs/adapter-static": "1.0.0-next.39", "cuid": "2.1.8", - "daisyui": "2.22.0", + "daisyui": "2.24.0", "js-cookie": "3.0.1", "p-limit": "4.0.0", "svelte-select": "4.4.7", diff --git a/apps/ui/src/routes/applications/[id]/__layout.svelte b/apps/ui/src/routes/applications/[id]/__layout.svelte index c40f66439..83f66dc6f 100644 --- a/apps/ui/src/routes/applications/[id]/__layout.svelte +++ b/apps/ui/src/routes/applications/[id]/__layout.svelte @@ -66,7 +66,6 @@ let loading = false; let statusInterval: any; - let isQueueActive = false; $disabledButton = !$appSession.isAdmin || (!application.fqdn && !application.settings.isBot) || @@ -121,7 +120,6 @@ if ($status.application.loading) return; $status.application.loading = true; const data = await get(`/applications/${id}/status`); - isQueueActive = data.isQueueActive; $status.application.isRunning = data.isRunning; $status.application.isExited = data.isExited; $status.application.loading = false; @@ -259,13 +257,10 @@
handleDeploySubmit(true)}>
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 45e590081..9fd8a9e23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,15 +23,15 @@ importers: '@fastify/static': 6.5.0 '@iarna/toml': 2.2.5 '@prisma/client': 3.15.2 - '@types/node': 18.7.11 + '@types/node': 18.7.13 '@types/node-os-utils': 1.3.0 - '@typescript-eslint/eslint-plugin': 5.34.0 - '@typescript-eslint/parser': 5.34.0 + '@typescript-eslint/eslint-plugin': 5.35.1 + '@typescript-eslint/parser': 5.35.1 axios: 0.27.2 bcryptjs: 2.4.3 bree: 9.1.2 cabin: 9.1.2 - compare-versions: 4.1.3 + compare-versions: 4.1.4 cuid: 2.1.8 dayjs: 1.11.5 dockerode: 3.3.4 @@ -52,7 +52,7 @@ importers: node-forge: 1.3.1 node-os-utils: 1.3.7 nodemon: 2.0.19 - p-queue: 7.3.0 + p-all: 4.0.0 prettier: 2.7.1 prisma: 3.15.2 public-ip: 6.0.1 @@ -63,7 +63,7 @@ importers: typescript: 4.7.4 unique-names-generator: 4.7.1 dependencies: - '@breejs/ts-worker': 2.0.0_vko2uubnomvm6mw63pxqdtopyq + '@breejs/ts-worker': 2.0.0_rzqxabipis2a5sxrpk4obdh4zu '@fastify/autoload': 5.2.0 '@fastify/cookie': 8.0.0 '@fastify/cors': 8.1.0 @@ -76,7 +76,7 @@ importers: bcryptjs: 2.4.3 bree: 9.1.2 cabin: 9.1.2 - compare-versions: 4.1.3 + compare-versions: 4.1.4 cuid: 2.1.8 dayjs: 1.11.5 dockerode: 3.3.4 @@ -92,16 +92,16 @@ importers: jsonwebtoken: 8.5.1 node-forge: 1.3.1 node-os-utils: 1.3.7 - p-queue: 7.3.0 + p-all: 4.0.0 public-ip: 6.0.1 ssh-config: 4.1.6 strip-ansi: 7.0.1 unique-names-generator: 4.7.1 devDependencies: - '@types/node': 18.7.11 + '@types/node': 18.7.13 '@types/node-os-utils': 1.3.0 - '@typescript-eslint/eslint-plugin': 5.34.0_euudt5oqhhodkyae5tf6wjmsda - '@typescript-eslint/parser': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq + '@typescript-eslint/eslint-plugin': 5.35.1_ktjxjibzrfqejavile4bhmzhjq + '@typescript-eslint/parser': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq esbuild: 0.15.5 eslint: 8.22.0 eslint-config-prettier: 8.5.0_eslint@8.22.0 @@ -115,16 +115,16 @@ importers: apps/ui: specifiers: - '@playwright/test': 1.24.2 + '@playwright/test': 1.25.1 '@sveltejs/adapter-static': 1.0.0-next.39 '@sveltejs/kit': 1.0.0-next.405 '@types/js-cookie': 3.0.2 - '@typescript-eslint/eslint-plugin': 5.33.0 - '@typescript-eslint/parser': 5.33.0 + '@typescript-eslint/eslint-plugin': 5.35.1 + '@typescript-eslint/parser': 5.35.1 autoprefixer: 10.4.8 cuid: 2.1.8 - daisyui: 2.22.0 - eslint: 8.21.0 + daisyui: 2.24.0 + eslint: 8.22.0 eslint-config-prettier: 8.5.0 eslint-plugin-svelte3: 4.0.0 js-cookie: 3.0.1 @@ -133,7 +133,7 @@ importers: prettier: 2.7.1 prettier-plugin-svelte: 2.7.0 svelte: 3.49.0 - svelte-check: 2.8.0 + svelte-check: 2.8.1 svelte-preprocess: 4.10.7 svelte-select: 4.4.7 sveltekit-i18n: 2.2.2 @@ -145,26 +145,26 @@ importers: dependencies: '@sveltejs/adapter-static': 1.0.0-next.39 cuid: 2.1.8 - daisyui: 2.22.0_25hquoklqeoqwmt7fwvvcyxm5e + daisyui: 2.24.0_25hquoklqeoqwmt7fwvvcyxm5e js-cookie: 3.0.1 p-limit: 4.0.0 svelte-select: 4.4.7 sveltekit-i18n: 2.2.2_svelte@3.49.0 devDependencies: - '@playwright/test': 1.24.2 + '@playwright/test': 1.25.1 '@sveltejs/kit': 1.0.0-next.405_svelte@3.49.0+vite@3.0.5 '@types/js-cookie': 3.0.2 - '@typescript-eslint/eslint-plugin': 5.33.0_njno5y7ry2l2lcmiu4tywxkwnq - '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq + '@typescript-eslint/eslint-plugin': 5.35.1_ktjxjibzrfqejavile4bhmzhjq + '@typescript-eslint/parser': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq autoprefixer: 10.4.8_postcss@8.4.16 - eslint: 8.21.0 - eslint-config-prettier: 8.5.0_eslint@8.21.0 - eslint-plugin-svelte3: 4.0.0_a7wk4ghvg4hia4trwaglu7p6cq + eslint: 8.22.0 + eslint-config-prettier: 8.5.0_eslint@8.22.0 + eslint-plugin-svelte3: 4.0.0_laaqauvsmoyypsiqkozwyi2fn4 postcss: 8.4.16 prettier: 2.7.1 prettier-plugin-svelte: 2.7.0_o3ioganyptcsrh6x4hnxvjkpqi svelte: 3.49.0 - svelte-check: 2.8.0_vylzxgme5yisu3bsyvcau4hjtq + svelte-check: 2.8.1_vylzxgme5yisu3bsyvcau4hjtq svelte-preprocess: 4.10.7_fje22ktja5v2dh6nbkissncqme tailwindcss: 3.1.8 tailwindcss-scrollbar: 0.1.0_tailwindcss@3.1.8 @@ -211,14 +211,14 @@ packages: engines: {node: '>= 10'} dev: false - /@breejs/ts-worker/2.0.0_vko2uubnomvm6mw63pxqdtopyq: + /@breejs/ts-worker/2.0.0_rzqxabipis2a5sxrpk4obdh4zu: resolution: {integrity: sha512-6anHRcmgYlF7mrm/YVRn6rx2cegLuiY3VBxkkimOTWC/dVQeH336imVSuIKEGKTwiuNTPr2hswVdDSneNuXg3A==} engines: {node: '>= 12.11'} peerDependencies: bree: '>=9.0.0' dependencies: bree: 9.1.2 - ts-node: 10.8.2_yuzmdm4dwbtqx7oi4ad7vmtwja + ts-node: 10.8.2_57uwcby55h6tzvkj3v5sfcgxoe tsconfig-paths: 4.1.0 transitivePeerDependencies: - '@swc/core' @@ -401,13 +401,13 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 - /@playwright/test/1.24.2: - resolution: {integrity: sha512-Q4X224pRHw4Dtkk5PoNJplZCokLNvVbXD9wDQEMrHcEuvWpJWEQDeJ9gEwkZ3iCWSFSWBshIX177B231XW4wOQ==} + /@playwright/test/1.25.1: + resolution: {integrity: sha512-IJ4X0yOakXtwkhbnNzKkaIgXe6df7u3H3FnuhI9Jqh+CdO0e/lYQlDLYiyI9cnXK8E7UAppAWP+VqAv6VX7HQg==} engines: {node: '>=14'} hasBin: true dependencies: - '@types/node': 18.6.5 - playwright-core: 1.24.2 + '@types/node': 18.7.13 + playwright-core: 1.25.1 dev: true /@prisma/client/3.15.2_prisma@3.15.2: @@ -534,7 +534,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 18.7.11 + '@types/node': 18.7.13 '@types/responselike': 1.0.0 dev: false @@ -557,7 +557,7 @@ packages: /@types/keyv/3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.7.11 + '@types/node': 18.7.13 dev: false /@types/lodash/4.14.182: @@ -568,16 +568,8 @@ packages: resolution: {integrity: sha512-XwVteWQx/XkfRPyaGkw8dEbrCAkoRZ73pI3XznUYIpzbCfpQB3UnDlR5TnmdhetlT889tUJGF8QWo9xrgTpsiA==} dev: true - /@types/node/18.0.3: - resolution: {integrity: sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==} - dev: true - - /@types/node/18.6.5: - resolution: {integrity: sha512-Xjt5ZGUa5WusGZJ4WJPbOT8QOqp6nDynVFRKcUt32bOgvXEoc6o085WNkYTMO7ifAj2isEfQQ2cseE+wT6jsRw==} - dev: true - - /@types/node/18.7.11: - resolution: {integrity: sha512-KZhFpSLlmK/sdocfSAjqPETTMd0ug6HIMIAwkwUpU79olnZdQtMxpQP+G1wDzCH7na+FltSIhbaZuKdwZ8RDrw==} + /@types/node/18.7.13: + resolution: {integrity: sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==} /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -590,17 +582,17 @@ packages: /@types/responselike/1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 18.7.11 + '@types/node': 18.7.13 dev: false /@types/sass/1.43.1: resolution: {integrity: sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==} dependencies: - '@types/node': 18.0.3 + '@types/node': 18.7.13 dev: true - /@typescript-eslint/eslint-plugin/5.33.0_njno5y7ry2l2lcmiu4tywxkwnq: - resolution: {integrity: sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg==} + /@typescript-eslint/eslint-plugin/5.35.1_ktjxjibzrfqejavile4bhmzhjq: + resolution: {integrity: sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -610,37 +602,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq - '@typescript-eslint/scope-manager': 5.33.0 - '@typescript-eslint/type-utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq - '@typescript-eslint/utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq - debug: 4.3.4 - eslint: 8.21.0 - functional-red-black-tree: 1.0.1 - ignore: 5.2.0 - regexpp: 3.2.0 - semver: 7.3.7 - tsutils: 3.21.0_typescript@4.7.4 - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/eslint-plugin/5.34.0_euudt5oqhhodkyae5tf6wjmsda: - resolution: {integrity: sha512-eRfPPcasO39iwjlUAMtjeueRGuIrW3TQ9WseIDl7i5UWuFbf83yYaU7YPs4j8+4CxUMIsj1k+4kV+E+G+6ypDQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/parser': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq - '@typescript-eslint/scope-manager': 5.34.0 - '@typescript-eslint/type-utils': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq - '@typescript-eslint/utils': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq + '@typescript-eslint/parser': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq + '@typescript-eslint/scope-manager': 5.35.1 + '@typescript-eslint/type-utils': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq + '@typescript-eslint/utils': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq debug: 4.3.4 eslint: 8.22.0 functional-red-black-tree: 1.0.1 @@ -653,8 +618,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: - resolution: {integrity: sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w==} + /@typescript-eslint/parser/5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq: + resolution: {integrity: sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -663,29 +628,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.33.0 - '@typescript-eslint/types': 5.33.0 - '@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 - debug: 4.3.4 - eslint: 8.21.0 - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/parser/5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq: - resolution: {integrity: sha512-SZ3NEnK4usd2CXkoV3jPa/vo1mWX1fqRyIVUQZR4As1vyp4fneknBNJj+OFtV8WAVgGf+rOHMSqQbs2Qn3nFZQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.34.0 - '@typescript-eslint/types': 5.34.0 - '@typescript-eslint/typescript-estree': 5.34.0_typescript@4.7.4 + '@typescript-eslint/scope-manager': 5.35.1 + '@typescript-eslint/types': 5.35.1 + '@typescript-eslint/typescript-estree': 5.35.1_typescript@4.7.4 debug: 4.3.4 eslint: 8.22.0 typescript: 4.7.4 @@ -693,24 +638,16 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager/5.33.0: - resolution: {integrity: sha512-/Jta8yMNpXYpRDl8EwF/M8It2A9sFJTubDo0ATZefGXmOqlaBffEw0ZbkbQ7TNDK6q55NPHFshGBPAZvZkE8Pw==} + /@typescript-eslint/scope-manager/5.35.1: + resolution: {integrity: sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.33.0 - '@typescript-eslint/visitor-keys': 5.33.0 + '@typescript-eslint/types': 5.35.1 + '@typescript-eslint/visitor-keys': 5.35.1 dev: true - /@typescript-eslint/scope-manager/5.34.0: - resolution: {integrity: sha512-HNvASMQlah5RsBW6L6c7IJ0vsm+8Sope/wu5sEAf7joJYWNb1LDbJipzmdhdUOnfrDFE6LR1j57x1EYVxrY4ow==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.34.0 - '@typescript-eslint/visitor-keys': 5.34.0 - dev: true - - /@typescript-eslint/type-utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: - resolution: {integrity: sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA==} + /@typescript-eslint/type-utils/5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq: + resolution: {integrity: sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -719,26 +656,7 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq - debug: 4.3.4 - eslint: 8.21.0 - tsutils: 3.21.0_typescript@4.7.4 - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/type-utils/5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq: - resolution: {integrity: sha512-Pxlno9bjsQ7hs1pdWRUv9aJijGYPYsHpwMeCQ/Inavhym3/XaKt1ZKAA8FIw4odTBfowBdZJDMxf2aavyMDkLg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/utils': 5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq + '@typescript-eslint/utils': 5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq debug: 4.3.4 eslint: 8.22.0 tsutils: 3.21.0_typescript@4.7.4 @@ -747,18 +665,13 @@ packages: - supports-color dev: true - /@typescript-eslint/types/5.33.0: - resolution: {integrity: sha512-nIMt96JngB4MYFYXpZ/3ZNU4GWPNdBbcB5w2rDOCpXOVUkhtNlG2mmm8uXhubhidRZdwMaMBap7Uk8SZMU/ppw==} + /@typescript-eslint/types/5.35.1: + resolution: {integrity: sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/types/5.34.0: - resolution: {integrity: sha512-49fm3xbbUPuzBIOcy2CDpYWqy/X7VBkxVN+DC21e0zIm3+61Z0NZi6J9mqPmSW1BDVk9FIOvuCFyUPjXz93sjA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@typescript-eslint/typescript-estree/5.33.0_typescript@4.7.4: - resolution: {integrity: sha512-tqq3MRLlggkJKJUrzM6wltk8NckKyyorCSGMq4eVkyL5sDYzJJcMgZATqmF8fLdsWrW7OjjIZ1m9v81vKcaqwQ==} + /@typescript-eslint/typescript-estree/5.35.1_typescript@4.7.4: + resolution: {integrity: sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -766,8 +679,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.33.0 - '@typescript-eslint/visitor-keys': 5.33.0 + '@typescript-eslint/types': 5.35.1 + '@typescript-eslint/visitor-keys': 5.35.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -778,55 +691,16 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree/5.34.0_typescript@4.7.4: - resolution: {integrity: sha512-mXHAqapJJDVzxauEkfJI96j3D10sd567LlqroyCeJaHnu42sDbjxotGb3XFtGPYKPD9IyLjhsoULML1oI3M86A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.34.0 - '@typescript-eslint/visitor-keys': 5.34.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.7 - tsutils: 3.21.0_typescript@4.7.4 - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: - resolution: {integrity: sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==} + /@typescript-eslint/utils/5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq: + resolution: {integrity: sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.33.0 - '@typescript-eslint/types': 5.33.0 - '@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 - eslint: 8.21.0 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.21.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/utils/5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq: - resolution: {integrity: sha512-kWRYybU4Rn++7lm9yu8pbuydRyQsHRoBDIo11k7eqBWTldN4xUdVUMCsHBiE7aoEkFzrUEaZy3iH477vr4xHAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.34.0 - '@typescript-eslint/types': 5.34.0 - '@typescript-eslint/typescript-estree': 5.34.0_typescript@4.7.4 + '@typescript-eslint/scope-manager': 5.35.1 + '@typescript-eslint/types': 5.35.1 + '@typescript-eslint/typescript-estree': 5.35.1_typescript@4.7.4 eslint: 8.22.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@8.22.0 @@ -835,19 +709,11 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys/5.33.0: - resolution: {integrity: sha512-/XsqCzD4t+Y9p5wd9HZiptuGKBlaZO5showwqODii5C0nZawxWLF+Q6k5wYHBrQv96h6GYKyqqMHCSTqta8Kiw==} + /@typescript-eslint/visitor-keys/5.35.1: + resolution: {integrity: sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.33.0 - eslint-visitor-keys: 3.3.0 - dev: true - - /@typescript-eslint/visitor-keys/5.34.0: - resolution: {integrity: sha512-O1moYjOSrab0a2fUvFpsJe0QHtvTC+cR+ovYpgKrAVXzqQyc74mv76TgY6z+aEtjQE2vgZux3CQVtGryqdcOAw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.34.0 + '@typescript-eslint/types': 5.35.1 eslint-visitor-keys: 3.3.0 dev: true @@ -2073,8 +1939,8 @@ packages: delayed-stream: 1.0.0 dev: false - /compare-versions/4.1.3: - resolution: {integrity: sha512-WQfnbDcrYnGr55UwbxKiQKASnTtNnaAWVi8jZyy8NTpVAXWACSne8lMD1iaIo9AiU6mnuLvSVshCzewVuWxHUg==} + /compare-versions/4.1.4: + resolution: {integrity: sha512-FemMreK9xNyL8gQevsdRMrvO4lFCkQP7qbuktn1q8ndcNk1+0mz7lgE7b/sNvbhVgY4w6tMN1FDp6aADjqw2rw==} dev: false /component-emitter/1.3.0: @@ -2224,8 +2090,8 @@ packages: resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==} dev: false - /daisyui/2.22.0_25hquoklqeoqwmt7fwvvcyxm5e: - resolution: {integrity: sha512-H08aQP+Mfl2fQOmyaxd1NP54gQbr2xRUj2MmFFvfJ5EDGbthVBICDMNFKyia/zBfR58G8eTJo3CmydglM81/7Q==} + /daisyui/2.24.0_25hquoklqeoqwmt7fwvvcyxm5e: + resolution: {integrity: sha512-Fdu/4LCdTfWLWAbCuPxvnaRotEfJ+hVPgZ2kv/aUk9RZ00Yk8fGdJtIf0kXJ3IgUKOr8rCXUpfQY6DQU9usPCQ==} peerDependencies: autoprefixer: ^10.0.2 postcss: ^8.1.6 @@ -2984,15 +2850,6 @@ packages: engines: {node: '>=12'} dev: false - /eslint-config-prettier/8.5.0_eslint@8.21.0: - resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - dependencies: - eslint: 8.21.0 - dev: true - /eslint-config-prettier/8.5.0_eslint@8.22.0: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true @@ -3019,13 +2876,13 @@ packages: prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-svelte3/4.0.0_a7wk4ghvg4hia4trwaglu7p6cq: + /eslint-plugin-svelte3/4.0.0_laaqauvsmoyypsiqkozwyi2fn4: resolution: {integrity: sha512-OIx9lgaNzD02+MDFNLw0GEUbuovNcglg+wnd/UY0fbZmlQSz7GlQiQ1f+yX0XvC07XPcDOnFcichqI3xCwp71g==} peerDependencies: eslint: '>=8.0.0' svelte: ^3.2.0 dependencies: - eslint: 8.21.0 + eslint: 8.22.0 svelte: 3.49.0 dev: true @@ -3045,16 +2902,6 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.21.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - dependencies: - eslint: 8.21.0 - eslint-visitor-keys: 2.1.0 - dev: true - /eslint-utils/3.0.0_eslint@8.22.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} @@ -3075,54 +2922,6 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.21.0: - resolution: {integrity: sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint/eslintrc': 1.3.0 - '@humanwhocodes/config-array': 0.10.4 - '@humanwhocodes/gitignore-to-minimatch': 1.0.2 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.21.0 - eslint-visitor-keys: 3.3.0 - espree: 9.3.3 - esquery: 1.4.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - functional-red-black-tree: 1.0.1 - glob-parent: 6.0.2 - globals: 13.15.0 - globby: 11.1.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.0 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.1 - regexpp: 3.2.0 - strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 - text-table: 0.2.0 - v8-compile-cache: 2.3.0 - transitivePeerDependencies: - - supports-color - dev: true - /eslint/8.22.0: resolution: {integrity: sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3223,10 +3022,6 @@ packages: engines: {node: '>=6'} dev: false - /eventemitter3/4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: false - /execa/6.1.0: resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4703,6 +4498,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /p-all/4.0.0: + resolution: {integrity: sha512-QXqMc8PpYu0gmNM6VcKP0uYqeI+dtvSNeaDb8ktnNjposr+nftHHCSYbj/S/oUceF6R868jw1XOxkJKUSiHgEQ==} + engines: {node: '>=12.20'} + dependencies: + p-map: 5.5.0 + dev: false + /p-cancelable/3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -4754,12 +4556,11 @@ packages: p-limit: 3.1.0 dev: true - /p-queue/7.3.0: - resolution: {integrity: sha512-5fP+yVQ0qp0rEfZoDTlP2c3RYBgxvRsw30qO+VtPPc95lyvSG+x6USSh1TuLB4n96IO6I8/oXQGsTgtna4q2nQ==} + /p-map/5.5.0: + resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} engines: {node: '>=12'} dependencies: - eventemitter3: 4.0.7 - p-timeout: 5.0.2 + aggregate-error: 4.0.1 dev: false /p-timeout/3.2.0: @@ -4769,11 +4570,6 @@ packages: p-finally: 1.0.0 dev: false - /p-timeout/5.0.2: - resolution: {integrity: sha512-sEmji9Yaq+Tw+STwsGAE56hf7gMy9p0tQfJojIAamB7WHJYJKf1qlsg9jqBWG8q9VCxKPhZaP/AcXwEoBcYQhQ==} - engines: {node: '>=12'} - dev: false - /p-try/2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -4954,8 +4750,8 @@ packages: find-up: 3.0.0 dev: false - /playwright-core/1.24.2: - resolution: {integrity: sha512-zfAoDoPY/0sDLsgSgLZwWmSCevIg1ym7CppBwllguVBNiHeixZkc1AdMuYUPZC6AdEYc4CxWEyLMBTw2YcmRrA==} + /playwright-core/1.25.1: + resolution: {integrity: sha512-lSvPCmA2n7LawD2Hw7gSCLScZ+vYRkhU8xH0AapMyzwN+ojoDqhkH/KIEUxwNu2PjPoE/fcE0wLAksdOhJ2O5g==} engines: {node: '>=14'} hasBin: true dev: true @@ -5751,8 +5547,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /svelte-check/2.8.0_vylzxgme5yisu3bsyvcau4hjtq: - resolution: {integrity: sha512-HRL66BxffMAZusqe5I5k26mRWQ+BobGd9Rxm3onh7ZVu0nTk8YTKJ9vu3LVPjUGLU9IX7zS+jmwPVhJYdXJ8vg==} + /svelte-check/2.8.1_vylzxgme5yisu3bsyvcau4hjtq: + resolution: {integrity: sha512-cibyY1sgt3ONIDnQbSgV2X9AJFhwEslRHNo95lijrYfPzVEvTvbmL2ohsUyqB5L7j1GhLXtQbjCJ4lZZ/fwbeQ==} hasBin: true peerDependencies: svelte: ^3.24.0 @@ -5988,7 +5784,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /ts-node/10.8.2_yuzmdm4dwbtqx7oi4ad7vmtwja: + /ts-node/10.8.2_57uwcby55h6tzvkj3v5sfcgxoe: resolution: {integrity: sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==} hasBin: true peerDependencies: @@ -6007,7 +5803,7 @@ packages: '@tsconfig/node12': 1.0.9 '@tsconfig/node14': 1.0.1 '@tsconfig/node16': 1.0.2 - '@types/node': 18.7.11 + '@types/node': 18.7.13 acorn: 8.8.0 acorn-walk: 8.2.0 arg: 4.1.3 From db16a357e891945b8db14e33e01060a17d76b91b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 10:17:07 +0200 Subject: [PATCH 04/32] debug cpu usage --- apps/api/src/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 3f4876c94..5492331e6 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -107,11 +107,11 @@ fastify.listen({ port, host }, async (err: any, address: any) => { await scheduler.start('cleanupPrismaEngines'); await scheduler.start('checkProxies'); - setInterval(async () => { - if (!scheduler.workers.has('deployApplication')) { - scheduler.run('deployApplication'); - } - }, 2000) + // setInterval(async () => { + // if (!scheduler.workers.has('deployApplication')) { + // scheduler.run('deployApplication'); + // } + // }, 2000) // Check for update & if no build is running setInterval(async () => { From c53f0dbb30c3c1160b230203c924723122e1451c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 10:28:32 +0200 Subject: [PATCH 05/32] fix: high cpu usage --- apps/api/src/index.ts | 10 +++++----- apps/api/src/jobs/checkProxies.ts | 26 ++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 5492331e6..3f4876c94 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -107,11 +107,11 @@ fastify.listen({ port, host }, async (err: any, address: any) => { await scheduler.start('cleanupPrismaEngines'); await scheduler.start('checkProxies'); - // setInterval(async () => { - // if (!scheduler.workers.has('deployApplication')) { - // scheduler.run('deployApplication'); - // } - // }, 2000) + setInterval(async () => { + if (!scheduler.workers.has('deployApplication')) { + scheduler.run('deployApplication'); + } + }, 2000) // Check for update & if no build is running setInterval(async () => { diff --git a/apps/api/src/jobs/checkProxies.ts b/apps/api/src/jobs/checkProxies.ts index 992281c3a..b493d7b83 100644 --- a/apps/api/src/jobs/checkProxies.ts +++ b/apps/api/src/jobs/checkProxies.ts @@ -5,6 +5,8 @@ import { checkContainer } from '../lib/docker'; (async () => { if (parentPort) { try { + const { default: isReachable } = await import('is-port-reachable'); + let portReachable; const { arch } = await listSettings(); // Coolify Proxy local const engine = '/var/run/docker.sock'; @@ -20,7 +22,11 @@ import { checkContainer } from '../lib/docker'; command: `docker stop -t 0 coolify-haproxy && docker rm coolify-haproxy` }) } - await startTraefikProxy(localDocker.id); + portReachable = await isReachable(80, { host: 'localhost' }) + console.log({ port: 80, portReachable }) + if (!portReachable) { + await startTraefikProxy(localDocker.id); + } } // TCP Proxies @@ -42,7 +48,11 @@ import { checkContainer } from '../lib/docker'; command: `docker stop -t 0 haproxy-for-${publicPort} && docker rm haproxy-for-${publicPort}` }) } - await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); + portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) + console.log({ publicPort, portReachable }) + if (!portReachable) { + await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); + } } } const wordpressWithFtp = await prisma.wordpress.findMany({ @@ -61,7 +71,11 @@ import { checkContainer } from '../lib/docker'; command: `docker stop -t 0 haproxy -for-${ftpPublicPort} && docker rm haproxy-for-${ftpPublicPort}` }) } - await startTraefikTCPProxy(destinationDocker, id, ftpPublicPort, 22, 'wordpressftp'); + portReachable = await isReachable(ftpPublicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) + console.log({ ftpPublicPort, portReachable }) + if (!portReachable) { + await startTraefikTCPProxy(destinationDocker, id, ftpPublicPort, 22, 'wordpressftp'); + } } } @@ -82,7 +96,11 @@ import { checkContainer } from '../lib/docker'; command: `docker stop -t 0 ${id}-${publicPort} && docker rm ${id}-${publicPort} ` }) } - await startTraefikTCPProxy(destinationDocker, id, publicPort, 9000); + portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) + console.log({ publicPort, portReachable }) + if (!portReachable) { + await startTraefikTCPProxy(destinationDocker, id, publicPort, 9000); + } } } From 27dfa24cfb5b356a4c774ce09b8de382480a7b2e Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 10:29:08 +0200 Subject: [PATCH 06/32] remove debug --- apps/api/src/jobs/checkProxies.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/api/src/jobs/checkProxies.ts b/apps/api/src/jobs/checkProxies.ts index b493d7b83..a394fc304 100644 --- a/apps/api/src/jobs/checkProxies.ts +++ b/apps/api/src/jobs/checkProxies.ts @@ -23,7 +23,6 @@ import { checkContainer } from '../lib/docker'; }) } portReachable = await isReachable(80, { host: 'localhost' }) - console.log({ port: 80, portReachable }) if (!portReachable) { await startTraefikProxy(localDocker.id); } @@ -49,7 +48,6 @@ import { checkContainer } from '../lib/docker'; }) } portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) - console.log({ publicPort, portReachable }) if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); } @@ -72,7 +70,6 @@ import { checkContainer } from '../lib/docker'; }) } portReachable = await isReachable(ftpPublicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) - console.log({ ftpPublicPort, portReachable }) if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, ftpPublicPort, 22, 'wordpressftp'); } @@ -97,7 +94,6 @@ import { checkContainer } from '../lib/docker'; }) } portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) - console.log({ publicPort, portReachable }) if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, publicPort, 9000); } From 8cb73e1680821db9655a6876223ca60f82938665 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 10:37:21 +0200 Subject: [PATCH 07/32] hmm --- apps/api/src/jobs/checkProxies.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/api/src/jobs/checkProxies.ts b/apps/api/src/jobs/checkProxies.ts index a394fc304..8f84cd78d 100644 --- a/apps/api/src/jobs/checkProxies.ts +++ b/apps/api/src/jobs/checkProxies.ts @@ -7,7 +7,7 @@ import { checkContainer } from '../lib/docker'; try { const { default: isReachable } = await import('is-port-reachable'); let portReachable; - const { arch } = await listSettings(); + const { arch, ipv4, ipv6 } = await listSettings(); // Coolify Proxy local const engine = '/var/run/docker.sock'; const localDocker = await prisma.destinationDocker.findFirst({ @@ -22,7 +22,7 @@ import { checkContainer } from '../lib/docker'; command: `docker stop -t 0 coolify-haproxy && docker rm coolify-haproxy` }) } - portReachable = await isReachable(80, { host: 'localhost' }) + portReachable = await isReachable(80, { host: ipv4 || ipv6 }) if (!portReachable) { await startTraefikProxy(localDocker.id); } @@ -47,7 +47,7 @@ import { checkContainer } from '../lib/docker'; command: `docker stop -t 0 haproxy-for-${publicPort} && docker rm haproxy-for-${publicPort}` }) } - portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) + portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); } @@ -69,7 +69,7 @@ import { checkContainer } from '../lib/docker'; command: `docker stop -t 0 haproxy -for-${ftpPublicPort} && docker rm haproxy-for-${ftpPublicPort}` }) } - portReachable = await isReachable(ftpPublicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) + portReachable = await isReachable(ftpPublicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, ftpPublicPort, 22, 'wordpressftp'); } @@ -93,7 +93,7 @@ import { checkContainer } from '../lib/docker'; command: `docker stop -t 0 ${id}-${publicPort} && docker rm ${id}-${publicPort} ` }) } - portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || 'localhost' }) + portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, publicPort, 9000); } From 9b613294ae445cc9f044b596782acaadd52f4155 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 10:43:01 +0200 Subject: [PATCH 08/32] debug cpu usage --- apps/api/src/jobs/checkProxies.ts | 41 +++++-------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/apps/api/src/jobs/checkProxies.ts b/apps/api/src/jobs/checkProxies.ts index 8f84cd78d..7ba6726ec 100644 --- a/apps/api/src/jobs/checkProxies.ts +++ b/apps/api/src/jobs/checkProxies.ts @@ -7,22 +7,16 @@ import { checkContainer } from '../lib/docker'; try { const { default: isReachable } = await import('is-port-reachable'); let portReachable; + const { arch, ipv4, ipv6 } = await listSettings(); // Coolify Proxy local const engine = '/var/run/docker.sock'; const localDocker = await prisma.destinationDocker.findFirst({ where: { engine, network: 'coolify' } }); - if (localDocker && localDocker.isCoolifyProxyUsed) { - // Remove HAProxy - const found = await checkContainer({ dockerId: localDocker.id, container: 'coolify-haproxy' }); - if (found) { - await executeDockerCmd({ - dockerId: localDocker.id, - command: `docker stop -t 0 coolify-haproxy && docker rm coolify-haproxy` - }) - } + if (localDocker && localDocker.isCoolifyProxyUsed) { portReachable = await isReachable(80, { host: ipv4 || ipv6 }) + console.log({ port: 80, portReachable }); if (!portReachable) { await startTraefikProxy(localDocker.id); } @@ -37,17 +31,8 @@ import { checkContainer } from '../lib/docker'; const { destinationDockerId, destinationDocker, publicPort, id } = database; if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { const { privatePort } = generateDatabaseConfiguration(database, arch); - // Remove HAProxy - const found = await checkContainer({ - dockerId: localDocker.id, container: `haproxy-for-${publicPort}` - }); - if (found) { - await executeDockerCmd({ - dockerId: localDocker.id, - command: `docker stop -t 0 haproxy-for-${publicPort} && docker rm haproxy-for-${publicPort}` - }) - } portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) + console.log({ publicPort, portReachable }); if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); } @@ -61,15 +46,8 @@ import { checkContainer } from '../lib/docker'; const { service, ftpPublicPort } = ftp; const { destinationDockerId, destinationDocker, id } = service; if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { - // Remove HAProxy - const found = await checkContainer({ dockerId: localDocker.id, container: `haproxy-for-${ftpPublicPort}` }); - if (found) { - await executeDockerCmd({ - dockerId: localDocker.id, - command: `docker stop -t 0 haproxy -for-${ftpPublicPort} && docker rm haproxy-for-${ftpPublicPort}` - }) - } portReachable = await isReachable(ftpPublicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) + console.log({ ftpPublicPort, portReachable }); if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, ftpPublicPort, 22, 'wordpressftp'); } @@ -85,15 +63,8 @@ import { checkContainer } from '../lib/docker'; const { service, publicPort } = minio; const { destinationDockerId, destinationDocker, id } = service; if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { - // Remove HAProxy - const found = await checkContainer({ dockerId: localDocker.id, container: `${id}-${publicPort}` }); - if (found) { - await executeDockerCmd({ - dockerId: localDocker.id, - command: `docker stop -t 0 ${id}-${publicPort} && docker rm ${id}-${publicPort} ` - }) - } portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) + console.log({ publicPort, portReachable }); if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, publicPort, 9000); } From c80ebf73ee463f936146beecfca1c8c2aaafaa50 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 10:47:58 +0200 Subject: [PATCH 09/32] hmm --- apps/api/src/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 3f4876c94..5492331e6 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -107,11 +107,11 @@ fastify.listen({ port, host }, async (err: any, address: any) => { await scheduler.start('cleanupPrismaEngines'); await scheduler.start('checkProxies'); - setInterval(async () => { - if (!scheduler.workers.has('deployApplication')) { - scheduler.run('deployApplication'); - } - }, 2000) + // setInterval(async () => { + // if (!scheduler.workers.has('deployApplication')) { + // scheduler.run('deployApplication'); + // } + // }, 2000) // Check for update & if no build is running setInterval(async () => { From 055db97273e1b23eb7d41f3917e2ff080f288a59 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 10:53:04 +0200 Subject: [PATCH 10/32] hm --- apps/api/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 5492331e6..6130ebf7f 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -104,8 +104,8 @@ fastify.listen({ port, host }, async (err: any, address: any) => { } console.log(`Coolify's API is listening on ${host}:${port}`); await initServer(); - await scheduler.start('cleanupPrismaEngines'); - await scheduler.start('checkProxies'); + // await scheduler.start('cleanupPrismaEngines'); + // await scheduler.start('checkProxies'); // setInterval(async () => { // if (!scheduler.workers.has('deployApplication')) { From 57b462223c22f0d292e5b10485fa9d142cf13e9c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 11:09:38 +0200 Subject: [PATCH 11/32] test --- apps/api/src/index.ts | 1 + apps/api/src/jobs/test.ts | 15 +++++++++++++++ apps/api/src/lib/scheduler.ts | 1 + 3 files changed, 17 insertions(+) create mode 100644 apps/api/src/jobs/test.ts diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 6130ebf7f..52b4bfd50 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -104,6 +104,7 @@ fastify.listen({ port, host }, async (err: any, address: any) => { } console.log(`Coolify's API is listening on ${host}:${port}`); await initServer(); + await scheduler.start('test'); // await scheduler.start('cleanupPrismaEngines'); // await scheduler.start('checkProxies'); diff --git a/apps/api/src/jobs/test.ts b/apps/api/src/jobs/test.ts new file mode 100644 index 000000000..2d0fc44c3 --- /dev/null +++ b/apps/api/src/jobs/test.ts @@ -0,0 +1,15 @@ +import { parentPort } from 'node:worker_threads';; + +(async () => { + if (parentPort) { + parentPort.on('message', async (message) => { + if (message === 'error') throw new Error('oops'); + if (message === 'cancel') { + parentPort.postMessage('cancelled'); + process.exit(0); + } + }); + console.log('test job started'); + process.exit(0) + } else process.exit(0); +})(); diff --git a/apps/api/src/lib/scheduler.ts b/apps/api/src/lib/scheduler.ts index 6c233d050..efe12d5c0 100644 --- a/apps/api/src/lib/scheduler.ts +++ b/apps/api/src/lib/scheduler.ts @@ -18,6 +18,7 @@ const options: any = { } }, jobs: [ + { name: 'test' }, { name: 'deployApplication', }, From c99f74b351eeba1670ddf8dc4a995d5216fb2703 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 11:49:19 +0200 Subject: [PATCH 12/32] debug --- apps/api/src/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 52b4bfd50..14833c826 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -108,6 +108,11 @@ fastify.listen({ port, host }, async (err: any, address: any) => { // await scheduler.start('cleanupPrismaEngines'); // await scheduler.start('checkProxies'); + setInterval(async () => { + if (!scheduler.workers.has('test')) { + scheduler.run('test'); + } + }, 2000) // setInterval(async () => { // if (!scheduler.workers.has('deployApplication')) { // scheduler.run('deployApplication'); From 8e6423e873ebba16df7ca2e362732013228c8ad8 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 11:54:23 +0200 Subject: [PATCH 13/32] hmm --- apps/api/src/index.ts | 10 +++++----- apps/api/src/lib/scheduler.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 14833c826..fb825d42d 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -108,11 +108,11 @@ fastify.listen({ port, host }, async (err: any, address: any) => { // await scheduler.start('cleanupPrismaEngines'); // await scheduler.start('checkProxies'); - setInterval(async () => { - if (!scheduler.workers.has('test')) { - scheduler.run('test'); - } - }, 2000) + // setInterval(async () => { + // if (!scheduler.workers.has('test')) { + // scheduler.run('test'); + // } + // }, 2000) // setInterval(async () => { // if (!scheduler.workers.has('deployApplication')) { // scheduler.run('deployApplication'); diff --git a/apps/api/src/lib/scheduler.ts b/apps/api/src/lib/scheduler.ts index efe12d5c0..2460b83d8 100644 --- a/apps/api/src/lib/scheduler.ts +++ b/apps/api/src/lib/scheduler.ts @@ -18,7 +18,7 @@ const options: any = { } }, jobs: [ - { name: 'test' }, + { name: 'test',interval: '2s' }, { name: 'deployApplication', }, From 7c8ffd510e412fff2ab30c3173c4de0206050039 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 11:59:56 +0200 Subject: [PATCH 14/32] asd --- apps/api/src/index.ts | 1 - apps/api/src/lib/scheduler.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index fb825d42d..69efb7af0 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -104,7 +104,6 @@ fastify.listen({ port, host }, async (err: any, address: any) => { } console.log(`Coolify's API is listening on ${host}:${port}`); await initServer(); - await scheduler.start('test'); // await scheduler.start('cleanupPrismaEngines'); // await scheduler.start('checkProxies'); diff --git a/apps/api/src/lib/scheduler.ts b/apps/api/src/lib/scheduler.ts index 2460b83d8..6c233d050 100644 --- a/apps/api/src/lib/scheduler.ts +++ b/apps/api/src/lib/scheduler.ts @@ -18,7 +18,6 @@ const options: any = { } }, jobs: [ - { name: 'test',interval: '2s' }, { name: 'deployApplication', }, From 0dc521206659cea85800d692a9df9f4a406f153e Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 12:25:46 +0200 Subject: [PATCH 15/32] Revert things --- apps/api/src/index.ts | 19 +++++++------------ apps/api/src/jobs/deployApplication.ts | 7 +------ apps/api/src/jobs/test.ts | 15 --------------- 3 files changed, 8 insertions(+), 33 deletions(-) delete mode 100644 apps/api/src/jobs/test.ts diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 69efb7af0..3f4876c94 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -104,19 +104,14 @@ fastify.listen({ port, host }, async (err: any, address: any) => { } console.log(`Coolify's API is listening on ${host}:${port}`); await initServer(); - // await scheduler.start('cleanupPrismaEngines'); - // await scheduler.start('checkProxies'); + await scheduler.start('cleanupPrismaEngines'); + await scheduler.start('checkProxies'); - // setInterval(async () => { - // if (!scheduler.workers.has('test')) { - // scheduler.run('test'); - // } - // }, 2000) - // setInterval(async () => { - // if (!scheduler.workers.has('deployApplication')) { - // scheduler.run('deployApplication'); - // } - // }, 2000) + setInterval(async () => { + if (!scheduler.workers.has('deployApplication')) { + scheduler.run('deployApplication'); + } + }, 2000) // Check for update & if no build is running setInterval(async () => { diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index 261f8bd32..ca0154649 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -347,14 +347,9 @@ import * as buildpacks from '../lib/buildPacks'; } }); } - await pAll.default(actions, { concurrency }) } - - } catch (error) { - process.exit(0); - - } finally { + } catch (error) { } finally { await prisma.$disconnect(); process.exit(0); } diff --git a/apps/api/src/jobs/test.ts b/apps/api/src/jobs/test.ts deleted file mode 100644 index 2d0fc44c3..000000000 --- a/apps/api/src/jobs/test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { parentPort } from 'node:worker_threads';; - -(async () => { - if (parentPort) { - parentPort.on('message', async (message) => { - if (message === 'error') throw new Error('oops'); - if (message === 'cancel') { - parentPort.postMessage('cancelled'); - process.exit(0); - } - }); - console.log('test job started'); - process.exit(0) - } else process.exit(0); -})(); From 6b65d435fb4f42bc8de5b277035cef974a943943 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 12:32:50 +0200 Subject: [PATCH 16/32] hmn --- apps/api/src/jobs/checkProxies.ts | 1 - apps/api/src/jobs/deployApplication.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/api/src/jobs/checkProxies.ts b/apps/api/src/jobs/checkProxies.ts index 7ba6726ec..32db9e07e 100644 --- a/apps/api/src/jobs/checkProxies.ts +++ b/apps/api/src/jobs/checkProxies.ts @@ -74,7 +74,6 @@ import { checkContainer } from '../lib/docker'; } catch (error) { } finally { - await prisma.$disconnect(); } } else process.exit(0); diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index ca0154649..fc3e5ab55 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -350,7 +350,6 @@ import * as buildpacks from '../lib/buildPacks'; await pAll.default(actions, { concurrency }) } } catch (error) { } finally { - await prisma.$disconnect(); process.exit(0); } } else process.exit(0); From be594dd49eea4c19375540b71ccce758990b699a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 12:44:04 +0200 Subject: [PATCH 17/32] revert test --- apps/api/src/jobs/checkProxies.ts | 1 + apps/api/src/jobs/deployApplication.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/api/src/jobs/checkProxies.ts b/apps/api/src/jobs/checkProxies.ts index 32db9e07e..7ba6726ec 100644 --- a/apps/api/src/jobs/checkProxies.ts +++ b/apps/api/src/jobs/checkProxies.ts @@ -74,6 +74,7 @@ import { checkContainer } from '../lib/docker'; } catch (error) { } finally { + await prisma.$disconnect(); } } else process.exit(0); diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index fc3e5ab55..ca0154649 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -350,6 +350,7 @@ import * as buildpacks from '../lib/buildPacks'; await pAll.default(actions, { concurrency }) } } catch (error) { } finally { + await prisma.$disconnect(); process.exit(0); } } else process.exit(0); From 71c15e0ff5313e8eb4d8cf7776153b398a84a449 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 25 Aug 2022 12:49:09 +0000 Subject: [PATCH 18/32] fix: worker --- apps/api/package.json | 1 + apps/api/src/jobs/deployApplication.ts | 662 ++++++++++---------- apps/api/src/lib/common.ts | 25 +- pnpm-lock.yaml | 796 +++++++++++++++++++------ 4 files changed, 974 insertions(+), 510 deletions(-) diff --git a/apps/api/package.json b/apps/api/package.json index f9766c5b5..3fe675596 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -44,6 +44,7 @@ "node-forge": "1.3.1", "node-os-utils": "1.3.7", "p-all": "4.0.0", + "p-throttle": "5.0.0", "public-ip": "6.0.1", "ssh-config": "4.1.6", "strip-ansi": "7.0.1", diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index ca0154649..d5d4a6d2f 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -18,340 +18,354 @@ import * as buildpacks from '../lib/buildPacks'; } }); try { - parentPort.postMessage({ deploying: true }); - const queuedBuilds = await prisma.build.findMany({ where: { status: 'queued' }, orderBy: { createdAt: 'asc' } }); - const { concurrentBuilds } = await prisma.setting.findFirst({}) - if (queuedBuilds.length > 0) { - const concurrency = concurrentBuilds; - const pAll = await import('p-all'); - const actions = [] + const pThrottle = await import('p-throttle') + const throttle = pThrottle.default({ + limit: 1, + interval: 2000 + }); - 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'); - try { - const { debug } = settings; - if (concurrency === 1) { - await prisma.build.updateMany({ - where: { - status: { in: ['queued', 'running'] }, - id: { not: buildId }, - applicationId, - createdAt: { lt: new Date(new Date().getTime() - 10 * 1000) } - }, - data: { status: 'failed' } - }); - } - let imageId = applicationId; - let domain = getDomain(fqdn); - const volumes = - persistentStorage?.map((storage) => { - return `${applicationId}${storage.path.replace(/\//gi, '-')}:${buildPack !== 'docker' ? '/app' : '' - }${storage.path}`; - }) || []; - // Previews, we need to get the source branch and set subdomain - if (pullmergeRequestId) { - branch = sourceBranch; - domain = `${pullmergeRequestId}.${domain}`; - imageId = `${applicationId}-${pullmergeRequestId}`; - } + const th = throttle(async () => { + const queuedBuilds = await prisma.build.findMany({ where: { status: 'queued' }, orderBy: { createdAt: 'asc' } }); + const { concurrentBuilds } = await prisma.setting.findFirst({}) + if (queuedBuilds.length > 0) { + parentPort.postMessage({ deploying: true }); + const concurrency = concurrentBuilds; + const pAll = await import('p-all'); + const actions = [] - let deployNeeded = true; - let destinationType; - - if (destinationDockerId) { - destinationType = 'docker'; - } - if (destinationType === 'docker') { - await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } }); - const { workdir, repodir } = await createDirectories({ repository, buildId }); - const configuration = await setDefaultConfiguration(application); - - buildPack = configuration.buildPack; - port = configuration.port; - installCommand = configuration.installCommand; - startCommand = configuration.startCommand; - buildCommand = configuration.buildCommand; - publishDirectory = configuration.publishDirectory; - baseDirectory = configuration.baseDirectory; - dockerFileLocation = configuration.dockerFileLocation; - denoMainFile = configuration.denoMainFile; - const commit = await importers[gitSource.type]({ - applicationId, - debug, - workdir, - repodir, - githubAppId: gitSource.githubApp?.id, - gitlabAppId: gitSource.gitlabApp?.id, - customPort: gitSource.customPort, - repository, - branch, - buildId, - apiUrl: gitSource.apiUrl, - htmlUrl: gitSource.htmlUrl, - projectId, - deployKeyId: gitSource.gitlabApp?.deployKeyId || null, - privateSshKey: decrypt(gitSource.gitlabApp?.privateSshKey) || null, - forPublic: gitSource.forPublic - }); - if (!commit) { - throw new Error('No commit found?'); - } - let tag = commit.slice(0, 7); - if (pullmergeRequestId) { - tag = `${commit.slice(0, 7)}-${pullmergeRequestId}`; - } - - try { - await prisma.build.update({ where: { id: buildId }, data: { commit } }); - } catch (err) { - console.log(err); - } - - if (!pullmergeRequestId) { - if (configHash !== currentHash) { - deployNeeded = true; - if (configHash) { - await saveBuildLog({ line: 'Configuration changed.', buildId, applicationId }); - } - } else { - deployNeeded = false; - } - } else { - deployNeeded = true; - } - - let imageFound = false; - try { - await executeDockerCmd({ - dockerId: destinationDocker.id, - command: `docker image inspect ${applicationId}:${tag}` + 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 }) - imageFound = true; - } catch (error) { - // - } - await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage); - - if (forceRebuild) deployNeeded = true - if (!imageFound || deployNeeded) { - // if (true) { - if (buildpacks[buildPack]) - await buildpacks[buildPack]({ - dockerId: destinationDocker.id, - buildId, - applicationId, - domain, - name, - type, - pullmergeRequestId, - buildPack, - repository, - branch, - projectId, - publishDirectory, - debug, - commit, - tag, - workdir, - port: exposePort ? `${exposePort}:${port}` : port, - installCommand, - buildCommand, - startCommand, - baseDirectory, - secrets, - phpModules, - pythonWSGI, - pythonModule, - pythonVariable, - dockerFileLocation, - denoMainFile, - denoOptions, - baseImage, - baseBuildImage, - deploymentType - }); - else { - await saveBuildLog({ line: `Build pack ${buildPack} not found`, buildId, applicationId }); - throw new Error(`Build pack ${buildPack} not found.`); - } - } else { - await saveBuildLog({ line: 'Build image already available - no rebuild required.', buildId, applicationId }); - } - try { - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker stop -t 0 ${imageId}` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker rm ${imageId}` }) - } catch (error) { - // - } - const envs = [ - `PORT=${port}` - ]; - if (secrets.length > 0) { - secrets.forEach((secret) => { - if (pullmergeRequestId) { - if (secret.isPRMRSecret) { - envs.push(`${secret.name}=${secret.value}`); - } - } else { - if (!secret.isPRMRSecret) { - envs.push(`${secret.name}=${secret.value}`); - } - } - }); - } - await fs.writeFile(`${workdir}/.env`, envs.join('\n')); - const labels = makeLabelForStandaloneApplication({ - applicationId, - fqdn, - name, - type, - pullmergeRequestId, - buildPack, - repository, - branch, - projectId, - port: exposePort ? `${exposePort}:${port}` : port, - commit, - installCommand, - buildCommand, - startCommand, - baseDirectory, - publishDirectory - }); - let envFound = false; - try { - envFound = !!(await fs.stat(`${workdir}/.env`)); - } catch (error) { - // - } - try { - await saveBuildLog({ line: 'Deployment started.', buildId, applicationId }); - const composeVolumes = volumes.map((volume) => { - return { - [`${volume.split(':')[0]}`]: { - name: volume.split(':')[0] - } - }; - }); - const composeFile = { - version: '3.8', - services: { - [imageId]: { - image: `${applicationId}:${tag}`, - container_name: imageId, - volumes, - env_file: envFound ? [`${workdir}/.env`] : [], - labels, - depends_on: [], - expose: [port], - ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), - // logging: { - // driver: 'fluentd', - // }, - ...defaultComposeConfiguration(destinationDocker.network), - } - }, - networks: { - [destinationDocker.network]: { - external: true - } - }, - volumes: Object.assign({}, ...composeVolumes) - }; - await fs.writeFile(`${workdir}/docker-compose.yml`, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose --project-directory ${workdir} up -d` }) - await saveBuildLog({ line: 'Deployment successful!', buildId, applicationId }); - } catch (error) { - await saveBuildLog({ line: error, buildId, applicationId }); + ) + .digest('hex'); + try { + const { debug } = settings; + if (concurrency === 1) { await prisma.build.updateMany({ - where: { id: buildId, status: { in: ['queued', 'running'] } }, + where: { + status: { in: ['queued', 'running'] }, + id: { not: buildId }, + applicationId, + createdAt: { lt: new Date(new Date().getTime() - 10 * 1000) } + }, data: { status: 'failed' } }); - throw new Error(error); } - await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId }); - await prisma.build.update({ where: { id: buildId }, data: { status: 'success' } }); - if (!pullmergeRequestId) await prisma.application.update({ - where: { id: applicationId }, - data: { configHash: currentHash } - }); + let imageId = applicationId; + let domain = getDomain(fqdn); + const volumes = + persistentStorage?.map((storage) => { + return `${applicationId}${storage.path.replace(/\//gi, '-')}:${buildPack !== 'docker' ? '/app' : '' + }${storage.path}`; + }) || []; + // Previews, we need to get the source branch and set subdomain + if (pullmergeRequestId) { + branch = sourceBranch; + domain = `${pullmergeRequestId}.${domain}`; + imageId = `${applicationId}-${pullmergeRequestId}`; + } + + let deployNeeded = true; + let destinationType; + + if (destinationDockerId) { + destinationType = 'docker'; + } + if (destinationType === 'docker') { + await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } }); + const { workdir, repodir } = await createDirectories({ repository, buildId }); + const configuration = await setDefaultConfiguration(application); + + buildPack = configuration.buildPack; + port = configuration.port; + installCommand = configuration.installCommand; + startCommand = configuration.startCommand; + buildCommand = configuration.buildCommand; + publishDirectory = configuration.publishDirectory; + baseDirectory = configuration.baseDirectory; + dockerFileLocation = configuration.dockerFileLocation; + denoMainFile = configuration.denoMainFile; + const commit = await importers[gitSource.type]({ + applicationId, + debug, + workdir, + repodir, + githubAppId: gitSource.githubApp?.id, + gitlabAppId: gitSource.gitlabApp?.id, + customPort: gitSource.customPort, + repository, + branch, + buildId, + apiUrl: gitSource.apiUrl, + htmlUrl: gitSource.htmlUrl, + projectId, + deployKeyId: gitSource.gitlabApp?.deployKeyId || null, + privateSshKey: decrypt(gitSource.gitlabApp?.privateSshKey) || null, + forPublic: gitSource.forPublic + }); + if (!commit) { + throw new Error('No commit found?'); + } + let tag = commit.slice(0, 7); + if (pullmergeRequestId) { + tag = `${commit.slice(0, 7)}-${pullmergeRequestId}`; + } + + try { + await prisma.build.update({ where: { id: buildId }, data: { commit } }); + } catch (err) { + console.log(err); + } + + if (!pullmergeRequestId) { + if (configHash !== currentHash) { + deployNeeded = true; + if (configHash) { + await saveBuildLog({ line: 'Configuration changed.', buildId, applicationId }); + } + } else { + deployNeeded = false; + } + } else { + deployNeeded = true; + } + + let imageFound = false; + try { + await executeDockerCmd({ + dockerId: destinationDocker.id, + command: `docker image inspect ${applicationId}:${tag}` + }) + imageFound = true; + } catch (error) { + // + } + await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage); + + if (forceRebuild) deployNeeded = true + if (!imageFound || deployNeeded) { + // if (true) { + if (buildpacks[buildPack]) + await buildpacks[buildPack]({ + dockerId: destinationDocker.id, + buildId, + applicationId, + domain, + name, + type, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + publishDirectory, + debug, + commit, + tag, + workdir, + port: exposePort ? `${exposePort}:${port}` : port, + installCommand, + buildCommand, + startCommand, + baseDirectory, + secrets, + phpModules, + pythonWSGI, + pythonModule, + pythonVariable, + dockerFileLocation, + denoMainFile, + denoOptions, + baseImage, + baseBuildImage, + deploymentType + }); + else { + await saveBuildLog({ line: `Build pack ${buildPack} not found`, buildId, applicationId }); + throw new Error(`Build pack ${buildPack} not found.`); + } + } else { + await saveBuildLog({ line: 'Build image already available - no rebuild required.', buildId, applicationId }); + } + try { + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker stop -t 0 ${imageId}` }) + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker rm ${imageId}` }) + } catch (error) { + // + } + const envs = [ + `PORT=${port}` + ]; + if (secrets.length > 0) { + secrets.forEach((secret) => { + if (pullmergeRequestId) { + if (secret.isPRMRSecret) { + envs.push(`${secret.name}=${secret.value}`); + } + } else { + if (!secret.isPRMRSecret) { + envs.push(`${secret.name}=${secret.value}`); + } + } + }); + } + await fs.writeFile(`${workdir}/.env`, envs.join('\n')); + const labels = makeLabelForStandaloneApplication({ + applicationId, + fqdn, + name, + type, + pullmergeRequestId, + buildPack, + repository, + branch, + projectId, + port: exposePort ? `${exposePort}:${port}` : port, + commit, + installCommand, + buildCommand, + startCommand, + baseDirectory, + publishDirectory + }); + let envFound = false; + try { + envFound = !!(await fs.stat(`${workdir}/.env`)); + } catch (error) { + // + } + try { + await saveBuildLog({ line: 'Deployment started.', buildId, applicationId }); + const composeVolumes = volumes.map((volume) => { + return { + [`${volume.split(':')[0]}`]: { + name: volume.split(':')[0] + } + }; + }); + const composeFile = { + version: '3.8', + services: { + [imageId]: { + image: `${applicationId}:${tag}`, + container_name: imageId, + volumes, + env_file: envFound ? [`${workdir}/.env`] : [], + labels, + depends_on: [], + expose: [port], + ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), + // logging: { + // driver: 'fluentd', + // }, + ...defaultComposeConfiguration(destinationDocker.network), + } + }, + networks: { + [destinationDocker.network]: { + external: true + } + }, + volumes: Object.assign({}, ...composeVolumes) + }; + await fs.writeFile(`${workdir}/docker-compose.yml`, yaml.dump(composeFile)); + await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose --project-directory ${workdir} up -d` }) + await saveBuildLog({ line: 'Deployment successful!', buildId, applicationId }); + } catch (error) { + await saveBuildLog({ line: error, buildId, applicationId }); + await prisma.build.updateMany({ + where: { id: buildId, status: { in: ['queued', 'running'] } }, + data: { status: 'failed' } + }); + throw new Error(error); + } + await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId }); + await prisma.build.update({ where: { id: buildId }, data: { status: 'success' } }); + if (!pullmergeRequestId) await prisma.application.update({ + where: { id: applicationId }, + data: { configHash: currentHash } + }); + } } - } - catch (error) { - await prisma.build.updateMany({ - where: { id: buildId, status: { in: ['queued', 'running'] } }, - data: { status: 'failed' } - }); - await saveBuildLog({ line: error, buildId, applicationId }); - } - }); + catch (error) { + await prisma.build.updateMany({ + where: { id: buildId, status: { in: ['queued', 'running'] } }, + data: { status: 'failed' } + }); + await saveBuildLog({ line: error, buildId, applicationId }); + } + }); + } + await pAll.default(actions, { concurrency }) } - await pAll.default(actions, { concurrency }) + }) + while (true) { + await th() } - } catch (error) { } finally { - await prisma.$disconnect(); - process.exit(0); + + } catch (error) { + } finally { + await prisma.$disconnect() } + + } else process.exit(0); })(); diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index 5d48c3f3b..cceca5ba7 100644 --- a/apps/api/src/lib/common.ts +++ b/apps/api/src/lib/common.ts @@ -134,9 +134,32 @@ export const asyncExecShellStream = async ({ debug, buildId, applicationId, comm export const asyncSleep = (delay: number): Promise => new Promise((resolve) => setTimeout(resolve, delay)); export const prisma = new PrismaClient({ - errorFormat: 'minimal' + errorFormat: 'minimal', + log: [ + { + emit: 'event', + level: 'query', + }, + { + emit: 'stdout', + level: 'error', + }, + { + emit: 'stdout', + level: 'info', + }, + { + emit: 'stdout', + level: 'warn', + }, + ], }); +// prisma.$on('query', (e) => { +// console.log('Query: ' + e.query) +// console.log('Params: ' + e.params) +// console.log('Duration: ' + e.duration + 'ms') +// }) export const base64Encode = (text: string): string => { return Buffer.from(text).toString('base64'); }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9fd8a9e23..bea7b8797 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,11 +6,9 @@ importers: specifiers: cross-var: 1.1.0 npm-run-all: 4.1.5 - opencollective-setup: 1.4.1 devDependencies: cross-var: 1.1.0 npm-run-all: 4.1.5 - opencollective-setup: 1.4.1 apps/api: specifiers: @@ -53,17 +51,19 @@ importers: node-os-utils: 1.3.7 nodemon: 2.0.19 p-all: 4.0.0 + p-throttle: ^5.0.0 prettier: 2.7.1 prisma: 3.15.2 public-ip: 6.0.1 rimraf: 3.0.2 + sqlite3: ^5.0.11 ssh-config: 4.1.6 strip-ansi: 7.0.1 tsconfig-paths: 4.1.0 typescript: 4.7.4 unique-names-generator: 4.7.1 dependencies: - '@breejs/ts-worker': 2.0.0_rzqxabipis2a5sxrpk4obdh4zu + '@breejs/ts-worker': 2.0.0_yjs2yukaec33oijlee4f5n7fqa '@fastify/autoload': 5.2.0 '@fastify/cookie': 8.0.0 '@fastify/cors': 8.1.0 @@ -93,7 +93,9 @@ importers: node-forge: 1.3.1 node-os-utils: 1.3.7 p-all: 4.0.0 + p-throttle: 5.0.0 public-ip: 6.0.1 + sqlite3: 5.0.11 ssh-config: 4.1.6 strip-ansi: 7.0.1 unique-names-generator: 4.7.1 @@ -166,7 +168,7 @@ importers: svelte: 3.49.0 svelte-check: 2.8.1_vylzxgme5yisu3bsyvcau4hjtq svelte-preprocess: 4.10.7_fje22ktja5v2dh6nbkissncqme - tailwindcss: 3.1.8 + tailwindcss: 3.1.8_postcss@8.4.16 tailwindcss-scrollbar: 0.1.0_tailwindcss@3.1.8 tslib: 2.4.0 typescript: 4.7.4 @@ -211,11 +213,12 @@ packages: engines: {node: '>= 10'} dev: false - /@breejs/ts-worker/2.0.0_rzqxabipis2a5sxrpk4obdh4zu: + /@breejs/ts-worker/2.0.0_yjs2yukaec33oijlee4f5n7fqa: resolution: {integrity: sha512-6anHRcmgYlF7mrm/YVRn6rx2cegLuiY3VBxkkimOTWC/dVQeH336imVSuIKEGKTwiuNTPr2hswVdDSneNuXg3A==} engines: {node: '>= 12.11'} peerDependencies: bree: '>=9.0.0' + tsconfig-paths: '>= 4' dependencies: bree: 9.1.2 ts-node: 10.8.2_57uwcby55h6tzvkj3v5sfcgxoe @@ -334,6 +337,11 @@ packages: - supports-color dev: false + /@gar/promisify/1.1.3: + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + dev: false + optional: true + /@humanwhocodes/config-array/0.10.4: resolution: {integrity: sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==} engines: {node: '>=10.10.0'} @@ -383,6 +391,24 @@ packages: engines: {node: '>=8'} dev: false + /@mapbox/node-pre-gyp/1.0.9: + resolution: {integrity: sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==} + hasBin: true + dependencies: + detect-libc: 2.0.1 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.6.7 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.3.7 + tar: 6.1.11 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -401,6 +427,23 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 + /@npmcli/fs/1.1.1: + resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.3.7 + dev: false + optional: true + + /@npmcli/move-file/1.1.2: + resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} + engines: {node: '>=10'} + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + dev: false + optional: true + /@playwright/test/1.25.1: resolution: {integrity: sha512-IJ4X0yOakXtwkhbnNzKkaIgXe6df7u3H3FnuhI9Jqh+CdO0e/lYQlDLYiyI9cnXK8E7UAppAWP+VqAv6VX7HQg==} engines: {node: '>=14'} @@ -513,6 +556,12 @@ packages: defer-to-connect: 2.0.1 dev: false + /@tootallnate/once/1.1.2: + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + dev: false + optional: true + /@tsconfig/node10/1.0.8: resolution: {integrity: sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==} dev: false @@ -719,7 +768,6 @@ packages: /abbrev/1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - dev: true /abort-controller/3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -766,6 +814,36 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /agent-base/6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /agentkeepalive/4.2.1: + resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==} + engines: {node: '>= 8.0.0'} + dependencies: + debug: 4.3.4 + depd: 1.1.2 + humanize-ms: 1.2.1 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + + /aggregate-error/3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: false + optional: true + /aggregate-error/4.0.1: resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} engines: {node: '>=12'} @@ -806,27 +884,14 @@ packages: engines: {node: '>=6'} dev: false - /ansi-escapes/4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: true - /ansi-regex/2.1.1: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} dev: true - /ansi-regex/4.1.1: - resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} - engines: {node: '>=6'} - dev: true - /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - dev: true /ansi-regex/6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} @@ -858,10 +923,31 @@ packages: normalize-path: 3.0.0 picomatch: 2.3.1 + /aproba/2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: false + /archy/1.0.0: resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} dev: false + /are-we-there-yet/2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.0 + dev: false + + /are-we-there-yet/3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.0 + dev: false + optional: true + /arg/4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: false @@ -1682,7 +1768,6 @@ packages: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - dev: true /brace-expansion/2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -1767,6 +1852,33 @@ packages: - supports-color dev: false + /cacache/15.3.0: + resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} + engines: {node: '>= 10'} + dependencies: + '@npmcli/fs': 1.1.1 + '@npmcli/move-file': 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.2.3 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.3.4 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.1.11 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + dev: false + optional: true + /cacheable-lookup/6.0.4: resolution: {integrity: sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A==} engines: {node: '>=10.6.0'} @@ -1835,10 +1947,6 @@ packages: supports-color: 7.2.0 dev: true - /chardet/0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: true - /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -1857,6 +1965,17 @@ packages: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} dev: false + /chownr/2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: false + + /clean-stack/2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: false + optional: true + /clean-stack/4.2.0: resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} engines: {node: '>=12'} @@ -1869,17 +1988,6 @@ packages: hasBin: true dev: false - /cli-cursor/3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: true - - /cli-width/2.2.1: - resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} - dev: true - /clone-regexp/3.0.0: resolution: {integrity: sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==} engines: {node: '>=12'} @@ -1917,6 +2025,11 @@ packages: simple-swizzle: 0.2.2 dev: false + /color-support/1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: false + /color/4.2.3: resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} engines: {node: '>=12.5.0'} @@ -1957,7 +2070,10 @@ packages: /concat-map/0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true + + /console-control-strings/1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: false /console-polyfill/0.3.0: resolution: {integrity: sha512-w+JSDZS7XML43Xnwo2x5O5vxB0ID7T5BdqDtyqT6uiCAX2kZAgcWxNaGqT97tZfSHzfOcvrfsDAodKcJ3UvnXQ==} @@ -2101,7 +2217,7 @@ packages: css-selector-tokenizer: 0.8.0 postcss: 8.4.16 postcss-js: 4.0.0_postcss@8.4.16 - tailwindcss: 3.1.8 + tailwindcss: 3.1.8_postcss@8.4.16 transitivePeerDependencies: - ts-node dev: false @@ -2132,18 +2248,6 @@ packages: supports-color: 5.5.0 dev: true - /debug/4.1.1: - resolution: {integrity: sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==} - deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - /debug/4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -2191,6 +2295,16 @@ packages: engines: {node: '>=0.4.0'} dev: false + /delegates/1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: false + + /depd/1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + dev: false + optional: true + /depd/2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -2208,16 +2322,16 @@ packages: repeating: 2.0.1 dev: true - /detect-indent/6.0.0: - resolution: {integrity: sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==} - engines: {node: '>=8'} - dev: true - /detect-indent/6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} dev: true + /detect-libc/2.0.1: + resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} + engines: {node: '>=8'} + dev: false + /detective/5.2.1: resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} engines: {node: '>=0.8.0'} @@ -2343,19 +2457,33 @@ packages: /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true + dev: false /encodeurl/1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} dev: false + /encoding/0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + requiresBuild: true + dependencies: + iconv-lite: 0.6.3 + dev: false + optional: true + /end-of-stream/1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 dev: false + /env-paths/2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: false + optional: true + /env-schema/5.0.0: resolution: {integrity: sha512-91u95Nlny+LmjF3Mk96j8k6k+GOXcFEdMUv3bWQjtM2l+KTAdW6qITiv8kHYO8vCaCScXpJTDyd1AFnCQTnYaQ==} dependencies: @@ -2364,6 +2492,11 @@ packages: dotenv-expand: 8.0.3 dev: false + /err-code/2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + dev: false + optional: true + /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: @@ -3042,15 +3175,6 @@ packages: engines: {node: '>= 0.8.0'} dev: true - /external-editor/3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: true - /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -3163,13 +3287,6 @@ packages: xtend: 4.0.2 dev: false - /figures/3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - dependencies: - escape-string-regexp: 1.0.5 - dev: true - /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -3280,6 +3397,13 @@ packages: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} dev: false + /fs-minipass/2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + dev: false + /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -3322,6 +3446,36 @@ packages: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true + /gauge/3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: false + + /gauge/4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: false + optional: true + /generate-password/1.7.0: resolution: {integrity: sha512-WPCtlfy0jexf7W5IbwxGUgpIDvsZIohbI2DAq2Q6TSlKKis+G4GT9sxvPxrZUGL8kP6WUXMWNqYnxY6DDKAdFA==} dev: false @@ -3374,7 +3528,6 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true /glob/8.0.3: resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} @@ -3440,7 +3593,6 @@ packages: /graceful-fs/4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true /grapheme-splitter/1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} @@ -3483,6 +3635,10 @@ packages: has-symbols: 1.0.3 dev: true + /has-unicode/2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: false + /has/1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} @@ -3526,6 +3682,18 @@ packages: next-line: 1.1.0 dev: false + /http-proxy-agent/4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + /http2-wrapper/2.1.11: resolution: {integrity: sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==} engines: {node: '>=10.19.0'} @@ -3534,6 +3702,16 @@ packages: resolve-alpn: 1.2.1 dev: false + /https-proxy-agent/5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + /human-interval/2.0.1: resolution: {integrity: sha512-r4Aotzf+OtKIGQCB3odUowy4GfUDTy3aTWTfLd7ZF2gBCy3XW3v/dJLRefZnOFFnjqs5B1TypvS8WarpBkYUNQ==} dependencies: @@ -3545,12 +3723,20 @@ packages: engines: {node: '>=12.20.0'} dev: false - /iconv-lite/0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + /humanize-ms/1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + dependencies: + ms: 2.1.3 + dev: false + optional: true + + /iconv-lite/0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 - dev: true + dev: false + optional: true /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -3576,13 +3762,23 @@ packages: /imurmurhash/0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - dev: true + + /indent-string/4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: false + optional: true /indent-string/5.0.0: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} dev: false + /infer-owner/1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + dev: false + optional: true + /inflight/1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -3596,25 +3792,6 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: false - /inquirer/7.0.0: - resolution: {integrity: sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==} - engines: {node: '>=6.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 2.4.2 - cli-cursor: 3.1.0 - cli-width: 2.2.1 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - run-async: 2.4.1 - rxjs: 6.6.7 - string-width: 4.2.3 - strip-ansi: 5.2.0 - through: 2.3.8 - dev: true - /internal-slot/1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} @@ -3635,6 +3812,11 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: false + /ip/2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + dev: false + optional: true + /ipaddr.js/1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -3710,7 +3892,7 @@ packages: /is-fullwidth-code-point/3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - dev: true + dev: false /is-glob/2.0.1: resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} @@ -3747,6 +3929,11 @@ packages: super-regex: 0.2.0 dev: false + /is-lambda/1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + dev: false + optional: true + /is-negative-zero/2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -4142,10 +4329,43 @@ packages: sourcemap-codec: 1.4.8 dev: true + /make-dir/3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: false + /make-error/1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: false + /make-fetch-happen/9.1.0: + resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} + engines: {node: '>= 10'} + dependencies: + agentkeepalive: 4.2.1 + cacache: 15.3.0 + http-cache-semantics: 4.1.0 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 6.0.0 + minipass: 3.3.4 + minipass-collect: 1.0.2 + minipass-fetch: 1.4.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 6.2.1 + ssri: 8.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + dev: false + optional: true + /memorystream/0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -4195,11 +4415,6 @@ packages: hasBin: true dev: false - /mimic-fn/2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: true - /mimic-fn/4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -4228,7 +4443,6 @@ packages: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 - dev: true /minimatch/5.1.0: resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} @@ -4237,13 +4451,68 @@ packages: brace-expansion: 2.0.1 dev: false - /minimist/1.2.0: - resolution: {integrity: sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==} - dev: true - /minimist/1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + /minipass-collect/1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + dev: false + optional: true + + /minipass-fetch/1.4.1: + resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==} + engines: {node: '>=8'} + dependencies: + minipass: 3.3.4 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + dev: false + optional: true + + /minipass-flush/1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + dev: false + optional: true + + /minipass-pipeline/1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + dependencies: + minipass: 3.3.4 + dev: false + optional: true + + /minipass-sized/1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + dependencies: + minipass: 3.3.4 + dev: false + optional: true + + /minipass/3.3.4: + resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: false + + /minizlib/2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + yallist: 4.0.0 + dev: false + /mkdirp-classic/0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} dev: false @@ -4255,6 +4524,12 @@ packages: minimist: 1.2.6 dev: true + /mkdirp/1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: false + /mnemonist/0.39.2: resolution: {integrity: sha512-n3ZCEosuMH03DVivZ9N0fcXPWiZrBLEdfSlEJ+S/mJxmk3zuo1ur0dj9URDczFyP1VS3wfiyKzqLLDXoPJ6rPA==} dependencies: @@ -4275,10 +4550,6 @@ packages: /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - /mute-stream/0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: true - /nan/2.16.0: resolution: {integrity: sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==} dev: false @@ -4297,6 +4568,12 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true + /negotiator/0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: false + optional: true + /next-line/1.1.0: resolution: {integrity: sha512-+I10J3wKNoKddNxn0CNpoZ3eTZuqxjNM3b1GImVx22+ePI+Y15P8g/j3WsbP0fhzzrFzrtjOAoq5NCCucswXOQ==} dev: false @@ -4311,16 +4588,49 @@ packages: lower-case: 1.1.4 dev: false - /node-fetch/2.6.0: - resolution: {integrity: sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==} + /node-addon-api/4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + dev: false + + /node-fetch/2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} - dev: true + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false /node-forge/1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} dev: false + /node-gyp/8.4.1: + resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} + engines: {node: '>= 10.12.0'} + hasBin: true + requiresBuild: true + dependencies: + env-paths: 2.2.1 + glob: 7.2.3 + graceful-fs: 4.2.10 + make-fetch-happen: 9.1.0 + nopt: 5.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.3.7 + tar: 6.1.11 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + dev: false + optional: true + /node-os-utils/1.3.7: resolution: {integrity: sha512-fvnX9tZbR7WfCG5BAy3yO/nCLyjVWD6MghEq0z5FDfN+ZXpLWNITBdbifxQkQ25ebr16G0N7eRWJisOcMEHG3Q==} dev: false @@ -4357,6 +4667,14 @@ packages: abbrev: 1.1.1 dev: true + /nopt/5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: false + /normalize-package-data/2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -4401,10 +4719,35 @@ packages: path-key: 4.0.0 dev: false + /npmlog/5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: false + + /npmlog/6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + dev: false + optional: true + /numbered/1.1.0: resolution: {integrity: sha512-pv/ue2Odr7IfYOO0byC1KgBI10wo5YDauLhxY6/saNzAdAs0r1SotGCPzzCLNPL0xtrAwWRialLu23AAu9xO1g==} dev: false + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false + /object-hash/3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} @@ -4447,13 +4790,6 @@ packages: dependencies: wrappy: 1.0.2 - /onetime/5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true - /onetime/6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} @@ -4461,21 +4797,6 @@ packages: mimic-fn: 4.0.0 dev: false - /opencollective-setup/1.4.1: - resolution: {integrity: sha512-XdYWl35SewxvjJCeuFQSkuL1elwOsGYXpzT0/vOaszC16KNmHi1NoLfiN/YJiw/VeP4E+DYVI906oGsXp0b77g==} - engines: {node: 11.8.0, npm: 6.5.0} - hasBin: true - dependencies: - chalk: 2.4.2 - debug: 4.1.1 - detect-indent: 6.0.0 - inquirer: 7.0.0 - minimist: 1.2.0 - node-fetch: 2.6.0 - transitivePeerDependencies: - - supports-color - dev: true - /optionator/0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} @@ -4556,6 +4877,14 @@ packages: p-limit: 3.1.0 dev: true + /p-map/4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: false + optional: true + /p-map/5.5.0: resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} engines: {node: '>=12'} @@ -4563,6 +4892,11 @@ packages: aggregate-error: 4.0.1 dev: false + /p-throttle/5.0.0: + resolution: {integrity: sha512-iXBFjW4kP/5Ivw7uC9EDnj+/xo3pNn4Rws3zgMGPwXnWTv1M3P0LVdZxLrqRUI5JK0Fp3Du0bt6lCaVrI3WF7g==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + /p-timeout/3.2.0: resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} engines: {node: '>=8'} @@ -4662,7 +4996,6 @@ packages: /path-is-absolute/1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - dev: true /path-key/2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} @@ -4868,6 +5201,25 @@ packages: resolution: {integrity: sha512-+MmoAXoUX+VTHAlwns0h+kFUWFs/3FZy+ZuchkgjyOu3oioLAo2LB5aCfKPh2+P9O18i3m43tUEv3YqttSy0Ww==} dev: false + /promise-inflight/1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + dev: false + optional: true + + /promise-retry/2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + dev: false + optional: true + /property-expr/2.0.5: resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==} dev: false @@ -5101,19 +5453,17 @@ packages: lowercase-keys: 2.0.0 dev: false - /restore-cursor/3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: true - /ret/0.2.2: resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} engines: {node: '>=4'} dev: false + /retry/0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + dev: false + optional: true + /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -5134,7 +5484,6 @@ packages: hasBin: true dependencies: glob: 7.2.3 - dev: true /rollup/2.77.0: resolution: {integrity: sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==} @@ -5144,23 +5493,11 @@ packages: fsevents: 2.3.2 dev: true - /run-async/2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - dev: true - /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 - /rxjs/6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - dev: true - /sade/1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} @@ -5193,6 +5530,7 @@ packages: /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false /sander/0.5.1: resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==} @@ -5211,6 +5549,11 @@ packages: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true + /semver/6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: false + /semver/7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} hasBin: true @@ -5248,6 +5591,10 @@ packages: resolution: {integrity: sha512-6oGOAj9wPBKEuzJxqrN1sxMHJKbWOg7D2zNYOXaKrDC4lP6FpAw2MVuZd4okp/KqtRxkgLMweEd6HM1+c4m8Yg==} dev: false + /set-blocking/2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: false + /set-cookie-parser/2.4.8: resolution: {integrity: sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==} dev: false @@ -5291,6 +5638,7 @@ packages: /signal-exit/3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: false /simple-swizzle/0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -5315,6 +5663,33 @@ packages: engines: {node: '>=8'} dev: true + /smart-buffer/4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: false + optional: true + + /socks-proxy-agent/6.2.1: + resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==} + engines: {node: '>= 10'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + socks: 2.7.0 + transitivePeerDependencies: + - supports-color + dev: false + optional: true + + /socks/2.7.0: + resolution: {integrity: sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: false + optional: true + /sonic-boom/3.0.0: resolution: {integrity: sha512-p5DiZOZHbJ2ZO5MADczp5qrfOd3W5Vr2vHxfCpe7G4AzPwVOweIjbfgku8wSQUuk+Y5Yuo8W7JqRe6XKmKistg==} dependencies: @@ -5377,6 +5752,24 @@ packages: engines: {node: '>= 10.x'} dev: false + /sqlite3/5.0.11: + resolution: {integrity: sha512-4akFOr7u9lJEeAWLJxmwiV43DJcGV7w3ab7SjQFAFaTVyknY3rZjvXTKIVtWqUoY4xwhjwoHKYs2HDW2SoHVsA==} + requiresBuild: true + peerDependenciesMeta: + node-gyp: + optional: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.9 + node-addon-api: 4.3.0 + tar: 6.1.11 + optionalDependencies: + node-gyp: 8.4.1 + transitivePeerDependencies: + - bluebird + - encoding + - supports-color + dev: false + /ssh-config/4.1.6: resolution: {integrity: sha512-YdPYn/2afoBonSFoMSvC1FraA/LKKrvy8UvbvAFGJ8gdlKuANvufLLkf8ynF2uq7Tl5+DQBIFyN37//09nAgNQ==} dev: false @@ -5393,6 +5786,14 @@ packages: nan: 2.16.0 dev: false + /ssri/8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + dev: false + optional: true + /statuses/2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -5415,7 +5816,7 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - dev: true + dev: false /string.prototype.padend/3.1.3: resolution: {integrity: sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==} @@ -5455,19 +5856,11 @@ packages: ansi-regex: 2.1.1 dev: true - /strip-ansi/5.2.0: - resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} - engines: {node: '>=6'} - dependencies: - ansi-regex: 4.1.1 - dev: true - /strip-ansi/6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 - dev: true /strip-ansi/7.0.1: resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} @@ -5659,13 +6052,15 @@ packages: peerDependencies: tailwindcss: '>= 2.x.x' dependencies: - tailwindcss: 3.1.8 + tailwindcss: 3.1.8_postcss@8.4.16 dev: true - /tailwindcss/3.1.8: + /tailwindcss/3.1.8_postcss@8.4.16: resolution: {integrity: sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==} engines: {node: '>=12.13.0'} hasBin: true + peerDependencies: + postcss: ^8.0.9 dependencies: arg: 5.0.2 chokidar: 3.5.3 @@ -5712,6 +6107,18 @@ packages: readable-stream: 3.6.0 dev: false + /tar/6.1.11: + resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} + engines: {node: '>= 10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 3.3.4 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: false + /text-table/0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -5722,10 +6129,6 @@ packages: real-require: 0.1.0 dev: false - /through/2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - /time-span/5.1.0: resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} engines: {node: '>=12'} @@ -5745,13 +6148,6 @@ packages: engines: {node: '>=6'} dev: false - /tmp/0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: true - /to-fast-properties/1.0.3: resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} engines: {node: '>=0.10.0'} @@ -5779,6 +6175,10 @@ packages: nopt: 1.0.10 dev: true + /tr46/0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + /trim-right/1.0.1: resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} engines: {node: '>=0.10.0'} @@ -5857,11 +6257,6 @@ packages: engines: {node: '>=10'} dev: true - /type-fest/0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true - /type-fest/0.6.0: resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} engines: {node: '>=8'} @@ -5896,11 +6291,25 @@ packages: resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} dev: true + /unique-filename/1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + dependencies: + unique-slug: 2.0.2 + dev: false + optional: true + /unique-names-generator/4.7.1: resolution: {integrity: sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==} engines: {node: '>=8'} dev: false + /unique-slug/2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + dependencies: + imurmurhash: 0.1.4 + dev: false + optional: true + /update-browserslist-db/1.0.5_browserslist@4.21.3: resolution: {integrity: sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==} hasBin: true @@ -5967,6 +6376,17 @@ packages: fsevents: 2.3.2 dev: true + /webidl-conversions/3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url/5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -5991,6 +6411,12 @@ packages: dependencies: isexe: 2.0.0 + /wide-align/1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: false + /word-wrap/1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} From ff8fe68f14562549efbbc70f87d10c7363be4aae Mon Sep 17 00:00:00 2001 From: Kaname <56084970+kaname-png@users.noreply.github.com> Date: Fri, 26 Aug 2022 01:40:46 +0000 Subject: [PATCH 19/32] feat(ui): rework home UI and with responsive design --- apps/ui/package.json | 1 + apps/ui/src/lib/components/Usage.svelte | 39 +- apps/ui/src/routes/index.svelte | 480 ++++++++++++------------ apps/ui/tailwind.config.cjs | 2 +- pnpm-lock.yaml | 28 +- 5 files changed, 281 insertions(+), 269 deletions(-) diff --git a/apps/ui/package.json b/apps/ui/package.json index 0a64124f0..2d2787fb9 100644 --- a/apps/ui/package.json +++ b/apps/ui/package.json @@ -38,6 +38,7 @@ "type": "module", "dependencies": { "@sveltejs/adapter-static": "1.0.0-next.39", + "@tailwindcss/typography": "^0.5.4", "cuid": "2.1.8", "daisyui": "2.22.0", "js-cookie": "3.0.1", diff --git a/apps/ui/src/lib/components/Usage.svelte b/apps/ui/src/lib/components/Usage.svelte index 6868322ad..46854145e 100644 --- a/apps/ui/src/lib/components/Usage.svelte +++ b/apps/ui/src/lib/components/Usage.svelte @@ -50,61 +50,70 @@ }); -
-
Hardware Details
-
-
-
+
+

Hardware details

+
+
+
+
Total Memory
{(usage?.memory.totalMemMb).toFixed(0)}MB
-
+ +
Used Memory
{(usage?.memory.usedMemMb).toFixed(0)}MB
-
+ +
Free Memory
{usage?.memory.freeMemPercentage}%
-
-
+ +
+
Total CPUs
{usage?.cpu.count}
-
+ +
CPU Usage
{usage?.cpu.usage}%
-
+ +
Load Average (5,10,30mins)
{usage?.cpu.load}
-
-
+ +
+
Total Disk
{usage?.disk.totalGb}GB
-
+ +
Used Disk
{usage?.disk.usedGb}GB
-
+ +
Free Disk
{usage?.disk.freePercentage}%
diff --git a/apps/ui/src/routes/index.svelte b/apps/ui/src/routes/index.svelte index d6cecacfd..896c029b8 100644 --- a/apps/ui/src/routes/index.svelte +++ b/apps/ui/src/routes/index.svelte @@ -99,256 +99,240 @@ > {/if}
-
-
-
- {#if applications.length > 0} -
-
Resources
-
- - - {#each applications as application} - - - - + {#if $appSession.teamId === '0'} + + {/if} + {#if applications.length > 0} +

Resources

+
+
+ {#each applications as application} +
+ {#await getStatus(application)} + + {:then status} + {#if status === 'Running'}1 + + {:else} + + {/if} + {/await} +
- {/each} - - {#each services as service} - - - - - - - - {/each} - {#each databases as database} - - - - - - - {/each} - -
- {#await getStatus(application)} -
- {:then status} - {#if status === 'Running'} -
- {:else} -
- {/if} - {/await} -
{application.name}
-
- - -
- Application - {#if application.settings.isBot} - | BOT - {/if} -
- {#await getStatus(service)} -
- {:then status} - {#if status === 'Running'} -
- {:else} -
- {/if} - {/await} -
{service.name}
-
- -
- Service -
-
- {#if service.fqdn} - - - - - - - {/if} - - - - - - - - - - - - - - -
- {#await getStatus(database)} -
- {:then status} - {#if status === 'Running'} -
- {:else} -
- {/if} - {/await} -
{database.name}
-
- - -
- Database -
-
- - - - - - - - - - - - - - -
+ + + + + + Website + + {/if} + {#if application.settings.isBot && application.exposePort} + + + + + + + + Server + + {/if} + + + + + + + + + + + + + + Manage + +
+
- {:else if $appSession.teamId !== '0'} -
Nothing is configured yet.
- {/if} - {#if $appSession.teamId === '0'} - - {/if} + {/each}
-
+

Services

+
+
+ {#each services as service} +
+ {#await getStatus(service)} + + {:then status} + {#if status === 'Running'}1 + + {:else} + + {/if} + {/await} +
+ +
+ + Service + +

{service.name}

+ +
+
+ {/each} +
+

Databases

+
+
+ {#each databases as database} +
+ {#await getStatus(database)} + + {:then status} + {#if status === 'Running'}1 + + {:else} + + {/if} + {/await} +
+ +
+ + Service + +

{database.name}

+ +
+
+ {/each} +
+ {:else if $appSession.teamId !== '0'} +
+

Nothing is configured yet.

+
+ {/if}
diff --git a/apps/ui/tailwind.config.cjs b/apps/ui/tailwind.config.cjs index 91cab4bf1..cc36c7115 100644 --- a/apps/ui/tailwind.config.cjs +++ b/apps/ui/tailwind.config.cjs @@ -62,5 +62,5 @@ module.exports = { scrollbar: ['dark'], extend: {} }, - plugins: [require('tailwindcss-scrollbar'), require('daisyui')] + plugins: [require('tailwindcss-scrollbar'), require('daisyui'), require("@tailwindcss/typography")] }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 45e590081..570aad819 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -118,6 +118,7 @@ importers: '@playwright/test': 1.24.2 '@sveltejs/adapter-static': 1.0.0-next.39 '@sveltejs/kit': 1.0.0-next.405 + '@tailwindcss/typography': ^0.5.4 '@types/js-cookie': 3.0.2 '@typescript-eslint/eslint-plugin': 5.33.0 '@typescript-eslint/parser': 5.33.0 @@ -144,6 +145,7 @@ importers: vite: 3.0.5 dependencies: '@sveltejs/adapter-static': 1.0.0-next.39 + '@tailwindcss/typography': 0.5.4_tailwindcss@3.1.8 cuid: 2.1.8 daisyui: 2.22.0_25hquoklqeoqwmt7fwvvcyxm5e js-cookie: 3.0.1 @@ -166,7 +168,7 @@ importers: svelte: 3.49.0 svelte-check: 2.8.0_vylzxgme5yisu3bsyvcau4hjtq svelte-preprocess: 4.10.7_fje22ktja5v2dh6nbkissncqme - tailwindcss: 3.1.8 + tailwindcss: 3.1.8_postcss@8.4.16 tailwindcss-scrollbar: 0.1.0_tailwindcss@3.1.8 tslib: 2.4.0 typescript: 4.7.4 @@ -513,6 +515,17 @@ packages: defer-to-connect: 2.0.1 dev: false + /@tailwindcss/typography/0.5.4_tailwindcss@3.1.8: + resolution: {integrity: sha512-QEdg40EmGvE7kKoDei8zr5sf4D1pIayHj4R31bH3lX8x2BtTiR+jNejYPOkhbmy3DXgkMF9jC8xqNiGFAuL9Sg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + dependencies: + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + tailwindcss: 3.1.8_postcss@8.4.16 + dev: false + /@tsconfig/node10/1.0.8: resolution: {integrity: sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==} dev: false @@ -2235,7 +2248,7 @@ packages: css-selector-tokenizer: 0.8.0 postcss: 8.4.16 postcss-js: 4.0.0_postcss@8.4.16 - tailwindcss: 3.1.8 + tailwindcss: 3.1.8_postcss@8.4.16 transitivePeerDependencies: - ts-node dev: false @@ -4254,6 +4267,10 @@ packages: lodash._basetostring: 4.12.0 dev: false + /lodash.castarray/4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + dev: false + /lodash.includes/4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} dev: false @@ -4280,7 +4297,6 @@ packages: /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true /lodash.omit/4.5.0: resolution: {integrity: sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==} @@ -5863,13 +5879,15 @@ packages: peerDependencies: tailwindcss: '>= 2.x.x' dependencies: - tailwindcss: 3.1.8 + tailwindcss: 3.1.8_postcss@8.4.16 dev: true - /tailwindcss/3.1.8: + /tailwindcss/3.1.8_postcss@8.4.16: resolution: {integrity: sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==} engines: {node: '>=12.13.0'} hasBin: true + peerDependencies: + postcss: ^8.0.9 dependencies: arg: 5.0.2 chokidar: 3.5.3 From ee4360de3a78baa14b6f730a8f988bdf19c1ca2d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 06:29:06 +0000 Subject: [PATCH 20/32] fix: better worker system --- apps/api/package.json | 1 + apps/api/src/index.ts | 55 +-- apps/api/src/jobs/deployApplication.ts | 27 +- apps/api/src/jobs/infrastructure.ts | 220 +++++++++ apps/api/src/lib/scheduler.ts | 33 +- pnpm-lock.yaml | 647 ++----------------------- 6 files changed, 307 insertions(+), 676 deletions(-) create mode 100644 apps/api/src/jobs/infrastructure.ts diff --git a/apps/api/package.json b/apps/api/package.json index 3fe675596..6b48e4b78 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -22,6 +22,7 @@ "@fastify/jwt": "6.3.2", "@fastify/static": "6.5.0", "@iarna/toml": "2.2.5", + "@ladjs/graceful": "3.0.2", "@prisma/client": "3.15.2", "axios": "0.27.2", "bcryptjs": "2.4.3", diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 3f4876c94..1230b92bc 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -7,9 +7,8 @@ import path, { join } from 'path'; import autoLoad from '@fastify/autoload'; import { asyncExecShell, asyncSleep, isDev, listSettings, prisma, version } from './lib/common'; import { scheduler } from './lib/scheduler'; -import axios from 'axios'; import compareVersions from 'compare-versions'; - +import Graceful from '@ladjs/graceful' declare module 'fastify' { interface FastifyInstance { config: { @@ -104,45 +103,39 @@ fastify.listen({ port, host }, async (err: any, address: any) => { } console.log(`Coolify's API is listening on ${host}:${port}`); await initServer(); - await scheduler.start('cleanupPrismaEngines'); - await scheduler.start('checkProxies'); - + // await scheduler.start('cleanupPrismaEngines'); + // await scheduler.start('checkProxies'); + const graceful = new Graceful({ brees: [scheduler] }); + graceful.listen(); + setInterval(async () => { if (!scheduler.workers.has('deployApplication')) { scheduler.run('deployApplication'); } + if (!scheduler.workers.has('infrastructure')) { + scheduler.run('infrastructure'); + } }, 2000) - // Check for update & if no build is running + // autoUpdater setInterval(async () => { - const { isAutoUpdateEnabled } = await prisma.setting.findFirst(); - if (isAutoUpdateEnabled) { - const currentVersion = version; - const { data: versions } = await axios - .get( - `https://get.coollabs.io/versions.json` - , { - params: { - appId: process.env['COOLIFY_APP_ID'] || undefined, - version: currentVersion - } - }) - const latestVersion = versions['coolify'].main.version; - const isUpdateAvailable = compareVersions(latestVersion, currentVersion); - if (isUpdateAvailable === 1) { - if (!scheduler.workers.has('deployApplication')) { - await scheduler.run('autoUpdater') - } - } - } + scheduler.workers.has('infrastructure') && scheduler.workers.get('infrastructure').postMessage("action:autoUpdater") }, isDev ? 5000 : 60000 * 15) - // Cleanup storage + // cleanupStorage setInterval(async () => { - if (!scheduler.workers.has('deployApplication') && !scheduler.workers.has('cleanupStorage')) { - await scheduler.run('cleanupStorage') - } - }, isDev ? 5000 : 60000 * 10) + scheduler.workers.has('infrastructure') && scheduler.workers.get('infrastructure').postMessage("action:cleanupStorage") + }, isDev ? 6000 : 60000 * 10) + + // checkProxies + setInterval(async () => { + scheduler.workers.has('infrastructure') && scheduler.workers.get('infrastructure').postMessage("action:checkProxies") + }, 10000) + + // cleanupPrismaEngines + setInterval(async () => { + scheduler.workers.has('infrastructure') && scheduler.workers.get('infrastructure').postMessage("action:cleanupPrismaEngines") + }, 60000) await getArch(); await getIPAddress(); diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index d5d4a6d2f..ca5a5e230 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -14,17 +14,19 @@ import * as buildpacks from '../lib/buildPacks'; if (message === 'error') throw new Error('oops'); if (message === 'cancel') { parentPort.postMessage('cancelled'); + await prisma.$disconnect() process.exit(0); } }); - try { - const pThrottle = await import('p-throttle') - const throttle = pThrottle.default({ - limit: 1, - interval: 2000 - }); + const pThrottle = await import('p-throttle') + const throttle = pThrottle.default({ + limit: 1, + interval: 2000 + }); - const th = throttle(async () => { + + const th = throttle(async () => { + try { const queuedBuilds = await prisma.build.findMany({ where: { status: 'queued' }, orderBy: { createdAt: 'asc' } }); const { concurrentBuilds } = await prisma.setting.findFirst({}) if (queuedBuilds.length > 0) { @@ -356,14 +358,13 @@ import * as buildpacks from '../lib/buildPacks'; } await pAll.default(actions, { concurrency }) } - }) - while (true) { - await th() + } catch (error) { + } finally { } + }) - } catch (error) { - } finally { - await prisma.$disconnect() + while (true) { + await th() } diff --git a/apps/api/src/jobs/infrastructure.ts b/apps/api/src/jobs/infrastructure.ts new file mode 100644 index 000000000..52a566758 --- /dev/null +++ b/apps/api/src/jobs/infrastructure.ts @@ -0,0 +1,220 @@ +import { parentPort } from 'node:worker_threads'; +import axios from 'axios'; +import compareVersions from 'compare-versions'; +import { asyncExecShell, cleanupDockerStorage, executeDockerCmd, isDev, prisma, startTraefikTCPProxy, generateDatabaseConfiguration, startTraefikProxy, listSettings, version } from '../lib/common'; + +async function disconnect() { + await prisma.$disconnect(); +} +async function autoUpdater() { + try { + const currentVersion = version; + const { data: versions } = await axios + .get( + `https://get.coollabs.io/versions.json` + , { + params: { + appId: process.env['COOLIFY_APP_ID'] || undefined, + version: currentVersion + } + }) + const latestVersion = versions['coolify'].main.version; + const isUpdateAvailable = compareVersions(latestVersion, currentVersion); + if (isUpdateAvailable === 1) { + const activeCount = 0 + if (activeCount === 0) { + if (!isDev) { + console.log(`Updating Coolify to ${latestVersion}.`); + await asyncExecShell(`docker pull coollabsio/coolify:${latestVersion}`); + await asyncExecShell(`env | grep COOLIFY > .env`); + await asyncExecShell( + `docker run --rm -tid --env-file .env -v /var/run/docker.sock:/var/run/docker.sock -v coolify-db coollabsio/coolify:${latestVersion} /bin/sh -c "env | grep COOLIFY > .env && echo 'TAG=${latestVersion}' >> .env && docker stop -t 0 coolify && docker rm coolify && docker compose up -d --force-recreate"` + ); + } else { + console.log('Updating (not really in dev mode).'); + } + } + } + } catch (error) { + console.log(error); + } +} +async function checkProxies(){ + try { + const { default: isReachable } = await import('is-port-reachable'); + let portReachable; + + const { arch, ipv4, ipv6 } = await listSettings(); + // Coolify Proxy local + const engine = '/var/run/docker.sock'; + const localDocker = await prisma.destinationDocker.findFirst({ + where: { engine, network: 'coolify' } + }); + if (localDocker && localDocker.isCoolifyProxyUsed) { + portReachable = await isReachable(80, { host: ipv4 || ipv6 }) + console.log({ port: 80, portReachable }); + if (!portReachable) { + await startTraefikProxy(localDocker.id); + } + } + + // TCP Proxies + const databasesWithPublicPort = await prisma.database.findMany({ + where: { publicPort: { not: null } }, + include: { settings: true, destinationDocker: true } + }); + for (const database of databasesWithPublicPort) { + const { destinationDockerId, destinationDocker, publicPort, id } = database; + if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { + const { privatePort } = generateDatabaseConfiguration(database, arch); + portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) + console.log({ publicPort, portReachable }); + if (!portReachable) { + await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); + } + } + } + const wordpressWithFtp = await prisma.wordpress.findMany({ + where: { ftpPublicPort: { not: null } }, + include: { service: { include: { destinationDocker: true } } } + }); + for (const ftp of wordpressWithFtp) { + const { service, ftpPublicPort } = ftp; + const { destinationDockerId, destinationDocker, id } = service; + if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { + portReachable = await isReachable(ftpPublicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) + console.log({ ftpPublicPort, portReachable }); + if (!portReachable) { + await startTraefikTCPProxy(destinationDocker, id, ftpPublicPort, 22, 'wordpressftp'); + } + } + } + + // HTTP Proxies + const minioInstances = await prisma.minio.findMany({ + where: { publicPort: { not: null } }, + include: { service: { include: { destinationDocker: true } } } + }); + for (const minio of minioInstances) { + const { service, publicPort } = minio; + const { destinationDockerId, destinationDocker, id } = service; + if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { + portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) + console.log({ publicPort, portReachable }); + if (!portReachable) { + await startTraefikTCPProxy(destinationDocker, id, publicPort, 9000); + } + } + } + } catch(error) { + + } +} +async function cleanupPrismaEngines(){ + if (!isDev) { + try { + const { stdout } = await asyncExecShell(`ps -ef | grep /app/prisma-engines/query-engine | grep -v grep | wc -l | xargs`) + if (stdout.trim() != null && stdout.trim() != '' && Number(stdout.trim()) > 1) { + await asyncExecShell(`killall -q -e /app/prisma-engines/query-engine -o 10m`) + } + } catch (error) { + console.log(error); + } + } +} +async function cleanupStorage() { + const destinationDockers = await prisma.destinationDocker.findMany(); + let enginesDone = new Set() + for (const destination of destinationDockers) { + if (enginesDone.has(destination.engine) || enginesDone.has(destination.remoteIpAddress)) return + if (destination.engine) enginesDone.add(destination.engine) + if (destination.remoteIpAddress) enginesDone.add(destination.remoteIpAddress) + + let lowDiskSpace = false; + try { + let stdout = null + if (!isDev) { + const output = await executeDockerCmd({ dockerId: destination.id, command: `CONTAINER=$(docker ps -lq | head -1) && docker exec $CONTAINER sh -c 'df -kPT /'` }) + stdout = output.stdout; + } else { + const output = await asyncExecShell( + `df -kPT /` + ); + stdout = output.stdout; + } + let lines = stdout.trim().split('\n'); + let header = lines[0]; + let regex = + /^Filesystem\s+|Type\s+|1024-blocks|\s+Used|\s+Available|\s+Capacity|\s+Mounted on\s*$/g; + const boundaries = []; + let match; + + while ((match = regex.exec(header))) { + boundaries.push(match[0].length); + } + + boundaries[boundaries.length - 1] = -1; + const data = lines.slice(1).map((line) => { + const cl = boundaries.map((boundary) => { + const column = boundary > 0 ? line.slice(0, boundary) : line; + line = line.slice(boundary); + return column.trim(); + }); + return { + capacity: Number.parseInt(cl[5], 10) / 100 + }; + }); + if (data.length > 0) { + const { capacity } = data[0]; + if (capacity > 0.8) { + lowDiskSpace = true; + } + } + } catch (error) { + console.log(error); + } + await cleanupDockerStorage(destination.id, lowDiskSpace, false) + } +} + +(async () => { + let status ={ + cleanupStorage: false, + autoUpdater: false + } + if (parentPort) { + parentPort.on('message', async (message) => { + if (parentPort) { + if (message === 'error') throw new Error('oops'); + if (message === 'cancel') { + parentPort.postMessage('cancelled'); + process.exit(1); + } + if (message === 'action:cleanupStorage') { + if (!status.autoUpdater) { + status.cleanupStorage = true + await cleanupStorage(); + status.cleanupStorage = false + } + return; + } + if (message === 'action:cleanupPrismaEngines') { + await cleanupPrismaEngines(); + return; + } + if (message === 'action:checkProxies') { + await checkProxies(); + return; + } + if (message === 'action:autoUpdater') { + if (!status.cleanupStorage) { + status.autoUpdater = true + await autoUpdater(); + status.autoUpdater = false + } + return; + } + } + }); + } else process.exit(0); +})(); diff --git a/apps/api/src/lib/scheduler.ts b/apps/api/src/lib/scheduler.ts index 6c233d050..71f5bc6f0 100644 --- a/apps/api/src/lib/scheduler.ts +++ b/apps/api/src/lib/scheduler.ts @@ -18,23 +18,22 @@ const options: any = { } }, jobs: [ - { - name: 'deployApplication', - }, - { - name: 'cleanupStorage', - }, - { - name: 'cleanupPrismaEngines', - interval: '1m' - }, - { - name: 'checkProxies', - interval: '10s' - }, - { - name: 'autoUpdater', - } + { name: 'infrastructure' }, + { name: 'deployApplication' }, + // { + // name: 'cleanupStorage', + // }, + // { + // name: 'cleanupPrismaEngines', + // interval: '1m' + // }, + // { + // name: 'checkProxies', + // interval: '10s' + // }, + // { + // name: 'autoUpdater', + // } ], }; if (isDev) options.root = path.join(__dirname, '../jobs'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bea7b8797..0ac67fbb0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,7 @@ importers: '@fastify/jwt': 6.3.2 '@fastify/static': 6.5.0 '@iarna/toml': 2.2.5 + '@ladjs/graceful': ^3.0.2 '@prisma/client': 3.15.2 '@types/node': 18.7.13 '@types/node-os-utils': 1.3.0 @@ -51,12 +52,11 @@ importers: node-os-utils: 1.3.7 nodemon: 2.0.19 p-all: 4.0.0 - p-throttle: ^5.0.0 + p-throttle: 5.0.0 prettier: 2.7.1 prisma: 3.15.2 public-ip: 6.0.1 rimraf: 3.0.2 - sqlite3: ^5.0.11 ssh-config: 4.1.6 strip-ansi: 7.0.1 tsconfig-paths: 4.1.0 @@ -71,6 +71,7 @@ importers: '@fastify/jwt': 6.3.2 '@fastify/static': 6.5.0 '@iarna/toml': 2.2.5 + '@ladjs/graceful': 3.0.2 '@prisma/client': 3.15.2_prisma@3.15.2 axios: 0.27.2 bcryptjs: 2.4.3 @@ -95,7 +96,6 @@ importers: p-all: 4.0.0 p-throttle: 5.0.0 public-ip: 6.0.1 - sqlite3: 5.0.11 ssh-config: 4.1.6 strip-ansi: 7.0.1 unique-names-generator: 4.7.1 @@ -337,11 +337,6 @@ packages: - supports-color dev: false - /@gar/promisify/1.1.3: - resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} - dev: false - optional: true - /@humanwhocodes/config-array/0.10.4: resolution: {integrity: sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==} engines: {node: '>=10.10.0'} @@ -382,6 +377,14 @@ packages: resolution: {integrity: sha512-hZere0rUga8kTzSTFbHREXpD9E/jwi94+B5RyLAmMIzl/w/EK1z7rFEnMHzPkU4AZkL42JWSsGXoV8LXMihybg==} dev: false + /@ladjs/graceful/3.0.2: + resolution: {integrity: sha512-T4Z+0R0zgZfR32KIs3FEuH7oFSnhj3c+00wVtp07aeIl8PDfQGcXGB3C8SfOZ2EzPMRuIpIul5kHkVBdSTULXw==} + engines: {node: '>=14'} + dependencies: + lil-http-terminator: 1.2.2 + p-is-promise: 3.0.0 + dev: false + /@leichtgewicht/ip-codec/2.0.4: resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==} dev: false @@ -391,24 +394,6 @@ packages: engines: {node: '>=8'} dev: false - /@mapbox/node-pre-gyp/1.0.9: - resolution: {integrity: sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==} - hasBin: true - dependencies: - detect-libc: 2.0.1 - https-proxy-agent: 5.0.1 - make-dir: 3.1.0 - node-fetch: 2.6.7 - nopt: 5.0.0 - npmlog: 5.0.1 - rimraf: 3.0.2 - semver: 7.3.7 - tar: 6.1.11 - transitivePeerDependencies: - - encoding - - supports-color - dev: false - /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -427,23 +412,6 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 - /@npmcli/fs/1.1.1: - resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} - dependencies: - '@gar/promisify': 1.1.3 - semver: 7.3.7 - dev: false - optional: true - - /@npmcli/move-file/1.1.2: - resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} - engines: {node: '>=10'} - dependencies: - mkdirp: 1.0.4 - rimraf: 3.0.2 - dev: false - optional: true - /@playwright/test/1.25.1: resolution: {integrity: sha512-IJ4X0yOakXtwkhbnNzKkaIgXe6df7u3H3FnuhI9Jqh+CdO0e/lYQlDLYiyI9cnXK8E7UAppAWP+VqAv6VX7HQg==} engines: {node: '>=14'} @@ -556,12 +524,6 @@ packages: defer-to-connect: 2.0.1 dev: false - /@tootallnate/once/1.1.2: - resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} - engines: {node: '>= 6'} - dev: false - optional: true - /@tsconfig/node10/1.0.8: resolution: {integrity: sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==} dev: false @@ -768,6 +730,7 @@ packages: /abbrev/1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true /abort-controller/3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -814,36 +777,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - /agent-base/6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: false - - /agentkeepalive/4.2.1: - resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==} - engines: {node: '>= 8.0.0'} - dependencies: - debug: 4.3.4 - depd: 1.1.2 - humanize-ms: 1.2.1 - transitivePeerDependencies: - - supports-color - dev: false - optional: true - - /aggregate-error/3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - dev: false - optional: true - /aggregate-error/4.0.1: resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} engines: {node: '>=12'} @@ -892,6 +825,7 @@ packages: /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + dev: true /ansi-regex/6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} @@ -923,31 +857,10 @@ packages: normalize-path: 3.0.0 picomatch: 2.3.1 - /aproba/2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - dev: false - /archy/1.0.0: resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} dev: false - /are-we-there-yet/2.0.0: - resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} - engines: {node: '>=10'} - dependencies: - delegates: 1.0.0 - readable-stream: 3.6.0 - dev: false - - /are-we-there-yet/3.0.1: - resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - delegates: 1.0.0 - readable-stream: 3.6.0 - dev: false - optional: true - /arg/4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: false @@ -1768,6 +1681,7 @@ packages: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + dev: true /brace-expansion/2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -1852,33 +1766,6 @@ packages: - supports-color dev: false - /cacache/15.3.0: - resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} - engines: {node: '>= 10'} - dependencies: - '@npmcli/fs': 1.1.1 - '@npmcli/move-file': 1.1.2 - chownr: 2.0.0 - fs-minipass: 2.1.0 - glob: 7.2.3 - infer-owner: 1.0.4 - lru-cache: 6.0.0 - minipass: 3.3.4 - minipass-collect: 1.0.2 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - mkdirp: 1.0.4 - p-map: 4.0.0 - promise-inflight: 1.0.1 - rimraf: 3.0.2 - ssri: 8.0.1 - tar: 6.1.11 - unique-filename: 1.1.1 - transitivePeerDependencies: - - bluebird - dev: false - optional: true - /cacheable-lookup/6.0.4: resolution: {integrity: sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A==} engines: {node: '>=10.6.0'} @@ -1965,17 +1852,6 @@ packages: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} dev: false - /chownr/2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - dev: false - - /clean-stack/2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - dev: false - optional: true - /clean-stack/4.2.0: resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} engines: {node: '>=12'} @@ -2025,11 +1901,6 @@ packages: simple-swizzle: 0.2.2 dev: false - /color-support/1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true - dev: false - /color/4.2.3: resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} engines: {node: '>=12.5.0'} @@ -2070,10 +1941,7 @@ packages: /concat-map/0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - /console-control-strings/1.1.0: - resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - dev: false + dev: true /console-polyfill/0.3.0: resolution: {integrity: sha512-w+JSDZS7XML43Xnwo2x5O5vxB0ID7T5BdqDtyqT6uiCAX2kZAgcWxNaGqT97tZfSHzfOcvrfsDAodKcJ3UvnXQ==} @@ -2295,16 +2163,6 @@ packages: engines: {node: '>=0.4.0'} dev: false - /delegates/1.0.0: - resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} - dev: false - - /depd/1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} - dev: false - optional: true - /depd/2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -2327,11 +2185,6 @@ packages: engines: {node: '>=8'} dev: true - /detect-libc/2.0.1: - resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} - engines: {node: '>=8'} - dev: false - /detective/5.2.1: resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} engines: {node: '>=0.8.0'} @@ -2455,35 +2308,17 @@ packages: /electron-to-chromium/1.4.213: resolution: {integrity: sha512-+3DbGHGOCHTVB/Ms63bGqbyC1b8y7Fk86+7ltssB8NQrZtSCvZG6eooSl9U2Q0yw++fL2DpHKOdTU0NVEkFObg==} - /emoji-regex/8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: false - /encodeurl/1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} dev: false - /encoding/0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - requiresBuild: true - dependencies: - iconv-lite: 0.6.3 - dev: false - optional: true - /end-of-stream/1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 dev: false - /env-paths/2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - dev: false - optional: true - /env-schema/5.0.0: resolution: {integrity: sha512-91u95Nlny+LmjF3Mk96j8k6k+GOXcFEdMUv3bWQjtM2l+KTAdW6qITiv8kHYO8vCaCScXpJTDyd1AFnCQTnYaQ==} dependencies: @@ -2492,11 +2327,6 @@ packages: dotenv-expand: 8.0.3 dev: false - /err-code/2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - dev: false - optional: true - /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: @@ -3397,13 +3227,6 @@ packages: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} dev: false - /fs-minipass/2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: false - /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -3446,36 +3269,6 @@ packages: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true - /gauge/3.0.2: - resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} - engines: {node: '>=10'} - dependencies: - aproba: 2.0.0 - color-support: 1.1.3 - console-control-strings: 1.1.0 - has-unicode: 2.0.1 - object-assign: 4.1.1 - signal-exit: 3.0.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wide-align: 1.1.5 - dev: false - - /gauge/4.0.4: - resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - aproba: 2.0.0 - color-support: 1.1.3 - console-control-strings: 1.1.0 - has-unicode: 2.0.1 - signal-exit: 3.0.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - wide-align: 1.1.5 - dev: false - optional: true - /generate-password/1.7.0: resolution: {integrity: sha512-WPCtlfy0jexf7W5IbwxGUgpIDvsZIohbI2DAq2Q6TSlKKis+G4GT9sxvPxrZUGL8kP6WUXMWNqYnxY6DDKAdFA==} dev: false @@ -3528,6 +3321,7 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: true /glob/8.0.3: resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} @@ -3593,6 +3387,7 @@ packages: /graceful-fs/4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true /grapheme-splitter/1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} @@ -3635,10 +3430,6 @@ packages: has-symbols: 1.0.3 dev: true - /has-unicode/2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - dev: false - /has/1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} @@ -3682,18 +3473,6 @@ packages: next-line: 1.1.0 dev: false - /http-proxy-agent/4.0.1: - resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} - engines: {node: '>= 6'} - dependencies: - '@tootallnate/once': 1.1.2 - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: false - optional: true - /http2-wrapper/2.1.11: resolution: {integrity: sha512-aNAk5JzLturWEUiuhAN73Jcbq96R7rTitAoXV54FYMatvihnpD2+6PUgU4ce3D/m5VDbw+F5CsyKSF176ptitQ==} engines: {node: '>=10.19.0'} @@ -3702,16 +3481,6 @@ packages: resolve-alpn: 1.2.1 dev: false - /https-proxy-agent/5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: false - /human-interval/2.0.1: resolution: {integrity: sha512-r4Aotzf+OtKIGQCB3odUowy4GfUDTy3aTWTfLd7ZF2gBCy3XW3v/dJLRefZnOFFnjqs5B1TypvS8WarpBkYUNQ==} dependencies: @@ -3723,21 +3492,6 @@ packages: engines: {node: '>=12.20.0'} dev: false - /humanize-ms/1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - dependencies: - ms: 2.1.3 - dev: false - optional: true - - /iconv-lite/0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: false - optional: true - /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false @@ -3762,23 +3516,13 @@ packages: /imurmurhash/0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - - /indent-string/4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - dev: false - optional: true + dev: true /indent-string/5.0.0: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} dev: false - /infer-owner/1.0.4: - resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} - dev: false - optional: true - /inflight/1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -3812,11 +3556,6 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: false - /ip/2.0.0: - resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} - dev: false - optional: true - /ipaddr.js/1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -3889,11 +3628,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-fullwidth-code-point/3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: false - /is-glob/2.0.1: resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} engines: {node: '>=0.10.0'} @@ -3929,11 +3663,6 @@ packages: super-regex: 0.2.0 dev: false - /is-lambda/1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - dev: false - optional: true - /is-negative-zero/2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -4161,6 +3890,11 @@ packages: set-cookie-parser: 2.4.8 dev: false + /lil-http-terminator/1.2.2: + resolution: {integrity: sha512-2n6gKJIKgPjy4JfSlwsQnAA7wK4SEA1cegqdsYwr7qObVfIHdELjDGjEcYWJanfF/u/mRzIT2WPqhpzC6R9pZw==} + engines: {node: '>=8'} + dev: false + /lilconfig/2.0.6: resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} engines: {node: '>=10'} @@ -4329,43 +4063,10 @@ packages: sourcemap-codec: 1.4.8 dev: true - /make-dir/3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.0 - dev: false - /make-error/1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: false - /make-fetch-happen/9.1.0: - resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} - engines: {node: '>= 10'} - dependencies: - agentkeepalive: 4.2.1 - cacache: 15.3.0 - http-cache-semantics: 4.1.0 - http-proxy-agent: 4.0.1 - https-proxy-agent: 5.0.1 - is-lambda: 1.0.1 - lru-cache: 6.0.0 - minipass: 3.3.4 - minipass-collect: 1.0.2 - minipass-fetch: 1.4.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - negotiator: 0.6.3 - promise-retry: 2.0.1 - socks-proxy-agent: 6.2.1 - ssri: 8.0.1 - transitivePeerDependencies: - - bluebird - - supports-color - dev: false - optional: true - /memorystream/0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} @@ -4443,6 +4144,7 @@ packages: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 + dev: true /minimatch/5.1.0: resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} @@ -4454,65 +4156,6 @@ packages: /minimist/1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} - /minipass-collect/1.0.2: - resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: false - optional: true - - /minipass-fetch/1.4.1: - resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==} - engines: {node: '>=8'} - dependencies: - minipass: 3.3.4 - minipass-sized: 1.0.3 - minizlib: 2.1.2 - optionalDependencies: - encoding: 0.1.13 - dev: false - optional: true - - /minipass-flush/1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: false - optional: true - - /minipass-pipeline/1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - dependencies: - minipass: 3.3.4 - dev: false - optional: true - - /minipass-sized/1.0.3: - resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} - engines: {node: '>=8'} - dependencies: - minipass: 3.3.4 - dev: false - optional: true - - /minipass/3.3.4: - resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} - engines: {node: '>=8'} - dependencies: - yallist: 4.0.0 - dev: false - - /minizlib/2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - yallist: 4.0.0 - dev: false - /mkdirp-classic/0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} dev: false @@ -4524,12 +4167,6 @@ packages: minimist: 1.2.6 dev: true - /mkdirp/1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: false - /mnemonist/0.39.2: resolution: {integrity: sha512-n3ZCEosuMH03DVivZ9N0fcXPWiZrBLEdfSlEJ+S/mJxmk3zuo1ur0dj9URDczFyP1VS3wfiyKzqLLDXoPJ6rPA==} dependencies: @@ -4568,12 +4205,6 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /negotiator/0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - dev: false - optional: true - /next-line/1.1.0: resolution: {integrity: sha512-+I10J3wKNoKddNxn0CNpoZ3eTZuqxjNM3b1GImVx22+ePI+Y15P8g/j3WsbP0fhzzrFzrtjOAoq5NCCucswXOQ==} dev: false @@ -4588,49 +4219,11 @@ packages: lower-case: 1.1.4 dev: false - /node-addon-api/4.3.0: - resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} - dev: false - - /node-fetch/2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: false - /node-forge/1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} dev: false - /node-gyp/8.4.1: - resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} - engines: {node: '>= 10.12.0'} - hasBin: true - requiresBuild: true - dependencies: - env-paths: 2.2.1 - glob: 7.2.3 - graceful-fs: 4.2.10 - make-fetch-happen: 9.1.0 - nopt: 5.0.0 - npmlog: 6.0.2 - rimraf: 3.0.2 - semver: 7.3.7 - tar: 6.1.11 - which: 2.0.2 - transitivePeerDependencies: - - bluebird - - supports-color - dev: false - optional: true - /node-os-utils/1.3.7: resolution: {integrity: sha512-fvnX9tZbR7WfCG5BAy3yO/nCLyjVWD6MghEq0z5FDfN+ZXpLWNITBdbifxQkQ25ebr16G0N7eRWJisOcMEHG3Q==} dev: false @@ -4667,14 +4260,6 @@ packages: abbrev: 1.1.1 dev: true - /nopt/5.0.0: - resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} - engines: {node: '>=6'} - hasBin: true - dependencies: - abbrev: 1.1.1 - dev: false - /normalize-package-data/2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -4719,35 +4304,10 @@ packages: path-key: 4.0.0 dev: false - /npmlog/5.0.1: - resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} - dependencies: - are-we-there-yet: 2.0.0 - console-control-strings: 1.1.0 - gauge: 3.0.2 - set-blocking: 2.0.0 - dev: false - - /npmlog/6.0.2: - resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - are-we-there-yet: 3.0.1 - console-control-strings: 1.1.0 - gauge: 4.0.4 - set-blocking: 2.0.0 - dev: false - optional: true - /numbered/1.1.0: resolution: {integrity: sha512-pv/ue2Odr7IfYOO0byC1KgBI10wo5YDauLhxY6/saNzAdAs0r1SotGCPzzCLNPL0xtrAwWRialLu23AAu9xO1g==} dev: false - /object-assign/4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: false - /object-hash/3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} @@ -4836,6 +4396,11 @@ packages: engines: {node: '>=4'} dev: false + /p-is-promise/3.0.0: + resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} + engines: {node: '>=8'} + dev: false + /p-limit/2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -4877,14 +4442,6 @@ packages: p-limit: 3.1.0 dev: true - /p-map/4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - dependencies: - aggregate-error: 3.1.0 - dev: false - optional: true - /p-map/5.5.0: resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} engines: {node: '>=12'} @@ -4996,6 +4553,7 @@ packages: /path-is-absolute/1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + dev: true /path-key/2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} @@ -5201,25 +4759,6 @@ packages: resolution: {integrity: sha512-+MmoAXoUX+VTHAlwns0h+kFUWFs/3FZy+ZuchkgjyOu3oioLAo2LB5aCfKPh2+P9O18i3m43tUEv3YqttSy0Ww==} dev: false - /promise-inflight/1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} - peerDependencies: - bluebird: '*' - peerDependenciesMeta: - bluebird: - optional: true - dev: false - optional: true - - /promise-retry/2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} - dependencies: - err-code: 2.0.3 - retry: 0.12.0 - dev: false - optional: true - /property-expr/2.0.5: resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==} dev: false @@ -5458,12 +4997,6 @@ packages: engines: {node: '>=4'} dev: false - /retry/0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - dev: false - optional: true - /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -5484,6 +5017,7 @@ packages: hasBin: true dependencies: glob: 7.2.3 + dev: true /rollup/2.77.0: resolution: {integrity: sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==} @@ -5549,11 +5083,6 @@ packages: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true - /semver/6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - dev: false - /semver/7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} hasBin: true @@ -5591,10 +5120,6 @@ packages: resolution: {integrity: sha512-6oGOAj9wPBKEuzJxqrN1sxMHJKbWOg7D2zNYOXaKrDC4lP6FpAw2MVuZd4okp/KqtRxkgLMweEd6HM1+c4m8Yg==} dev: false - /set-blocking/2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: false - /set-cookie-parser/2.4.8: resolution: {integrity: sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==} dev: false @@ -5663,33 +5188,6 @@ packages: engines: {node: '>=8'} dev: true - /smart-buffer/4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - dev: false - optional: true - - /socks-proxy-agent/6.2.1: - resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==} - engines: {node: '>= 10'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - socks: 2.7.0 - transitivePeerDependencies: - - supports-color - dev: false - optional: true - - /socks/2.7.0: - resolution: {integrity: sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==} - engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} - dependencies: - ip: 2.0.0 - smart-buffer: 4.2.0 - dev: false - optional: true - /sonic-boom/3.0.0: resolution: {integrity: sha512-p5DiZOZHbJ2ZO5MADczp5qrfOd3W5Vr2vHxfCpe7G4AzPwVOweIjbfgku8wSQUuk+Y5Yuo8W7JqRe6XKmKistg==} dependencies: @@ -5752,24 +5250,6 @@ packages: engines: {node: '>= 10.x'} dev: false - /sqlite3/5.0.11: - resolution: {integrity: sha512-4akFOr7u9lJEeAWLJxmwiV43DJcGV7w3ab7SjQFAFaTVyknY3rZjvXTKIVtWqUoY4xwhjwoHKYs2HDW2SoHVsA==} - requiresBuild: true - peerDependenciesMeta: - node-gyp: - optional: true - dependencies: - '@mapbox/node-pre-gyp': 1.0.9 - node-addon-api: 4.3.0 - tar: 6.1.11 - optionalDependencies: - node-gyp: 8.4.1 - transitivePeerDependencies: - - bluebird - - encoding - - supports-color - dev: false - /ssh-config/4.1.6: resolution: {integrity: sha512-YdPYn/2afoBonSFoMSvC1FraA/LKKrvy8UvbvAFGJ8gdlKuANvufLLkf8ynF2uq7Tl5+DQBIFyN37//09nAgNQ==} dev: false @@ -5786,14 +5266,6 @@ packages: nan: 2.16.0 dev: false - /ssri/8.0.1: - resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: false - optional: true - /statuses/2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -5809,15 +5281,6 @@ packages: reusify: 1.0.4 dev: false - /string-width/4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: false - /string.prototype.padend/3.1.3: resolution: {integrity: sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==} engines: {node: '>= 0.4'} @@ -5861,6 +5324,7 @@ packages: engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 + dev: true /strip-ansi/7.0.1: resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} @@ -6107,18 +5571,6 @@ packages: readable-stream: 3.6.0 dev: false - /tar/6.1.11: - resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} - engines: {node: '>= 10'} - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 3.3.4 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - dev: false - /text-table/0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -6175,10 +5627,6 @@ packages: nopt: 1.0.10 dev: true - /tr46/0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false - /trim-right/1.0.1: resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} engines: {node: '>=0.10.0'} @@ -6291,25 +5739,11 @@ packages: resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} dev: true - /unique-filename/1.1.1: - resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} - dependencies: - unique-slug: 2.0.2 - dev: false - optional: true - /unique-names-generator/4.7.1: resolution: {integrity: sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==} engines: {node: '>=8'} dev: false - /unique-slug/2.0.2: - resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} - dependencies: - imurmurhash: 0.1.4 - dev: false - optional: true - /update-browserslist-db/1.0.5_browserslist@4.21.3: resolution: {integrity: sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==} hasBin: true @@ -6376,17 +5810,6 @@ packages: fsevents: 2.3.2 dev: true - /webidl-conversions/3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false - - /whatwg-url/5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: false - /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -6411,12 +5834,6 @@ packages: dependencies: isexe: 2.0.0 - /wide-align/1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} - dependencies: - string-width: 4.2.3 - dev: false - /word-wrap/1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} From 224604f2e74a8d115ad3b4e94eadc574f509e5a3 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 09:01:48 +0200 Subject: [PATCH 21/32] fixes --- Dockerfile | 2 +- apps/api/src/index.ts | 9 ++++----- apps/api/src/jobs/infrastructure.ts | 12 ++++++------ apps/api/src/lib/common.ts | 10 +++++----- apps/api/src/lib/scheduler.ts | 14 -------------- 5 files changed, 16 insertions(+), 31 deletions(-) diff --git a/Dockerfile b/Dockerfile index fea6b8624..50f616291 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,7 +21,7 @@ ENV PRISMA_QUERY_ENGINE_BINARY=/app/prisma-engines/query-engine \ PRISMA_CLI_QUERY_ENGINE_TYPE=binary \ PRISMA_CLIENT_ENGINE_TYPE=binary -COPY --from=coollabsio/prisma-engine:3.15 /prisma-engines/query-engine /prisma-engines/migration-engine /prisma-engines/introspection-engine /prisma-engines/prisma-fmt /app/prisma-engines/ +COPY --from=coollabsio/prisma-engine:3.15 /prisma-engines/query-engine /app/prisma-engines/ RUN apk add --no-cache git git-lfs openssh-client curl jq cmake sqlite openssl psmisc RUN curl -sL https://unpkg.com/@pnpm/self-installer | node diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 1230b92bc..dac8d34ef 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -103,8 +103,7 @@ fastify.listen({ port, host }, async (err: any, address: any) => { } console.log(`Coolify's API is listening on ${host}:${port}`); await initServer(); - // await scheduler.start('cleanupPrismaEngines'); - // await scheduler.start('checkProxies'); + const graceful = new Graceful({ brees: [scheduler] }); graceful.listen(); @@ -133,9 +132,9 @@ fastify.listen({ port, host }, async (err: any, address: any) => { }, 10000) // cleanupPrismaEngines - setInterval(async () => { - scheduler.workers.has('infrastructure') && scheduler.workers.get('infrastructure').postMessage("action:cleanupPrismaEngines") - }, 60000) + // setInterval(async () => { + // scheduler.workers.has('infrastructure') && scheduler.workers.get('infrastructure').postMessage("action:cleanupPrismaEngines") + // }, 60000) await getArch(); await getIPAddress(); diff --git a/apps/api/src/jobs/infrastructure.ts b/apps/api/src/jobs/infrastructure.ts index 52a566758..740d011d2 100644 --- a/apps/api/src/jobs/infrastructure.ts +++ b/apps/api/src/jobs/infrastructure.ts @@ -39,7 +39,7 @@ async function autoUpdater() { console.log(error); } } -async function checkProxies(){ +async function checkProxies() { try { const { default: isReachable } = await import('is-port-reachable'); let portReachable; @@ -50,7 +50,7 @@ async function checkProxies(){ const localDocker = await prisma.destinationDocker.findFirst({ where: { engine, network: 'coolify' } }); - if (localDocker && localDocker.isCoolifyProxyUsed) { + if (localDocker && localDocker.isCoolifyProxyUsed) { portReachable = await isReachable(80, { host: ipv4 || ipv6 }) console.log({ port: 80, portReachable }); if (!portReachable) { @@ -106,16 +106,16 @@ async function checkProxies(){ } } } - } catch(error) { + } catch (error) { } } -async function cleanupPrismaEngines(){ +async function cleanupPrismaEngines() { if (!isDev) { try { const { stdout } = await asyncExecShell(`ps -ef | grep /app/prisma-engines/query-engine | grep -v grep | wc -l | xargs`) if (stdout.trim() != null && stdout.trim() != '' && Number(stdout.trim()) > 1) { - await asyncExecShell(`killall -q -e /app/prisma-engines/query-engine -o 10m`) + await asyncExecShell(`killall -q -e /app/prisma-engines/query-engine -o 1m`) } } catch (error) { console.log(error); @@ -178,7 +178,7 @@ async function cleanupStorage() { } (async () => { - let status ={ + let status = { cleanupStorage: false, autoUpdater: false } diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index cceca5ba7..e3326c4a9 100644 --- a/apps/api/src/lib/common.ts +++ b/apps/api/src/lib/common.ts @@ -155,11 +155,11 @@ export const prisma = new PrismaClient({ ], }); -// prisma.$on('query', (e) => { -// console.log('Query: ' + e.query) -// console.log('Params: ' + e.params) -// console.log('Duration: ' + e.duration + 'ms') -// }) +prisma.$on('query', (e) => { + console.log('Query: ' + e.query) + console.log('Params: ' + e.params) + console.log('Duration: ' + e.duration + 'ms') + }) export const base64Encode = (text: string): string => { return Buffer.from(text).toString('base64'); }; diff --git a/apps/api/src/lib/scheduler.ts b/apps/api/src/lib/scheduler.ts index 71f5bc6f0..2e7db85cb 100644 --- a/apps/api/src/lib/scheduler.ts +++ b/apps/api/src/lib/scheduler.ts @@ -20,20 +20,6 @@ const options: any = { jobs: [ { name: 'infrastructure' }, { name: 'deployApplication' }, - // { - // name: 'cleanupStorage', - // }, - // { - // name: 'cleanupPrismaEngines', - // interval: '1m' - // }, - // { - // name: 'checkProxies', - // interval: '10s' - // }, - // { - // name: 'autoUpdater', - // } ], }; if (isDev) options.root = path.join(__dirname, '../jobs'); From f4f605867b83e0f63ef834a434f98180d51c460d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 09:09:41 +0200 Subject: [PATCH 22/32] hm --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 50f616291..fea6b8624 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,7 +21,7 @@ ENV PRISMA_QUERY_ENGINE_BINARY=/app/prisma-engines/query-engine \ PRISMA_CLI_QUERY_ENGINE_TYPE=binary \ PRISMA_CLIENT_ENGINE_TYPE=binary -COPY --from=coollabsio/prisma-engine:3.15 /prisma-engines/query-engine /app/prisma-engines/ +COPY --from=coollabsio/prisma-engine:3.15 /prisma-engines/query-engine /prisma-engines/migration-engine /prisma-engines/introspection-engine /prisma-engines/prisma-fmt /app/prisma-engines/ RUN apk add --no-cache git git-lfs openssh-client curl jq cmake sqlite openssl psmisc RUN curl -sL https://unpkg.com/@pnpm/self-installer | node From 12e91f1c6b81af077e6f209ace196790aca052dc Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 09:33:50 +0200 Subject: [PATCH 23/32] fix --- apps/api/src/lib/common.ts | 7 +- pnpm-lock.yaml | 208 ++++++++++++++++++++++++++++++++++--- 2 files changed, 200 insertions(+), 15 deletions(-) diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index e3326c4a9..da4cd3ebd 100644 --- a/apps/api/src/lib/common.ts +++ b/apps/api/src/lib/common.ts @@ -156,9 +156,10 @@ export const prisma = new PrismaClient({ }); prisma.$on('query', (e) => { - console.log('Query: ' + e.query) - console.log('Params: ' + e.params) - console.log('Duration: ' + e.duration + 'ms') + // console.log({e}) + // console.log('Query: ' + e.query) + // console.log('Params: ' + e.params) + // console.log('Duration: ' + e.duration + 'ms') }) export const base64Encode = (text: string): string => { return Buffer.from(text).toString('base64'); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0ac67fbb0..6788e9203 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,9 +6,11 @@ importers: specifiers: cross-var: 1.1.0 npm-run-all: 4.1.5 + opencollective-setup: 1.4.1 devDependencies: cross-var: 1.1.0 npm-run-all: 4.1.5 + opencollective-setup: 1.4.1 apps/api: specifiers: @@ -20,7 +22,7 @@ importers: '@fastify/jwt': 6.3.2 '@fastify/static': 6.5.0 '@iarna/toml': 2.2.5 - '@ladjs/graceful': ^3.0.2 + '@ladjs/graceful': 3.0.2 '@prisma/client': 3.15.2 '@types/node': 18.7.13 '@types/node-os-utils': 1.3.0 @@ -63,7 +65,7 @@ importers: typescript: 4.7.4 unique-names-generator: 4.7.1 dependencies: - '@breejs/ts-worker': 2.0.0_yjs2yukaec33oijlee4f5n7fqa + '@breejs/ts-worker': 2.0.0_rzqxabipis2a5sxrpk4obdh4zu '@fastify/autoload': 5.2.0 '@fastify/cookie': 8.0.0 '@fastify/cors': 8.1.0 @@ -168,7 +170,7 @@ importers: svelte: 3.49.0 svelte-check: 2.8.1_vylzxgme5yisu3bsyvcau4hjtq svelte-preprocess: 4.10.7_fje22ktja5v2dh6nbkissncqme - tailwindcss: 3.1.8_postcss@8.4.16 + tailwindcss: 3.1.8 tailwindcss-scrollbar: 0.1.0_tailwindcss@3.1.8 tslib: 2.4.0 typescript: 4.7.4 @@ -213,12 +215,11 @@ packages: engines: {node: '>= 10'} dev: false - /@breejs/ts-worker/2.0.0_yjs2yukaec33oijlee4f5n7fqa: + /@breejs/ts-worker/2.0.0_rzqxabipis2a5sxrpk4obdh4zu: resolution: {integrity: sha512-6anHRcmgYlF7mrm/YVRn6rx2cegLuiY3VBxkkimOTWC/dVQeH336imVSuIKEGKTwiuNTPr2hswVdDSneNuXg3A==} engines: {node: '>= 12.11'} peerDependencies: bree: '>=9.0.0' - tsconfig-paths: '>= 4' dependencies: bree: 9.1.2 ts-node: 10.8.2_57uwcby55h6tzvkj3v5sfcgxoe @@ -817,11 +818,23 @@ packages: engines: {node: '>=6'} dev: false + /ansi-escapes/4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + /ansi-regex/2.1.1: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} dev: true + /ansi-regex/4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + dev: true + /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1834,6 +1847,10 @@ packages: supports-color: 7.2.0 dev: true + /chardet/0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: true + /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -1864,6 +1881,17 @@ packages: hasBin: true dev: false + /cli-cursor/3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-width/2.2.1: + resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} + dev: true + /clone-regexp/3.0.0: resolution: {integrity: sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==} engines: {node: '>=12'} @@ -2085,7 +2113,7 @@ packages: css-selector-tokenizer: 0.8.0 postcss: 8.4.16 postcss-js: 4.0.0_postcss@8.4.16 - tailwindcss: 3.1.8_postcss@8.4.16 + tailwindcss: 3.1.8 transitivePeerDependencies: - ts-node dev: false @@ -2116,6 +2144,18 @@ packages: supports-color: 5.5.0 dev: true + /debug/4.1.1: + resolution: {integrity: sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==} + deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + /debug/4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -2180,6 +2220,11 @@ packages: repeating: 2.0.1 dev: true + /detect-indent/6.0.0: + resolution: {integrity: sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==} + engines: {node: '>=8'} + dev: true + /detect-indent/6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -2308,6 +2353,10 @@ packages: /electron-to-chromium/1.4.213: resolution: {integrity: sha512-+3DbGHGOCHTVB/Ms63bGqbyC1b8y7Fk86+7ltssB8NQrZtSCvZG6eooSl9U2Q0yw++fL2DpHKOdTU0NVEkFObg==} + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + /encodeurl/1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -3005,6 +3054,15 @@ packages: engines: {node: '>= 0.8.0'} dev: true + /external-editor/3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -3117,6 +3175,13 @@ packages: xtend: 4.0.2 dev: false + /figures/3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -3492,6 +3557,13 @@ packages: engines: {node: '>=12.20.0'} dev: false + /iconv-lite/0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false @@ -3536,6 +3608,25 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: false + /inquirer/7.0.0: + resolution: {integrity: sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==} + engines: {node: '>=6.0.0'} + dependencies: + ansi-escapes: 4.3.2 + chalk: 2.4.2 + cli-cursor: 3.1.0 + cli-width: 2.2.1 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + run-async: 2.4.1 + rxjs: 6.6.7 + string-width: 4.2.3 + strip-ansi: 5.2.0 + through: 2.3.8 + dev: true + /internal-slot/1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} @@ -3628,6 +3719,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + /is-glob/2.0.1: resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} engines: {node: '>=0.10.0'} @@ -4116,6 +4212,11 @@ packages: hasBin: true dev: false + /mimic-fn/2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + /mimic-fn/4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -4153,6 +4254,10 @@ packages: brace-expansion: 2.0.1 dev: false + /minimist/1.2.0: + resolution: {integrity: sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==} + dev: true + /minimist/1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} @@ -4187,6 +4292,10 @@ packages: /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + /mute-stream/0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + dev: true + /nan/2.16.0: resolution: {integrity: sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==} dev: false @@ -4219,6 +4328,11 @@ packages: lower-case: 1.1.4 dev: false + /node-fetch/2.6.0: + resolution: {integrity: sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==} + engines: {node: 4.x || >=6.0.0} + dev: true + /node-forge/1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} @@ -4350,6 +4464,13 @@ packages: dependencies: wrappy: 1.0.2 + /onetime/5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + /onetime/6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} @@ -4357,6 +4478,21 @@ packages: mimic-fn: 4.0.0 dev: false + /opencollective-setup/1.4.1: + resolution: {integrity: sha512-XdYWl35SewxvjJCeuFQSkuL1elwOsGYXpzT0/vOaszC16KNmHi1NoLfiN/YJiw/VeP4E+DYVI906oGsXp0b77g==} + engines: {node: 11.8.0, npm: 6.5.0} + hasBin: true + dependencies: + chalk: 2.4.2 + debug: 4.1.1 + detect-indent: 6.0.0 + inquirer: 7.0.0 + minimist: 1.2.0 + node-fetch: 2.6.0 + transitivePeerDependencies: + - supports-color + dev: true + /optionator/0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} @@ -4992,6 +5128,14 @@ packages: lowercase-keys: 2.0.0 dev: false + /restore-cursor/3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + /ret/0.2.2: resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} engines: {node: '>=4'} @@ -5027,11 +5171,23 @@ packages: fsevents: 2.3.2 dev: true + /run-async/2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + dev: true + /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 + /rxjs/6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + dependencies: + tslib: 1.14.1 + dev: true + /sade/1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} @@ -5064,7 +5220,6 @@ packages: /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: false /sander/0.5.1: resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==} @@ -5163,7 +5318,6 @@ packages: /signal-exit/3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: false /simple-swizzle/0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -5281,6 +5435,15 @@ packages: reusify: 1.0.4 dev: false + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + /string.prototype.padend/3.1.3: resolution: {integrity: sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==} engines: {node: '>= 0.4'} @@ -5319,6 +5482,13 @@ packages: ansi-regex: 2.1.1 dev: true + /strip-ansi/5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + dependencies: + ansi-regex: 4.1.1 + dev: true + /strip-ansi/6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -5516,15 +5686,13 @@ packages: peerDependencies: tailwindcss: '>= 2.x.x' dependencies: - tailwindcss: 3.1.8_postcss@8.4.16 + tailwindcss: 3.1.8 dev: true - /tailwindcss/3.1.8_postcss@8.4.16: + /tailwindcss/3.1.8: resolution: {integrity: sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==} engines: {node: '>=12.13.0'} hasBin: true - peerDependencies: - postcss: ^8.0.9 dependencies: arg: 5.0.2 chokidar: 3.5.3 @@ -5581,6 +5749,10 @@ packages: real-require: 0.1.0 dev: false + /through/2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + /time-span/5.1.0: resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} engines: {node: '>=12'} @@ -5600,6 +5772,13 @@ packages: engines: {node: '>=6'} dev: false + /tmp/0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: true + /to-fast-properties/1.0.3: resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} engines: {node: '>=0.10.0'} @@ -5705,6 +5884,11 @@ packages: engines: {node: '>=10'} dev: true + /type-fest/0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + /type-fest/0.6.0: resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} engines: {node: '>=8'} From 0f8f33e9fe557cbbcbabb4a7506c2deddfe3920c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 09:49:17 +0200 Subject: [PATCH 24/32] remove unnecessary things --- apps/api/src/jobs/autoUpdater.ts | 43 -- apps/api/src/jobs/checkProxies.ts | 81 ---- apps/api/src/jobs/cleanupPrismaEngines.ts | 19 - apps/api/src/jobs/cleanupStorage.ts | 60 --- apps/api/src/jobs/deployApplication-old.ts | 366 ------------------ apps/api/src/jobs/infrastructure.ts | 6 +- apps/api/src/lib/common.ts | 40 +- apps/api/src/lib/scheduler.ts | 4 +- .../applications/[id]/logs/build.svelte | 1 - 9 files changed, 23 insertions(+), 597 deletions(-) delete mode 100644 apps/api/src/jobs/autoUpdater.ts delete mode 100644 apps/api/src/jobs/checkProxies.ts delete mode 100644 apps/api/src/jobs/cleanupPrismaEngines.ts delete mode 100644 apps/api/src/jobs/cleanupStorage.ts delete mode 100644 apps/api/src/jobs/deployApplication-old.ts diff --git a/apps/api/src/jobs/autoUpdater.ts b/apps/api/src/jobs/autoUpdater.ts deleted file mode 100644 index 566ffea29..000000000 --- a/apps/api/src/jobs/autoUpdater.ts +++ /dev/null @@ -1,43 +0,0 @@ -import axios from 'axios'; -import compareVersions from 'compare-versions'; -import { parentPort } from 'node:worker_threads'; -import { asyncExecShell, asyncSleep, isDev, prisma, version } from '../lib/common'; - -(async () => { - if (parentPort) { - try { - const currentVersion = version; - const { data: versions } = await axios - .get( - `https://get.coollabs.io/versions.json` - , { - params: { - appId: process.env['COOLIFY_APP_ID'] || undefined, - version: currentVersion - } - }) - const latestVersion = versions['coolify'].main.version; - const isUpdateAvailable = compareVersions(latestVersion, currentVersion); - if (isUpdateAvailable === 1) { - const activeCount = 0 - if (activeCount === 0) { - if (!isDev) { - console.log(`Updating Coolify to ${latestVersion}.`); - await asyncExecShell(`docker pull coollabsio/coolify:${latestVersion}`); - await asyncExecShell(`env | grep COOLIFY > .env`); - await asyncExecShell( - `docker run --rm -tid --env-file .env -v /var/run/docker.sock:/var/run/docker.sock -v coolify-db coollabsio/coolify:${latestVersion} /bin/sh -c "env | grep COOLIFY > .env && echo 'TAG=${latestVersion}' >> .env && docker stop -t 0 coolify && docker rm coolify && docker compose up -d --force-recreate"` - ); - } else { - console.log('Updating (not really in dev mode).'); - } - } - } - } catch (error) { - console.log(error); - } finally { - await prisma.$disconnect(); - } - - } else process.exit(0); -})(); diff --git a/apps/api/src/jobs/checkProxies.ts b/apps/api/src/jobs/checkProxies.ts deleted file mode 100644 index 7ba6726ec..000000000 --- a/apps/api/src/jobs/checkProxies.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { parentPort } from 'node:worker_threads'; -import { prisma, startTraefikTCPProxy, generateDatabaseConfiguration, startTraefikProxy, executeDockerCmd, listSettings } from '../lib/common'; -import { checkContainer } from '../lib/docker'; - -(async () => { - if (parentPort) { - try { - const { default: isReachable } = await import('is-port-reachable'); - let portReachable; - - const { arch, ipv4, ipv6 } = await listSettings(); - // Coolify Proxy local - const engine = '/var/run/docker.sock'; - const localDocker = await prisma.destinationDocker.findFirst({ - where: { engine, network: 'coolify' } - }); - if (localDocker && localDocker.isCoolifyProxyUsed) { - portReachable = await isReachable(80, { host: ipv4 || ipv6 }) - console.log({ port: 80, portReachable }); - if (!portReachable) { - await startTraefikProxy(localDocker.id); - } - } - - // TCP Proxies - const databasesWithPublicPort = await prisma.database.findMany({ - where: { publicPort: { not: null } }, - include: { settings: true, destinationDocker: true } - }); - for (const database of databasesWithPublicPort) { - const { destinationDockerId, destinationDocker, publicPort, id } = database; - if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { - const { privatePort } = generateDatabaseConfiguration(database, arch); - portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) - console.log({ publicPort, portReachable }); - if (!portReachable) { - await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); - } - } - } - const wordpressWithFtp = await prisma.wordpress.findMany({ - where: { ftpPublicPort: { not: null } }, - include: { service: { include: { destinationDocker: true } } } - }); - for (const ftp of wordpressWithFtp) { - const { service, ftpPublicPort } = ftp; - const { destinationDockerId, destinationDocker, id } = service; - if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { - portReachable = await isReachable(ftpPublicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) - console.log({ ftpPublicPort, portReachable }); - if (!portReachable) { - await startTraefikTCPProxy(destinationDocker, id, ftpPublicPort, 22, 'wordpressftp'); - } - } - } - - // HTTP Proxies - const minioInstances = await prisma.minio.findMany({ - where: { publicPort: { not: null } }, - include: { service: { include: { destinationDocker: true } } } - }); - for (const minio of minioInstances) { - const { service, publicPort } = minio; - const { destinationDockerId, destinationDocker, id } = service; - if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { - portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) - console.log({ publicPort, portReachable }); - if (!portReachable) { - await startTraefikTCPProxy(destinationDocker, id, publicPort, 9000); - } - } - } - - } catch (error) { - - } finally { - await prisma.$disconnect(); - } - - } else process.exit(0); -})(); diff --git a/apps/api/src/jobs/cleanupPrismaEngines.ts b/apps/api/src/jobs/cleanupPrismaEngines.ts deleted file mode 100644 index 335bdce7d..000000000 --- a/apps/api/src/jobs/cleanupPrismaEngines.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { parentPort } from 'node:worker_threads'; -import { asyncExecShell, isDev, prisma } from '../lib/common'; - -(async () => { - if (parentPort) { - if (!isDev) { - try { - const { stdout } = await asyncExecShell(`ps -ef | grep /app/prisma-engines/query-engine | grep -v grep | wc -l | xargs`) - if (stdout.trim() != null && stdout.trim() != '' && Number(stdout.trim()) > 1) { - await asyncExecShell(`killall -q -e /app/prisma-engines/query-engine -o 10m`) - } - } catch (error) { - console.log(error); - } finally { - await prisma.$disconnect(); - } - } - } else process.exit(0); -})(); diff --git a/apps/api/src/jobs/cleanupStorage.ts b/apps/api/src/jobs/cleanupStorage.ts deleted file mode 100644 index 4740c1df8..000000000 --- a/apps/api/src/jobs/cleanupStorage.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { parentPort } from 'node:worker_threads'; -import { asyncExecShell, cleanupDockerStorage, executeDockerCmd, isDev, prisma } from '../lib/common'; - -(async () => { - if (parentPort) { - const destinationDockers = await prisma.destinationDocker.findMany(); - let enginesDone = new Set() - for (const destination of destinationDockers) { - if (enginesDone.has(destination.engine) || enginesDone.has(destination.remoteIpAddress)) return - if (destination.engine) enginesDone.add(destination.engine) - if (destination.remoteIpAddress) enginesDone.add(destination.remoteIpAddress) - - let lowDiskSpace = false; - try { - let stdout = null - if (!isDev) { - const output = await executeDockerCmd({ dockerId: destination.id, command: `CONTAINER=$(docker ps -lq | head -1) && docker exec $CONTAINER sh -c 'df -kPT /'` }) - stdout = output.stdout; - } else { - const output = await asyncExecShell( - `df -kPT /` - ); - stdout = output.stdout; - } - let lines = stdout.trim().split('\n'); - let header = lines[0]; - let regex = - /^Filesystem\s+|Type\s+|1024-blocks|\s+Used|\s+Available|\s+Capacity|\s+Mounted on\s*$/g; - const boundaries = []; - let match; - - while ((match = regex.exec(header))) { - boundaries.push(match[0].length); - } - - boundaries[boundaries.length - 1] = -1; - const data = lines.slice(1).map((line) => { - const cl = boundaries.map((boundary) => { - const column = boundary > 0 ? line.slice(0, boundary) : line; - line = line.slice(boundary); - return column.trim(); - }); - return { - capacity: Number.parseInt(cl[5], 10) / 100 - }; - }); - if (data.length > 0) { - const { capacity } = data[0]; - if (capacity > 0.8) { - lowDiskSpace = true; - } - } - } catch (error) { - console.log(error); - } - await cleanupDockerStorage(destination.id, lowDiskSpace, false) - } - await prisma.$disconnect(); - } else process.exit(0); -})(); diff --git a/apps/api/src/jobs/deployApplication-old.ts b/apps/api/src/jobs/deployApplication-old.ts deleted file mode 100644 index 93d358fe3..000000000 --- a/apps/api/src/jobs/deployApplication-old.ts +++ /dev/null @@ -1,366 +0,0 @@ -import { parentPort } from 'node:worker_threads'; -import crypto from 'crypto'; -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 * as importers from '../lib/importers'; -import * as buildpacks from '../lib/buildPacks'; - -(async () => { - if (parentPort) { - const concurrency = 1 - const PQueue = await import('p-queue'); - const queue = new PQueue.default({ concurrency }); - parentPort.on('message', async (message) => { - if (parentPort) { - if (message === 'error') throw new Error('oops'); - if (message === 'cancel') { - parentPort.postMessage('cancelled'); - return; - } - if (message === 'status:autoUpdater') { - parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'autoUpdater' }); - return; - } - if (message === 'status:cleanupStorage') { - parentPort.postMessage({ size: queue.size, pending: queue.pending, caller: 'cleanupStorage' }); - return; - } - if (message === 'action:flushQueue') { - queue.clear() - return; - } - - await queue.add(async () => { - const { - id: applicationId, - repository, - name, - destinationDocker, - destinationDockerId, - gitSource, - build_id: buildId, - configHash, - fqdn, - projectId, - secrets, - phpModules, - type, - pullmergeRequestId = null, - sourceBranch = null, - settings, - persistentStorage, - pythonWSGI, - pythonModule, - pythonVariable, - denoOptions, - exposePort, - baseImage, - baseBuildImage, - deploymentType, - forceRebuild - } = message - let { - branch, - buildPack, - port, - installCommand, - buildCommand, - startCommand, - baseDirectory, - publishDirectory, - dockerFileLocation, - denoMainFile - } = message - 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'); - try { - const { debug } = settings; - if (concurrency === 1) { - await prisma.build.updateMany({ - where: { - status: { in: ['queued', 'running'] }, - id: { not: buildId }, - applicationId, - createdAt: { lt: new Date(new Date().getTime() - 10 * 1000) } - }, - data: { status: 'failed' } - }); - } - let imageId = applicationId; - let domain = getDomain(fqdn); - const volumes = - persistentStorage?.map((storage) => { - return `${applicationId}${storage.path.replace(/\//gi, '-')}:${buildPack !== 'docker' ? '/app' : '' - }${storage.path}`; - }) || []; - // Previews, we need to get the source branch and set subdomain - if (pullmergeRequestId) { - branch = sourceBranch; - domain = `${pullmergeRequestId}.${domain}`; - imageId = `${applicationId}-${pullmergeRequestId}`; - } - - let deployNeeded = true; - let destinationType; - - if (destinationDockerId) { - destinationType = 'docker'; - } - if (destinationType === 'docker') { - await prisma.build.update({ where: { id: buildId }, data: { status: 'running' } }); - const { workdir, repodir } = await createDirectories({ repository, buildId }); - const configuration = await setDefaultConfiguration(message); - - buildPack = configuration.buildPack; - port = configuration.port; - installCommand = configuration.installCommand; - startCommand = configuration.startCommand; - buildCommand = configuration.buildCommand; - publishDirectory = configuration.publishDirectory; - baseDirectory = configuration.baseDirectory; - dockerFileLocation = configuration.dockerFileLocation; - denoMainFile = configuration.denoMainFile; - const commit = await importers[gitSource.type]({ - applicationId, - debug, - workdir, - repodir, - githubAppId: gitSource.githubApp?.id, - gitlabAppId: gitSource.gitlabApp?.id, - customPort: gitSource.customPort, - repository, - branch, - buildId, - apiUrl: gitSource.apiUrl, - htmlUrl: gitSource.htmlUrl, - projectId, - deployKeyId: gitSource.gitlabApp?.deployKeyId || null, - privateSshKey: decrypt(gitSource.gitlabApp?.privateSshKey) || null, - forPublic: gitSource.forPublic - }); - if (!commit) { - throw new Error('No commit found?'); - } - let tag = commit.slice(0, 7); - if (pullmergeRequestId) { - tag = `${commit.slice(0, 7)}-${pullmergeRequestId}`; - } - - try { - await prisma.build.update({ where: { id: buildId }, data: { commit } }); - } catch (err) { - console.log(err); - } - - if (!pullmergeRequestId) { - - if (configHash !== currentHash) { - deployNeeded = true; - if (configHash) { - await saveBuildLog({ line: 'Configuration changed.', buildId, applicationId }); - } - } else { - deployNeeded = false; - } - } else { - deployNeeded = true; - } - - let imageFound = false; - try { - await executeDockerCmd({ - dockerId: destinationDocker.id, - command: `docker image inspect ${applicationId}:${tag}` - }) - imageFound = true; - } catch (error) { - // - } - await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage); - - if (forceRebuild) deployNeeded = true - if (!imageFound || deployNeeded) { - // if (true) { - if (buildpacks[buildPack]) - await buildpacks[buildPack]({ - dockerId: destinationDocker.id, - buildId, - applicationId, - domain, - name, - type, - pullmergeRequestId, - buildPack, - repository, - branch, - projectId, - publishDirectory, - debug, - commit, - tag, - workdir, - port: exposePort ? `${exposePort}:${port}` : port, - installCommand, - buildCommand, - startCommand, - baseDirectory, - secrets, - phpModules, - pythonWSGI, - pythonModule, - pythonVariable, - dockerFileLocation, - denoMainFile, - denoOptions, - baseImage, - baseBuildImage, - deploymentType - }); - else { - await saveBuildLog({ line: `Build pack ${buildPack} not found`, buildId, applicationId }); - throw new Error(`Build pack ${buildPack} not found.`); - } - } else { - await saveBuildLog({ line: 'Build image already available - no rebuild required.', buildId, applicationId }); - } - try { - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker stop -t 0 ${imageId}` }) - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker rm ${imageId}` }) - } catch (error) { - // - } - const envs = [ - `PORT=${port}` - ]; - if (secrets.length > 0) { - secrets.forEach((secret) => { - if (pullmergeRequestId) { - if (secret.isPRMRSecret) { - envs.push(`${secret.name}=${secret.value}`); - } - } else { - if (!secret.isPRMRSecret) { - envs.push(`${secret.name}=${secret.value}`); - } - } - }); - } - await fs.writeFile(`${workdir}/.env`, envs.join('\n')); - const labels = makeLabelForStandaloneApplication({ - applicationId, - fqdn, - name, - type, - pullmergeRequestId, - buildPack, - repository, - branch, - projectId, - port: exposePort ? `${exposePort}:${port}` : port, - commit, - installCommand, - buildCommand, - startCommand, - baseDirectory, - publishDirectory - }); - let envFound = false; - try { - envFound = !!(await fs.stat(`${workdir}/.env`)); - } catch (error) { - // - } - try { - await saveBuildLog({ line: 'Deployment started.', buildId, applicationId }); - const composeVolumes = volumes.map((volume) => { - return { - [`${volume.split(':')[0]}`]: { - name: volume.split(':')[0] - } - }; - }); - const composeFile = { - version: '3.8', - services: { - [imageId]: { - image: `${applicationId}:${tag}`, - container_name: imageId, - volumes, - env_file: envFound ? [`${workdir}/.env`] : [], - labels, - depends_on: [], - expose: [port], - ...(exposePort ? { ports: [`${exposePort}:${port}`] } : {}), - // logging: { - // driver: 'fluentd', - // }, - ...defaultComposeConfiguration(destinationDocker.network), - } - }, - networks: { - [destinationDocker.network]: { - external: true - } - }, - volumes: Object.assign({}, ...composeVolumes) - }; - await fs.writeFile(`${workdir}/docker-compose.yml`, yaml.dump(composeFile)); - await executeDockerCmd({ dockerId: destinationDocker.id, command: `docker compose --project-directory ${workdir} up -d` }) - await saveBuildLog({ line: 'Deployment successful!', buildId, applicationId }); - } catch (error) { - await saveBuildLog({ line: error, buildId, applicationId }); - await prisma.build.updateMany({ - where: { id: message.build_id, status: { in: ['queued', 'running'] } }, - data: { status: 'failed' } - }); - throw new Error(error); - } - await saveBuildLog({ line: 'Proxy will be updated shortly.', buildId, applicationId }); - await prisma.build.update({ where: { id: message.build_id }, data: { status: 'success' } }); - if (!pullmergeRequestId) await prisma.application.update({ - where: { id: applicationId }, - data: { configHash: currentHash } - }); - } - - } - catch (error) { - await prisma.build.updateMany({ - where: { id: message.build_id, status: { in: ['queued', 'running'] } }, - data: { status: 'failed' } - }); - await saveBuildLog({ line: error, buildId, applicationId }); - } finally { - await prisma.$disconnect(); - } - }); - await prisma.$disconnect(); - } - }); - } else process.exit(0); -})(); diff --git a/apps/api/src/jobs/infrastructure.ts b/apps/api/src/jobs/infrastructure.ts index 740d011d2..d19163686 100644 --- a/apps/api/src/jobs/infrastructure.ts +++ b/apps/api/src/jobs/infrastructure.ts @@ -52,7 +52,6 @@ async function checkProxies() { }); if (localDocker && localDocker.isCoolifyProxyUsed) { portReachable = await isReachable(80, { host: ipv4 || ipv6 }) - console.log({ port: 80, portReachable }); if (!portReachable) { await startTraefikProxy(localDocker.id); } @@ -68,7 +67,6 @@ async function checkProxies() { if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { const { privatePort } = generateDatabaseConfiguration(database, arch); portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) - console.log({ publicPort, portReachable }); if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, publicPort, privatePort); } @@ -83,7 +81,6 @@ async function checkProxies() { const { destinationDockerId, destinationDocker, id } = service; if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { portReachable = await isReachable(ftpPublicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) - console.log({ ftpPublicPort, portReachable }); if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, ftpPublicPort, 22, 'wordpressftp'); } @@ -100,14 +97,13 @@ async function checkProxies() { const { destinationDockerId, destinationDocker, id } = service; if (destinationDockerId && destinationDocker.isCoolifyProxyUsed) { portReachable = await isReachable(publicPort, { host: destinationDocker.remoteIpAddress || ipv4 || ipv6 }) - console.log({ publicPort, portReachable }); if (!portReachable) { await startTraefikTCPProxy(destinationDocker, id, publicPort, 9000); } } } } catch (error) { - + } } async function cleanupPrismaEngines() { diff --git a/apps/api/src/lib/common.ts b/apps/api/src/lib/common.ts index da4cd3ebd..148bacfff 100644 --- a/apps/api/src/lib/common.ts +++ b/apps/api/src/lib/common.ts @@ -135,32 +135,32 @@ export const asyncSleep = (delay: number): Promise => new Promise((resolve) => setTimeout(resolve, delay)); export const prisma = new PrismaClient({ errorFormat: 'minimal', - log: [ - { - emit: 'event', - level: 'query', - }, - { - emit: 'stdout', - level: 'error', - }, - { - emit: 'stdout', - level: 'info', - }, - { - emit: 'stdout', - level: 'warn', - }, - ], + // log: [ + // { + // emit: 'event', + // level: 'query', + // }, + // { + // emit: 'stdout', + // level: 'error', + // }, + // { + // emit: 'stdout', + // level: 'info', + // }, + // { + // emit: 'stdout', + // level: 'warn', + // }, + // ], }); -prisma.$on('query', (e) => { +// prisma.$on('query', (e) => { // console.log({e}) // console.log('Query: ' + e.query) // console.log('Params: ' + e.params) // console.log('Duration: ' + e.duration + 'ms') - }) +// }) export const base64Encode = (text: string): string => { return Buffer.from(text).toString('base64'); }; diff --git a/apps/api/src/lib/scheduler.ts b/apps/api/src/lib/scheduler.ts index 2e7db85cb..ebff53e12 100644 --- a/apps/api/src/lib/scheduler.ts +++ b/apps/api/src/lib/scheduler.ts @@ -9,7 +9,8 @@ Bree.extend(TSBree); const options: any = { defaultExtension: 'js', - logger: new Cabin(), + // logger: new Cabin(), + logger: false, workerMessageHandler: async ({ name, message }) => { if (name === 'deployApplication' && message?.deploying) { if (scheduler.workers.has('autoUpdater') || scheduler.workers.has('cleanupStorage')) { @@ -24,7 +25,6 @@ const options: any = { }; if (isDev) options.root = path.join(__dirname, '../jobs'); - export const scheduler = new Bree(options); diff --git a/apps/ui/src/routes/applications/[id]/logs/build.svelte b/apps/ui/src/routes/applications/[id]/logs/build.svelte index 56faaf7d5..d1373e71e 100644 --- a/apps/ui/src/routes/applications/[id]/logs/build.svelte +++ b/apps/ui/src/routes/applications/[id]/logs/build.svelte @@ -158,7 +158,6 @@ {build.type}
-
{#if build.status === 'running'} From 7691706295a759488530a2624f92d38f1b91d881 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 10:00:48 +0200 Subject: [PATCH 25/32] fix lockfile --- pnpm-lock.yaml | 78 ++++++++++++-------------------------------------- 1 file changed, 18 insertions(+), 60 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 34c431e77..f99ba1f6c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,7 +172,7 @@ importers: svelte: 3.49.0 svelte-check: 2.8.1_vylzxgme5yisu3bsyvcau4hjtq svelte-preprocess: 4.10.7_fje22ktja5v2dh6nbkissncqme - tailwindcss: 3.1.8_postcss@8.4.16_postcss@8.4.16 + tailwindcss: 3.1.8 tailwindcss-scrollbar: 0.1.0_tailwindcss@3.1.8 tslib: 2.4.0 typescript: 4.7.4 @@ -420,8 +420,8 @@ packages: engines: {node: '>=14'} hasBin: true dependencies: - '@types/node': 18.6.5 - playwright-core: 1.24.2 + '@types/node': 18.7.13 + playwright-core: 1.25.1 dev: true /@prisma/client/3.15.2_prisma@3.15.2: @@ -535,7 +535,7 @@ packages: lodash.castarray: 4.4.0 lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 - tailwindcss: 3.1.8_postcss@8.4.16 + tailwindcss: 3.1.8 dev: false /@tsconfig/node10/1.0.8: @@ -593,16 +593,8 @@ packages: resolution: {integrity: sha512-XwVteWQx/XkfRPyaGkw8dEbrCAkoRZ73pI3XznUYIpzbCfpQB3UnDlR5TnmdhetlT889tUJGF8QWo9xrgTpsiA==} dev: true - /@types/node/18.0.3: - resolution: {integrity: sha512-HzNRZtp4eepNitP+BD6k2L6DROIDG4Q0fm4x+dwfsr6LGmROENnok75VGw40628xf+iR24WeMFcHuuBDUAzzsQ==} - dev: true - - /@types/node/18.6.5: - resolution: {integrity: sha512-Xjt5ZGUa5WusGZJ4WJPbOT8QOqp6nDynVFRKcUt32bOgvXEoc6o085WNkYTMO7ifAj2isEfQQ2cseE+wT6jsRw==} - dev: true - - /@types/node/18.7.11: - resolution: {integrity: sha512-KZhFpSLlmK/sdocfSAjqPETTMd0ug6HIMIAwkwUpU79olnZdQtMxpQP+G1wDzCH7na+FltSIhbaZuKdwZ8RDrw==} + /@types/node/18.7.13: + resolution: {integrity: sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==} /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -701,14 +693,19 @@ packages: /@typescript-eslint/types/5.35.1: resolution: {integrity: sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree/5.35.1_typescript@4.7.4: + resolution: {integrity: sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.33.0 - '@typescript-eslint/visitor-keys': 5.33.0 + '@typescript-eslint/types': 5.35.1 + '@typescript-eslint/visitor-keys': 5.35.1 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -719,55 +716,16 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree/5.34.0_typescript@4.7.4: - resolution: {integrity: sha512-mXHAqapJJDVzxauEkfJI96j3D10sd567LlqroyCeJaHnu42sDbjxotGb3XFtGPYKPD9IyLjhsoULML1oI3M86A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.34.0 - '@typescript-eslint/visitor-keys': 5.34.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.7 - tsutils: 3.21.0_typescript@4.7.4 - typescript: 4.7.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/utils/5.33.0_qugx7qdu5zevzvxaiqyxfiwquq: - resolution: {integrity: sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==} + /@typescript-eslint/utils/5.35.1_4rv7y5c6xz3vfxwhbrcxxi73bq: + resolution: {integrity: sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.33.0 - '@typescript-eslint/types': 5.33.0 - '@typescript-eslint/typescript-estree': 5.33.0_typescript@4.7.4 - eslint: 8.21.0 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.21.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/utils/5.34.0_4rv7y5c6xz3vfxwhbrcxxi73bq: - resolution: {integrity: sha512-kWRYybU4Rn++7lm9yu8pbuydRyQsHRoBDIo11k7eqBWTldN4xUdVUMCsHBiE7aoEkFzrUEaZy3iH477vr4xHAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@types/json-schema': 7.0.11 - '@typescript-eslint/scope-manager': 5.34.0 - '@typescript-eslint/types': 5.34.0 - '@typescript-eslint/typescript-estree': 5.34.0_typescript@4.7.4 + '@typescript-eslint/scope-manager': 5.35.1 + '@typescript-eslint/types': 5.35.1 + '@typescript-eslint/typescript-estree': 5.35.1_typescript@4.7.4 eslint: 8.22.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@8.22.0 From 3b95d7278d817ddd3eb9a6551e0dd0daeb32103c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 10:22:50 +0200 Subject: [PATCH 26/32] ui: dashboard fine-tunes --- apps/ui/src/lib/components/Usage.svelte | 24 +++--- .../components/svg/applications/Docker.svelte | 81 ++----------------- .../svg/services/PlausibleAnalytics.svelte | 2 +- .../components/svg/services/Searxng.svelte | 3 +- apps/ui/src/routes/index.svelte | 62 +++++++------- 5 files changed, 47 insertions(+), 125 deletions(-) diff --git a/apps/ui/src/lib/components/Usage.svelte b/apps/ui/src/lib/components/Usage.svelte index 46854145e..00915b767 100644 --- a/apps/ui/src/lib/components/Usage.svelte +++ b/apps/ui/src/lib/components/Usage.svelte @@ -54,68 +54,68 @@

Hardware details

-
+
Total Memory
-
+
{(usage?.memory.totalMemMb).toFixed(0)}MB
Used Memory
-
+
{(usage?.memory.usedMemMb).toFixed(0)}MB
Free Memory
-
+
{usage?.memory.freeMemPercentage}%
-
+
Total CPUs
-
+
{usage?.cpu.count}
CPU Usage
-
+
{usage?.cpu.usage}%
Load Average (5,10,30mins)
-
{usage?.cpu.load}
+
{usage?.cpu.load}
-
+
Total Disk
-
+
{usage?.disk.totalGb}GB
Used Disk
-
+
{usage?.disk.usedGb}GB
Free Disk
-
{usage?.disk.freePercentage}%
+
{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 981d4d225..ea1787bd9 100644 --- a/apps/ui/src/lib/components/svg/applications/Docker.svelte +++ b/apps/ui/src/lib/components/svg/applications/Docker.svelte @@ -2,79 +2,8 @@ export let isAbsolute = true; - - - + + + + + diff --git a/apps/ui/src/lib/components/svg/services/PlausibleAnalytics.svelte b/apps/ui/src/lib/components/svg/services/PlausibleAnalytics.svelte index c02a9e6d9..e10ead645 100644 --- a/apps/ui/src/lib/components/svg/services/PlausibleAnalytics.svelte +++ b/apps/ui/src/lib/components/svg/services/PlausibleAnalytics.svelte @@ -4,6 +4,6 @@ plausible logo diff --git a/apps/ui/src/lib/components/svg/services/Searxng.svelte b/apps/ui/src/lib/components/svg/services/Searxng.svelte index 52cbaed81..bb775d2bf 100644 --- a/apps/ui/src/lib/components/svg/services/Searxng.svelte +++ b/apps/ui/src/lib/components/svg/services/Searxng.svelte @@ -3,7 +3,6 @@ diff --git a/apps/ui/src/routes/index.svelte b/apps/ui/src/routes/index.svelte index 896c029b8..e5ba5c05e 100644 --- a/apps/ui/src/routes/index.svelte +++ b/apps/ui/src/routes/index.svelte @@ -108,14 +108,14 @@
{#each applications as application} -
+
{#await getStatus(application)} - + {:then status} - {#if status === 'Running'}1 - + {#if status === 'Running'} + {:else} - + {/if} {/await}
@@ -129,12 +129,12 @@

{application.name}

-
+
{#if application.fqdn} - + - Website {/if} {#if application.settings.isBot && application.exposePort} - Server {/if} - + - Manage
@@ -208,14 +205,14 @@
{#each services as service} -
+
{#await getStatus(service)} - + {:then status} {#if status === 'Running'}1 - + {:else} - + {/if} {/await}
@@ -226,12 +223,12 @@

{service.name}

-
+
{#if service.fqdn} - + - Website {/if} - + - Manage
@@ -281,14 +276,14 @@
{#each databases as database} -
+
{#await getStatus(database)} - + {:then status} {#if status === 'Running'}1 - + {:else} - + {/if} {/await}
@@ -299,11 +294,11 @@

{database.name}

- From 0e8b0697815b7f75f29425befe6e3cbb622473f4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 10:29:45 +0200 Subject: [PATCH 27/32] ui: fine-tune --- apps/ui/src/lib/components/Usage.svelte | 43 ++- apps/ui/src/routes/index.svelte | 340 +++++++++--------------- 2 files changed, 160 insertions(+), 223 deletions(-) diff --git a/apps/ui/src/lib/components/Usage.svelte b/apps/ui/src/lib/components/Usage.svelte index 00915b767..66b201da3 100644 --- a/apps/ui/src/lib/components/Usage.svelte +++ b/apps/ui/src/lib/components/Usage.svelte @@ -22,9 +22,9 @@ usage: false, cleanup: false }; - import { appSession } from '$lib/store'; + import { addToast, appSession } from '$lib/store'; import { onDestroy, onMount } from 'svelte'; - import { get } from '$lib/api'; + import { get, post } from '$lib/api'; import { errorNotification } from '$lib/common'; async function getStatus() { if (loading.usage) return; @@ -48,13 +48,36 @@ return errorNotification(error); } }); + async function manuallyCleanupStorage() { + try { + loading.cleanup = true; + await post('/internal/cleanup', {}); + return addToast({ + message: 'Cleanup done.', + type: 'success' + }); + } catch (error) { + return errorNotification(error); + } finally { + loading.cleanup = false; + } + }
-

Hardware details

+
+

Hardware Details

+ {#if $appSession.teamId === '0'} + + {/if} +
-
+
Total Memory
@@ -77,7 +100,9 @@
-
+
Total CPUs
@@ -98,7 +123,9 @@
-
+
Total Disk
@@ -115,7 +142,9 @@
Free Disk
-
{usage?.disk.freePercentage}%
+
+ {usage?.disk.freePercentage}% +
diff --git a/apps/ui/src/routes/index.svelte b/apps/ui/src/routes/index.svelte index e5ba5c05e..dde8186c5 100644 --- a/apps/ui/src/routes/index.svelte +++ b/apps/ui/src/routes/index.svelte @@ -36,10 +36,6 @@ import ServiceIcons from '$lib/components/svg/services/ServiceIcons.svelte'; import { dev } from '$app/env'; - let loading = { - cleanup: false - }; - let numberOfGetStatus = 0; function getRndInteger(min: number, max: number) { @@ -75,253 +71,165 @@ numberOfGetStatus--; } } - async function manuallyCleanupStorage() { - try { - loading.cleanup = true; - await post('/internal/cleanup', {}); - return addToast({ - message: 'Cleanup done.', - type: 'success' - }); - } catch (error) { - return errorNotification(error); - } finally { - loading.cleanup = false; - } - }
{$t('index.dashboard')}
- {#if $appSession.teamId === '0'} - - {/if}
{#if $appSession.teamId === '0'} {/if} {#if applications.length > 0} -

Resources

+

Applications

{#each applications as application} -
- {#await getStatus(application)} - - {:then status} - {#if status === 'Running'} - - {:else} - - {/if} - {/await} -
- -
- - Application - {#if application.settings.isBot} - | BOT - {/if} - -

{application.name}

-
-

Services

{#each services as service} -
- {#await getStatus(service)} - - {:then status} - {#if status === 'Running'}1 - - {:else} - - {/if} - {/await} -
- -
- - Service - -

{service.name}

-
-

Databases

{#each databases as database} -
- {#await getStatus(database)} - - {:then status} - {#if status === 'Running'}1 - - {:else} - - {/if} - {/await} -
- -
- - Service - -

{database.name}

-
- {:else if $appSession.teamId !== '0'} From 05ee35b6bc91d2760dc9030e385c7fe4e8b204da Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 12:07:21 +0200 Subject: [PATCH 28/32] typo --- apps/ui/src/routes/index.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/ui/src/routes/index.svelte b/apps/ui/src/routes/index.svelte index dde8186c5..67708fcf0 100644 --- a/apps/ui/src/routes/index.svelte +++ b/apps/ui/src/routes/index.svelte @@ -166,7 +166,7 @@ {#await getStatus(service)} {:then status} - {#if status === 'Running'}1 + {#if status === 'Running'} {:else} @@ -214,7 +214,7 @@ {#await getStatus(database)} {:then status} - {#if status === 'Running'}1 + {#if status === 'Running'} {:else} From 7528ca18d8bcd9fa5bbeda0bee890f1263eeadf8 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 12:46:20 +0200 Subject: [PATCH 29/32] ui: fixes feat: restart coolify button --- apps/api/src/routes/api/v1/handlers.ts | 17 ++++++ apps/api/src/routes/api/v1/index.ts | 6 ++- apps/ui/src/lib/components/Usage.svelte | 71 ++++++++++++++++--------- apps/ui/src/routes/index.svelte | 38 +++++++------ 4 files changed, 92 insertions(+), 40 deletions(-) diff --git a/apps/api/src/routes/api/v1/handlers.ts b/apps/api/src/routes/api/v1/handlers.ts index ae558320e..ed7a77c6e 100644 --- a/apps/api/src/routes/api/v1/handlers.ts +++ b/apps/api/src/routes/api/v1/handlers.ts @@ -73,6 +73,23 @@ export async function update(request: FastifyRequest) { return errorHandler({ status, message }) } } +export async function restartCoolify(request: FastifyRequest) { + try { + const teamId = request.user.teamId; + if (teamId === '0') { + if (!isDev) { + await asyncExecShell(`docker restart coolify`); + return {}; + } else { + console.log('Restarting Coolify') + return {}; + } + } + throw { status: 500, message: 'You are not authorized to restart Coolify.' }; + } catch ({ status, message }) { + return errorHandler({ status, message }) + } +} export async function showUsage() { try { return { diff --git a/apps/api/src/routes/api/v1/index.ts b/apps/api/src/routes/api/v1/index.ts index 0d145312d..8f9f821f8 100644 --- a/apps/api/src/routes/api/v1/index.ts +++ b/apps/api/src/routes/api/v1/index.ts @@ -1,5 +1,5 @@ import { FastifyPluginAsync } from 'fastify'; -import { checkUpdate, login, showDashboard, update, showUsage, getCurrentUser, cleanupManually } from './handlers'; +import { checkUpdate, login, showDashboard, update, showUsage, getCurrentUser, cleanupManually, restartCoolify } from './handlers'; import { GetCurrentUser } from './types'; export interface Update { @@ -47,6 +47,10 @@ const root: FastifyPluginAsync = async (fastify): Promise => { onRequest: [fastify.authenticate] }, async () => await showUsage()); + fastify.post('/internal/restart', { + onRequest: [fastify.authenticate] + }, async (request) => await restartCoolify(request)); + fastify.post('/internal/cleanup', { onRequest: [fastify.authenticate] }, async () => await cleanupManually()); diff --git a/apps/ui/src/lib/components/Usage.svelte b/apps/ui/src/lib/components/Usage.svelte index 66b201da3..a461f8419 100644 --- a/apps/ui/src/lib/components/Usage.svelte +++ b/apps/ui/src/lib/components/Usage.svelte @@ -20,7 +20,8 @@ let usageInterval: any; let loading = { usage: false, - cleanup: false + cleanup: false, + restart: false }; import { addToast, appSession } from '$lib/store'; import { onDestroy, onMount } from 'svelte'; @@ -33,6 +34,25 @@ usage = data.usage; loading.usage = false; } + async function restartCoolify() { + const sure = confirm( + 'Are you sure you would like to restart Coolify? Currently running deployments will be stopped and restarted.' + ); + if (sure) { + loading.restart = true; + try { + await post(`/internal/restart`, {}); + addToast({ + type: 'success', + message: 'Coolify restarted successfully. It will take a moment.' + }); + } catch (error) { + return errorNotification(error); + } finally { + loading.restart = false; + } + } + } onDestroy(() => { clearInterval(usageInterval); }); @@ -67,51 +87,56 @@

Hardware Details

- {#if $appSession.teamId === '0'} - - {/if} +
+ {#if $appSession.teamId === '0'} + + + {/if} +
-
+
+
Memory
-
Total Memory
+
Total
{(usage?.memory.totalMemMb).toFixed(0)}MB
-
Used Memory
+
Used
{(usage?.memory.usedMemMb).toFixed(0)}MB
-
Free Memory
+
Free
{usage?.memory.freeMemPercentage}%
-
+
+
CPU
-
Total CPUs
+
Total
{usage?.cpu.count}
-
CPU Usage
+
Usage
{usage?.cpu.usage}%
@@ -122,26 +147,24 @@
{usage?.cpu.load}
- -
+
+
Disk
-
Total Disk
+
Total
{usage?.disk.totalGb}GB
-
Used Disk
+
Used
{usage?.disk.usedGb}GB
-
Free Disk
+
Free
{usage?.disk.freePercentage}%
diff --git a/apps/ui/src/routes/index.svelte b/apps/ui/src/routes/index.svelte index 67708fcf0..52b8ad172 100644 --- a/apps/ui/src/routes/index.svelte +++ b/apps/ui/src/routes/index.svelte @@ -86,7 +86,7 @@
{#each applications as application} -
+
{#await getStatus(application)} {:then status} @@ -99,15 +99,18 @@
- - Application +

+ {application.name} {#if application.settings.isBot} | BOT {/if} - -

{application.name}

-
-
+ + {#if application?.fqdn} +

{application?.fqdn}

+ {:else if !application.settings.isBot && !application?.fqdn} +

Not configured

+ {/if} +
+ {/if} + {#if services.length > 0}

Services

{#each services as service} -
+
{#await getStatus(service)} {:then status} @@ -175,10 +180,13 @@
- Service

{service.name}

-
-
+ {#if service?.fqdn} +

{service?.fqdn}

+ {:else} +

Not configured

+ {/if} +
+ {/if} + {#if databases.length > 0}

Databases

{#each databases as database} -
+
{#await getStatus(database)} {:then status} @@ -220,12 +230,10 @@ {/if} {/await} -
+
- Service

{database.name}

-
From cf9e122bd26bb587602aadb5d503488f39046efb Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 13:17:35 +0200 Subject: [PATCH 30/32] ui: fixes --- apps/api/src/routes/api/v1/handlers.ts | 3 +- apps/ui/src/routes/index.svelte | 116 ++++++++++++++++--------- 2 files changed, 75 insertions(+), 44 deletions(-) diff --git a/apps/api/src/routes/api/v1/handlers.ts b/apps/api/src/routes/api/v1/handlers.ts index ed7a77c6e..f5946c447 100644 --- a/apps/api/src/routes/api/v1/handlers.ts +++ b/apps/api/src/routes/api/v1/handlers.ts @@ -118,7 +118,8 @@ export async function showDashboard(request: FastifyRequest) { include: { settings: true } }); const databases = await prisma.database.findMany({ - where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } } + where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } }, + include: { settings: true } }); const services = await prisma.service.findMany({ where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } } diff --git a/apps/ui/src/routes/index.svelte b/apps/ui/src/routes/index.svelte index 52b8ad172..7380250a1 100644 --- a/apps/ui/src/routes/index.svelte +++ b/apps/ui/src/routes/index.svelte @@ -80,13 +80,13 @@ {#if $appSession.teamId === '0'} {/if} - {#if applications.length > 0} -

Applications

-
-
+

Applications

+
+
+ {#if applications.length > 0} {#each applications as application} -
+
{#await getStatus(application)} {:then status} @@ -99,18 +99,20 @@
-

+

{application.name} {#if application.settings.isBot} - | BOT + BOT {/if}

- {#if application?.fqdn} -

{application?.fqdn}

- {:else if !application.settings.isBot && !application?.fqdn} -

Not configured

- {/if} -
+
+ {#if application?.fqdn} +

{application?.fqdn}

+ {:else if !application.settings.isBot && !application?.fqdn} +

Not configured

+ {/if} +
+
- {/if} - {#if services.length > 0} -

Services

-
-
+ {:else} +

Nothing is configured yet.

+ {/if} +
+

Services

+
+
+ {#if services.length > 0} {#each services as service} -
+
{#await getStatus(service)} {:then status} @@ -180,15 +184,17 @@
-

{service.name}

- {#if service?.fqdn} -

{service?.fqdn}

- {:else} -

Not configured

- {/if} -
+

{service.name}

+
+ {#if service?.fqdn} +

{service?.fqdn}

+ {:else} +

Not configured

+ {/if} +
+
- {/if} - {#if databases.length > 0} -

Databases

-
-
+ {:else} +

Nothing is configured yet.

+ {/if} +
+ +

Databases

+
+
+ {#if databases.length > 0} {#each databases as database} - - {:else if $appSession.teamId !== '0'} -
-

Nothing is configured yet.

-
- {/if} + {:else} +

Nothing is configured yet.

+ {/if} +
From 91bb323e847e45734ef3db3e52aa7b41d439264f Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 26 Aug 2022 13:22:43 +0200 Subject: [PATCH 31/32] ui fixes --- .../components/svg/services/Appwrite.svelte | 2 +- .../lib/components/svg/services/Fider.svelte | 2 +- .../components/svg/services/GlitchTip.svelte | 2 +- apps/ui/src/routes/index.svelte | 47 ++++++++++--------- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/apps/ui/src/lib/components/svg/services/Appwrite.svelte b/apps/ui/src/lib/components/svg/services/Appwrite.svelte index fbabd5168..5523a6f09 100644 --- a/apps/ui/src/lib/components/svg/services/Appwrite.svelte +++ b/apps/ui/src/lib/components/svg/services/Appwrite.svelte @@ -4,7 +4,7 @@ diff --git a/apps/ui/src/lib/components/svg/services/Fider.svelte b/apps/ui/src/lib/components/svg/services/Fider.svelte index 6d7ccaba7..e94c94591 100644 --- a/apps/ui/src/lib/components/svg/services/Fider.svelte +++ b/apps/ui/src/lib/components/svg/services/Fider.svelte @@ -5,7 +5,7 @@
{#if application?.fqdn} -

{application?.fqdn}

+

{application?.fqdn.replace('https://','').replace('http://','')}

{:else if !application.settings.isBot && !application?.fqdn}

Not configured

{/if}