fix: expose port checker
This commit is contained in:
parent
ac1991291d
commit
df01139c41
@ -994,8 +994,24 @@ export async function updatePasswordInDb(database, user, newPassword, isRoot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export async function getExposedFreePort(id, exposePort) {
|
||||||
export async function getFreePort() {
|
const { default: getPort } = await import('get-port');
|
||||||
|
const applicationUsed = await (
|
||||||
|
await prisma.application.findMany({
|
||||||
|
where: { exposePort: { not: null }, id: { not: id } },
|
||||||
|
select: { exposePort: true }
|
||||||
|
})
|
||||||
|
).map((a) => a.exposePort);
|
||||||
|
const serviceUsed = await (
|
||||||
|
await prisma.service.findMany({
|
||||||
|
where: { exposePort: { not: null }, id: { not: id } },
|
||||||
|
select: { exposePort: true }
|
||||||
|
})
|
||||||
|
).map((a) => a.exposePort);
|
||||||
|
const usedPorts = [...applicationUsed, ...serviceUsed];
|
||||||
|
return await getPort({ port: exposePort, exclude: usedPorts });
|
||||||
|
}
|
||||||
|
export async function getFreePublicPort() {
|
||||||
const { default: getPort, portNumbers } = await import('get-port');
|
const { default: getPort, portNumbers } = await import('get-port');
|
||||||
const data = await prisma.setting.findFirst();
|
const data = await prisma.setting.findFirst();
|
||||||
const { minPort, maxPort } = data;
|
const { minPort, maxPort } = data;
|
||||||
|
@ -5,7 +5,7 @@ import axios from 'axios';
|
|||||||
import { FastifyReply } from 'fastify';
|
import { FastifyReply } from 'fastify';
|
||||||
import { day } from '../../../../lib/dayjs';
|
import { day } from '../../../../lib/dayjs';
|
||||||
import { setDefaultBaseImage, setDefaultConfiguration } from '../../../../lib/buildPacks/common';
|
import { setDefaultBaseImage, setDefaultConfiguration } from '../../../../lib/buildPacks/common';
|
||||||
import { asyncExecShell, checkDomainsIsValidInDNS, checkDoubleBranch, decrypt, encrypt, errorHandler, executeDockerCmd, generateSshKeyPair, getContainerUsage, getDomain, isDev, isDomainConfigured, prisma, stopBuild, uniqueName } from '../../../../lib/common';
|
import { checkDomainsIsValidInDNS, checkDoubleBranch, decrypt, encrypt, errorHandler, executeDockerCmd, generateSshKeyPair, getContainerUsage, getDomain, getExposedFreePort, isDev, isDomainConfigured, prisma, stopBuild, uniqueName } from '../../../../lib/common';
|
||||||
import { checkContainer, dockerInstance, isContainerExited, removeContainer } from '../../../../lib/docker';
|
import { checkContainer, dockerInstance, isContainerExited, removeContainer } from '../../../../lib/docker';
|
||||||
import { scheduler } from '../../../../lib/scheduler';
|
import { scheduler } from '../../../../lib/scheduler';
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ export async function getImages(request: FastifyRequest<GetImages>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return { baseImage, baseBuildImage, baseBuildImages, baseImages, publishDirectory, port }
|
return { baseBuildImage, baseBuildImages, publishDirectory, port }
|
||||||
} catch ({ status, message }) {
|
} catch ({ status, message }) {
|
||||||
return errorHandler({ status, message })
|
return errorHandler({ status, message })
|
||||||
}
|
}
|
||||||
@ -249,6 +249,7 @@ export async function saveApplication(request: FastifyRequest<SaveApplication>,
|
|||||||
dockerFileLocation,
|
dockerFileLocation,
|
||||||
denoMainFile
|
denoMainFile
|
||||||
});
|
});
|
||||||
|
console.log({ baseImage })
|
||||||
await prisma.application.update({
|
await prisma.application.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: {
|
data: {
|
||||||
@ -352,7 +353,9 @@ export async function checkDNS(request: FastifyRequest<CheckDNS>) {
|
|||||||
const { id } = request.params
|
const { id } = request.params
|
||||||
|
|
||||||
let { exposePort, fqdn, forceSave, dualCerts } = request.body
|
let { exposePort, fqdn, forceSave, dualCerts } = request.body
|
||||||
fqdn = fqdn.toLowerCase();
|
|
||||||
|
if (fqdn) fqdn = fqdn.toLowerCase();
|
||||||
|
if (exposePort) exposePort = Number(exposePort);
|
||||||
|
|
||||||
const { isDNSCheckEnabled } = await prisma.setting.findFirst({});
|
const { isDNSCheckEnabled } = await prisma.setting.findFirst({});
|
||||||
const found = await isDomainConfigured({ id, fqdn });
|
const found = await isDomainConfigured({ id, fqdn });
|
||||||
@ -360,14 +363,12 @@ export async function checkDNS(request: FastifyRequest<CheckDNS>) {
|
|||||||
throw { status: 500, message: `Domain ${getDomain(fqdn).replace('www.', '')} is already in use!` }
|
throw { status: 500, message: `Domain ${getDomain(fqdn).replace('www.', '')} is already in use!` }
|
||||||
}
|
}
|
||||||
if (exposePort) {
|
if (exposePort) {
|
||||||
exposePort = Number(exposePort);
|
|
||||||
|
|
||||||
if (exposePort < 1024 || exposePort > 65535) {
|
if (exposePort < 1024 || exposePort > 65535) {
|
||||||
throw { status: 500, message: `Exposed Port needs to be between 1024 and 65535.` }
|
throw { status: 500, message: `Exposed Port needs to be between 1024 and 65535.` }
|
||||||
}
|
}
|
||||||
const { default: getPort } = await import('get-port');
|
const availablePort = await getExposedFreePort(id, exposePort);
|
||||||
const publicPort = await getPort({ port: exposePort });
|
if (availablePort.toString() !== exposePort.toString()) {
|
||||||
if (publicPort !== exposePort) {
|
|
||||||
throw { status: 500, message: `Port ${exposePort} is already in use.` }
|
throw { status: 500, message: `Port ${exposePort} is already in use.` }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -765,13 +766,13 @@ export async function getApplicationLogs(request: FastifyRequest<GetApplicationL
|
|||||||
try {
|
try {
|
||||||
// const found = await checkContainer({ dockerId, container: id })
|
// const found = await checkContainer({ dockerId, container: id })
|
||||||
// if (found) {
|
// if (found) {
|
||||||
const { default: ansi } = await import('strip-ansi')
|
const { default: ansi } = await import('strip-ansi')
|
||||||
const { stdout, stderr } = await executeDockerCmd({ dockerId, command: `docker logs --since ${since} --tail 5000 --timestamps ${id}` })
|
const { stdout, stderr } = await executeDockerCmd({ dockerId, command: `docker logs --since ${since} --tail 5000 --timestamps ${id}` })
|
||||||
const stripLogsStdout = stdout.toString().split('\n').map((l) => ansi(l)).filter((a) => a);
|
const stripLogsStdout = stdout.toString().split('\n').map((l) => ansi(l)).filter((a) => a);
|
||||||
const stripLogsStderr = stderr.toString().split('\n').map((l) => ansi(l)).filter((a) => a);
|
const stripLogsStderr = stderr.toString().split('\n').map((l) => ansi(l)).filter((a) => a);
|
||||||
const logs = stripLogsStderr.concat(stripLogsStdout)
|
const logs = stripLogsStderr.concat(stripLogsStdout)
|
||||||
const sortedLogs = logs.sort((a, b) => (day(a.split(' ')[0]).isAfter(day(b.split(' ')[0])) ? 1 : -1))
|
const sortedLogs = logs.sort((a, b) => (day(a.split(' ')[0]).isAfter(day(b.split(' ')[0])) ? 1 : -1))
|
||||||
return { logs: sortedLogs }
|
return { logs: sortedLogs }
|
||||||
// }
|
// }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const { statusCode } = error;
|
const { statusCode } = error;
|
||||||
|
@ -3,7 +3,7 @@ import type { FastifyRequest } from 'fastify';
|
|||||||
import { FastifyReply } from 'fastify';
|
import { FastifyReply } from 'fastify';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { ComposeFile, createDirectories, decrypt, encrypt, errorHandler, executeDockerCmd, generateDatabaseConfiguration, generatePassword, getContainerUsage, getDatabaseImage, getDatabaseVersions, getFreePort, listSettings, makeLabelForStandaloneDatabase, prisma, startTraefikTCPProxy, stopDatabaseContainer, stopTcpHttpProxy, supportedDatabaseTypesAndVersions, uniqueName, updatePasswordInDb } from '../../../../lib/common';
|
import { ComposeFile, createDirectories, decrypt, encrypt, errorHandler, executeDockerCmd, generateDatabaseConfiguration, generatePassword, getContainerUsage, getDatabaseImage, getDatabaseVersions, getFreePublicPort, listSettings, makeLabelForStandaloneDatabase, prisma, startTraefikTCPProxy, stopDatabaseContainer, stopTcpHttpProxy, supportedDatabaseTypesAndVersions, uniqueName, updatePasswordInDb } from '../../../../lib/common';
|
||||||
import { checkContainer } from '../../../../lib/docker';
|
import { checkContainer } from '../../../../lib/docker';
|
||||||
import { day } from '../../../../lib/dayjs';
|
import { day } from '../../../../lib/dayjs';
|
||||||
|
|
||||||
@ -431,7 +431,7 @@ export async function saveDatabaseSettings(request: FastifyRequest<SaveDatabaseS
|
|||||||
const teamId = request.user.teamId;
|
const teamId = request.user.teamId;
|
||||||
const { id } = request.params;
|
const { id } = request.params;
|
||||||
const { isPublic, appendOnly = true } = request.body;
|
const { isPublic, appendOnly = true } = request.body;
|
||||||
const publicPort = await getFreePort();
|
const publicPort = await getFreePublicPort();
|
||||||
const settings = await listSettings();
|
const settings = await listSettings();
|
||||||
await prisma.database.update({
|
await prisma.database.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
|
@ -2,7 +2,7 @@ import type { FastifyReply, FastifyRequest } from 'fastify';
|
|||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import bcrypt from 'bcryptjs';
|
import bcrypt from 'bcryptjs';
|
||||||
import { prisma, uniqueName, asyncExecShell, getServiceImage, getServiceImages, configureServiceType, getServiceFromDB, getContainerUsage, removeService, isDomainConfigured, saveUpdateableFields, fixType, decrypt, encrypt, getServiceMainPort, createDirectories, ComposeFile, makeLabelForServices, getFreePort, getDomain, errorHandler, generatePassword, isDev, stopTcpHttpProxy, supportedServiceTypesAndVersions, executeDockerCmd, listSettings } from '../../../../lib/common';
|
import { prisma, uniqueName, asyncExecShell, getServiceImage, configureServiceType, getServiceFromDB, getContainerUsage, removeService, isDomainConfigured, saveUpdateableFields, fixType, decrypt, encrypt, getServiceMainPort, createDirectories, ComposeFile, makeLabelForServices, getFreePublicPort, getDomain, errorHandler, generatePassword, isDev, stopTcpHttpProxy, supportedServiceTypesAndVersions, executeDockerCmd, listSettings, getExposedFreePort } from '../../../../lib/common';
|
||||||
import { day } from '../../../../lib/dayjs';
|
import { day } from '../../../../lib/dayjs';
|
||||||
import { checkContainer, dockerInstance, isContainerExited, removeContainer } from '../../../../lib/docker';
|
import { checkContainer, dockerInstance, isContainerExited, removeContainer } from '../../../../lib/docker';
|
||||||
import cuid from 'cuid';
|
import cuid from 'cuid';
|
||||||
@ -305,13 +305,13 @@ export async function getServiceLogs(request: FastifyRequest<GetServiceLogs>) {
|
|||||||
try {
|
try {
|
||||||
// const found = await checkContainer({ dockerId, container: id })
|
// const found = await checkContainer({ dockerId, container: id })
|
||||||
// if (found) {
|
// if (found) {
|
||||||
const { default: ansi } = await import('strip-ansi')
|
const { default: ansi } = await import('strip-ansi')
|
||||||
const { stdout, stderr } = await executeDockerCmd({ dockerId, command: `docker logs --since ${since} --tail 5000 --timestamps ${id}` })
|
const { stdout, stderr } = await executeDockerCmd({ dockerId, command: `docker logs --since ${since} --tail 5000 --timestamps ${id}` })
|
||||||
const stripLogsStdout = stdout.toString().split('\n').map((l) => ansi(l)).filter((a) => a);
|
const stripLogsStdout = stdout.toString().split('\n').map((l) => ansi(l)).filter((a) => a);
|
||||||
const stripLogsStderr = stderr.toString().split('\n').map((l) => ansi(l)).filter((a) => a);
|
const stripLogsStderr = stderr.toString().split('\n').map((l) => ansi(l)).filter((a) => a);
|
||||||
const logs = stripLogsStderr.concat(stripLogsStdout)
|
const logs = stripLogsStderr.concat(stripLogsStdout)
|
||||||
const sortedLogs = logs.sort((a, b) => (day(a.split(' ')[0]).isAfter(day(b.split(' ')[0])) ? 1 : -1))
|
const sortedLogs = logs.sort((a, b) => (day(a.split(' ')[0]).isAfter(day(b.split(' ')[0])) ? 1 : -1))
|
||||||
return { logs: sortedLogs }
|
return { logs: sortedLogs }
|
||||||
// }
|
// }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const { statusCode } = error;
|
const { statusCode } = error;
|
||||||
@ -373,15 +373,12 @@ export async function checkService(request: FastifyRequest<CheckService>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (exposePort) {
|
if (exposePort) {
|
||||||
const { default: getPort } = await import('get-port');
|
|
||||||
exposePort = Number(exposePort);
|
|
||||||
|
|
||||||
if (exposePort < 1024 || exposePort > 65535) {
|
if (exposePort < 1024 || exposePort > 65535) {
|
||||||
throw { status: 500, message: `Exposed Port needs to be between 1024 and 65535.` }
|
throw { status: 500, message: `Exposed Port needs to be between 1024 and 65535.` }
|
||||||
}
|
}
|
||||||
|
|
||||||
const publicPort = await getPort({ port: exposePort });
|
const availablePort = await getExposedFreePort(id, exposePort);
|
||||||
if (publicPort !== exposePort) {
|
if (availablePort.toString() !== exposePort.toString()) {
|
||||||
throw { status: 500, message: `Port ${exposePort} is already in use.` }
|
throw { status: 500, message: `Port ${exposePort} is already in use.` }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -983,7 +980,7 @@ async function startMinioService(request: FastifyRequest<ServiceStartStop>) {
|
|||||||
const network = destinationDockerId && destinationDocker.network;
|
const network = destinationDockerId && destinationDocker.network;
|
||||||
const port = getServiceMainPort('minio');
|
const port = getServiceMainPort('minio');
|
||||||
|
|
||||||
const publicPort = await getFreePort();
|
const publicPort = await getFreePublicPort();
|
||||||
|
|
||||||
const consolePort = 9001;
|
const consolePort = 9001;
|
||||||
const { workdir } = await createDirectories({ repository: type, buildId: id });
|
const { workdir } = await createDirectories({ repository: type, buildId: id });
|
||||||
@ -2679,7 +2676,7 @@ export async function activateWordpressFtp(request: FastifyRequest<ActivateWordp
|
|||||||
const { id } = request.params
|
const { id } = request.params
|
||||||
const { ftpEnabled } = request.body;
|
const { ftpEnabled } = request.body;
|
||||||
|
|
||||||
const publicPort = await getFreePort();
|
const publicPort = await getFreePublicPort();
|
||||||
let ftpUser = cuid();
|
let ftpUser = cuid();
|
||||||
let ftpPassword = generatePassword();
|
let ftpPassword = generatePassword();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user