feat: Taiga

This commit is contained in:
Andras Bacsai
2022-09-02 14:11:36 +02:00
parent 8ad152e5fc
commit d098ea675f
15 changed files with 850 additions and 304 deletions

View File

@@ -1353,9 +1353,9 @@ export const getServiceMainPort = (service: string) => {
export function makeLabelForServices(type) {
return [
'coolify.managed=true',
`coolify.version = ${version}`,
`coolify.type = service`,
`coolify.service.type = ${type}`
`coolify.version=${version}`,
`coolify.type=service`,
`coolify.service.type=${type}`
];
}
export function errorHandler({ status = 500, message = 'Unknown error.' }: { status: number, message: string | any }) {
@@ -1475,14 +1475,25 @@ export async function cleanupDockerStorage(dockerId, lowDiskSpace, force) {
}
export function persistentVolumes(id, persistentStorage, config) {
let volumeSet = new Set();
if (Object.keys(config).length > 0) {
for (const [key, value] of Object.entries(config)) {
if (value.volumes) {
for (const volume of value.volumes) {
volumeSet.add(volume);
}
}
}
}
const volumesArray = Array.from(volumeSet);
const persistentVolume =
persistentStorage?.map((storage) => {
return `${id}${storage.path.replace(/\//gi, '-')}:${storage.path}`;
}) || [];
let volumes = [...persistentVolume]
if (config.volume) volumes = [config.volume, ...volumes]
if (volumesArray) volumes = [...volumesArray, ...volumes]
const composeVolumes = volumes.length > 0 && volumes.map((volume) => {
return {
[`${volume.split(':')[0]}`]: {
@@ -1491,16 +1502,11 @@ export function persistentVolumes(id, persistentStorage, config) {
};
}) || []
const volumeMounts = config.volume && Object.assign(
const volumeMounts = Object.assign(
{},
{
[config.volume.split(':')[0]]: {
name: config.volume.split(':')[0]
}
},
...composeVolumes
) || {}
return { volumes, volumeMounts }
return { volumeMounts }
}
export function defaultComposeConfiguration(network: string): any {
return {

View File

@@ -19,7 +19,8 @@ export const includeServices: any = {
appwrite: true,
glitchTip: true,
searxng: true,
weblate: true
weblate: true,
taiga: true
};
export async function configureServiceType({
id,
@@ -297,7 +298,7 @@ export async function configureServiceType({
}
}
});
}else if (type === 'weblate') {
} else if (type === 'weblate') {
const adminPassword = encrypt(generatePassword({}))
const postgresqlUser = cuid();
const postgresqlPassword = encrypt(generatePassword({}));
@@ -318,6 +319,37 @@ export async function configureServiceType({
}
}
});
} else if (type === 'taiga') {
const secretKey = encrypt(generatePassword({}))
const erlangSecret = encrypt(generatePassword({}))
const rabbitMQUser = cuid();
const djangoAdminUser = cuid();
const djangoAdminPassword = encrypt(generatePassword({}))
const rabbitMQPassword = encrypt(generatePassword({}))
const postgresqlUser = cuid();
const postgresqlPassword = encrypt(generatePassword({}));
const postgresqlDatabase = 'taiga';
await prisma.service.update({
where: { id },
data: {
type,
taiga: {
create: {
secretKey,
erlangSecret,
djangoAdminUser,
djangoAdminPassword,
rabbitMQUser,
rabbitMQPassword,
postgresqlHost: `${id}-postgresql`,
postgresqlPort: 5432,
postgresqlUser,
postgresqlPassword,
postgresqlDatabase,
}
}
}
});
} else {
await prisma.service.update({
where: { id },
@@ -345,6 +377,7 @@ export async function removeService({ id }: { id: string }): Promise<void> {
await prisma.appwrite.deleteMany({ where: { serviceId: id } });
await prisma.searxng.deleteMany({ where: { serviceId: id } });
await prisma.weblate.deleteMany({ where: { serviceId: id } });
await prisma.taiga.deleteMany({ where: { serviceId: id } });
await prisma.service.delete({ where: { id } });
}

File diff suppressed because it is too large Load Diff

View File

@@ -777,6 +777,86 @@ export const weblate = [{
isBoolean: false,
isEncrypted: true
},
{
name: 'postgresqlDatabase',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: false
}]
export const taiga = [{
name: 'secretKey',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: true
},
{
name: 'djangoAdminUser',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: false
},
{
name: 'djangoAdminPassword',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: true
},
{
name: 'rabbitMQUser',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: false
},
{
name: 'rabbitMQPassword',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: true
},
{
name: 'postgresqlHost',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: false
},
{
name: 'postgresqlPort',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: false
},
{
name: 'postgresqlUser',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: false
},
{
name: 'postgresqlPassword',
isEditable: false,
isLowerCase: false,
isNumber: false,
isBoolean: false,
isEncrypted: true
},
{
name: 'postgresqlDatabase',
isEditable: false,

View File

@@ -194,11 +194,22 @@ export const supportedServiceTypesAndVersions = [
name: 'weblate',
fancyName: 'Weblate',
baseImage: 'weblate/weblate',
images: ['postgres:14-alpine','redis:6-alpine'],
images: ['postgres:14-alpine', 'redis:6-alpine'],
versions: ['latest'],
recommendedVersion: 'latest',
ports: {
main: 8080
}
},
{
name: 'taiga',
fancyName: 'Taiga',
baseImage: 'taigaio/taiga-front',
images: ['postgres:12.3', 'rabbitmq:3.8-management-alpine', 'taigaio/taiga-back', 'taigaio/taiga-events', 'taigaio/taiga-protected'],
versions: ['latest'],
recommendedVersion: 'latest',
ports: {
main: 80
}
},
];

View File

@@ -1,15 +1,13 @@
import type { FastifyReply, FastifyRequest } from 'fastify';
import fs from 'fs/promises';
import yaml from 'js-yaml';
import bcrypt from 'bcryptjs';
import { prisma, uniqueName, asyncExecShell, getServiceImage, getServiceFromDB, getContainerUsage, isDomainConfigured, saveUpdateableFields, fixType, decrypt, encrypt, getServiceMainPort, createDirectories, ComposeFile, makeLabelForServices, getFreePublicPort, getDomain, errorHandler, generatePassword, isDev, stopTcpHttpProxy, executeDockerCmd, checkDomainsIsValidInDNS, persistentVolumes, asyncSleep, isARM, defaultComposeConfiguration, checkExposedPort } from '../../../../lib/common';
import { prisma, uniqueName, asyncExecShell, getServiceFromDB, getContainerUsage, isDomainConfigured, saveUpdateableFields, fixType, decrypt, encrypt, ComposeFile, getFreePublicPort, getDomain, errorHandler, generatePassword, isDev, stopTcpHttpProxy, executeDockerCmd, checkDomainsIsValidInDNS, checkExposedPort } from '../../../../lib/common';
import { day } from '../../../../lib/dayjs';
import { checkContainer, isContainerExited, removeContainer } from '../../../../lib/docker';
import { checkContainer, isContainerExited } from '../../../../lib/docker';
import cuid from 'cuid';
import type { OnlyId } from '../../../../types';
import type { ActivateWordpressFtp, CheckService, CheckServiceDomain, DeleteServiceSecret, DeleteServiceStorage, GetServiceLogs, SaveService, SaveServiceDestination, SaveServiceSecret, SaveServiceSettings, SaveServiceStorage, SaveServiceType, SaveServiceVersion, ServiceStartStop, SetGlitchTipSettings, SetWordpressSettings } from './types';
import { defaultServiceConfigurations } from '../../../../lib/services';
import { supportedServiceTypesAndVersions } from '../../../../lib/services/supportedVersions';
import { configureServiceType, removeService } from '../../../../lib/services/common';

View File

@@ -3,6 +3,7 @@ import { errorHandler, getDomain, isDev, prisma, executeDockerCmd } from "../../
import { supportedServiceTypesAndVersions } from "../../../lib/services/supportedVersions";
import { includeServices } from "../../../lib/services/common";
import { TraefikOtherConfiguration } from "./types";
import { OnlyId } from "../../../types";
function configureMiddleware(
{ id, container, port, domain, nakedDomain, isHttps, isWWW, isDualCerts, scriptName, type },
@@ -530,7 +531,7 @@ export async function traefikOtherConfiguration(request: FastifyRequest<TraefikO
}
}
export async function remoteTraefikConfiguration(request: FastifyRequest) {
export async function remoteTraefikConfiguration(request: FastifyRequest<OnlyId>) {
const { id } = request.params
try {
const traefik = {