211 lines
5.7 KiB
TypeScript
211 lines
5.7 KiB
TypeScript
import { dev } from '$app/env';
|
|
import { sentry } from '$lib/common';
|
|
import {
|
|
supportedDatabaseTypesAndVersions,
|
|
supportedServiceTypesAndVersions
|
|
} from '$lib/components/common';
|
|
import * as Prisma from '@prisma/client';
|
|
import { default as ProdPrisma } from '@prisma/client';
|
|
import type { PrismaClientOptions } from '@prisma/client/runtime';
|
|
import generator from 'generate-password';
|
|
import forge from 'node-forge';
|
|
|
|
export function generatePassword(length = 24) {
|
|
return generator.generate({
|
|
length,
|
|
numbers: true,
|
|
strict: true
|
|
});
|
|
}
|
|
|
|
let { PrismaClient } = Prisma;
|
|
let P = Prisma.Prisma;
|
|
if (!dev) {
|
|
PrismaClient = ProdPrisma.PrismaClient;
|
|
P = ProdPrisma.Prisma;
|
|
}
|
|
|
|
export const prisma = new PrismaClient({
|
|
errorFormat: 'pretty',
|
|
rejectOnNotFound: false
|
|
});
|
|
|
|
export function ErrorHandler(e) {
|
|
if (e! instanceof Error) {
|
|
e = new Error(e.toString());
|
|
}
|
|
let truncatedError = e;
|
|
if (e.stdout) {
|
|
truncatedError = e.stdout;
|
|
}
|
|
if (e.message?.includes('docker run')) {
|
|
let truncatedArray = [];
|
|
truncatedArray = truncatedError.message.split('-').filter((line) => {
|
|
if (!line.startsWith('e ')) {
|
|
return line;
|
|
}
|
|
});
|
|
truncatedError.message = truncatedArray.join('-');
|
|
}
|
|
if (e.message?.includes('git clone')) {
|
|
truncatedError.message = 'git clone failed';
|
|
}
|
|
if (!e.message?.includes('Coolify Proxy is not running')) {
|
|
sentry.captureException(truncatedError);
|
|
}
|
|
const payload = {
|
|
status: truncatedError.status || 500,
|
|
body: {
|
|
message: 'Ooops, something is not okay, are you okay?',
|
|
error: truncatedError.error || truncatedError.message
|
|
}
|
|
};
|
|
if (truncatedError?.name === 'NotFoundError') {
|
|
payload.status = 404;
|
|
}
|
|
if (truncatedError instanceof P.PrismaClientKnownRequestError) {
|
|
if (truncatedError?.code === 'P2002') {
|
|
payload.body.message = 'Already exists. Choose another name.';
|
|
}
|
|
}
|
|
// console.error(e)
|
|
return payload;
|
|
}
|
|
export async function generateSshKeyPair(): Promise<{ publicKey: string; privateKey: string }> {
|
|
return await new Promise(async (resolve, reject) => {
|
|
forge.pki.rsa.generateKeyPair({ bits: 4096, workers: -1 }, function (err, keys) {
|
|
if (keys) {
|
|
resolve({
|
|
publicKey: forge.ssh.publicKeyToOpenSSH(keys.publicKey),
|
|
privateKey: forge.ssh.privateKeyToOpenSSH(keys.privateKey)
|
|
});
|
|
} else {
|
|
reject(keys);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
export function getVersions(type) {
|
|
const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type);
|
|
if (found) {
|
|
return found.versions;
|
|
}
|
|
return [];
|
|
}
|
|
export function getDatabaseImage(type) {
|
|
const found = supportedDatabaseTypesAndVersions.find((t) => t.name === type);
|
|
if (found) {
|
|
return found.baseImage;
|
|
}
|
|
return '';
|
|
}
|
|
export function getServiceImage(type) {
|
|
const found = supportedServiceTypesAndVersions.find((t) => t.name === type);
|
|
if (found) {
|
|
return found.baseImage;
|
|
}
|
|
return '';
|
|
}
|
|
export function getServiceImages(type) {
|
|
const found = supportedServiceTypesAndVersions.find((t) => t.name === type);
|
|
if (found) {
|
|
return found.images;
|
|
}
|
|
return [];
|
|
}
|
|
export function generateDatabaseConfiguration(database) {
|
|
const {
|
|
id,
|
|
dbUser,
|
|
dbUserPassword,
|
|
rootUser,
|
|
rootUserPassword,
|
|
defaultDatabase,
|
|
version,
|
|
type,
|
|
settings: { appendOnly }
|
|
} = database;
|
|
const baseImage = getDatabaseImage(type);
|
|
if (type === 'mysql') {
|
|
return {
|
|
// url: `mysql://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 3306}/${defaultDatabase}`,
|
|
privatePort: 3306,
|
|
environmentVariables: {
|
|
MYSQL_USER: dbUser,
|
|
MYSQL_PASSWORD: dbUserPassword,
|
|
MYSQL_ROOT_PASSWORD: rootUserPassword,
|
|
MYSQL_ROOT_USER: rootUser,
|
|
MYSQL_DATABASE: defaultDatabase
|
|
},
|
|
image: `${baseImage}:${version}`,
|
|
volume: `${id}-${type}-data:/bitnami/mysql/data`,
|
|
ulimits: {}
|
|
};
|
|
} else if (type === 'mongodb') {
|
|
return {
|
|
// url: `mongodb://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 27017}/${defaultDatabase}`,
|
|
privatePort: 27017,
|
|
environmentVariables: {
|
|
MONGODB_ROOT_USER: rootUser,
|
|
MONGODB_ROOT_PASSWORD: rootUserPassword
|
|
},
|
|
image: `${baseImage}:${version}`,
|
|
volume: `${id}-${type}-data:/bitnami/mongodb`,
|
|
ulimits: {}
|
|
};
|
|
} else if (type === 'postgresql') {
|
|
return {
|
|
// url: `psql://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 5432}/${defaultDatabase}`,
|
|
privatePort: 5432,
|
|
environmentVariables: {
|
|
POSTGRESQL_POSTGRES_PASSWORD: rootUserPassword,
|
|
POSTGRESQL_PASSWORD: dbUserPassword,
|
|
POSTGRESQL_USERNAME: dbUser,
|
|
POSTGRESQL_DATABASE: defaultDatabase
|
|
},
|
|
image: `${baseImage}:${version}`,
|
|
volume: `${id}-${type}-data:/bitnami/postgresql`,
|
|
ulimits: {}
|
|
};
|
|
} else if (type === 'redis') {
|
|
return {
|
|
// url: `redis://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 6379}/${defaultDatabase}`,
|
|
privatePort: 6379,
|
|
environmentVariables: {
|
|
REDIS_PASSWORD: dbUserPassword,
|
|
REDIS_AOF_ENABLED: appendOnly ? 'yes' : 'no'
|
|
},
|
|
image: `${baseImage}:${version}`,
|
|
volume: `${id}-${type}-data:/bitnami/redis/data`,
|
|
ulimits: {}
|
|
};
|
|
} else if (type === 'couchdb') {
|
|
return {
|
|
// url: `couchdb://${dbUser}:${dbUserPassword}@${id}:${isPublic ? port : 5984}/${defaultDatabase}`,
|
|
privatePort: 5984,
|
|
environmentVariables: {
|
|
COUCHDB_PASSWORD: dbUserPassword,
|
|
COUCHDB_USER: dbUser
|
|
},
|
|
image: `${baseImage}:${version}`,
|
|
volume: `${id}-${type}-data:/bitnami/couchdb`,
|
|
ulimits: {}
|
|
};
|
|
}
|
|
// } else if (type === 'clickhouse') {
|
|
// return {
|
|
// url: `clickhouse://${dbUser}:${dbUserPassword}@${id}:${port}/${defaultDatabase}`,
|
|
// privatePort: 9000,
|
|
// image: `bitnami/clickhouse-server:${version}`,
|
|
// volume: `${id}-${type}-data:/var/lib/clickhouse`,
|
|
// ulimits: {
|
|
// nofile: {
|
|
// soft: 262144,
|
|
// hard: 262144
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
}
|