diff --git a/apps/api/src/routes/api/v1/handlers.ts b/apps/api/src/routes/api/v1/handlers.ts index f05b8acb9..e7f75c610 100644 --- a/apps/api/src/routes/api/v1/handlers.ts +++ b/apps/api/src/routes/api/v1/handlers.ts @@ -2,6 +2,8 @@ import axios from "axios"; import { compareVersions } from "compare-versions"; import cuid from "cuid"; import bcrypt from "bcryptjs"; +import fs from 'fs/promises'; +import yaml from 'js-yaml'; import { asyncExecShell, asyncSleep, @@ -36,6 +38,30 @@ export async function cleanupManually(request: FastifyRequest) { return errorHandler({ status, message }); } } +export async function refreshTemplates(request: FastifyRequest) { + try { + const { default: got } = await import('got') + let templates = {} + try { + const response = await got.get('https://get.coollabs.io/coolify/service-templates.yaml').text() + templates = yaml.load(response) + } catch (error) { + throw { + status: 500, + message: 'Could not fetch templates from get.coollabs.io' + }; + } + + if (isDev) { + await fs.writeFile('./template.json', JSON.stringify(templates, null, 2)) + } else { + await fs.writeFile('/app/template.json', JSON.stringify(templates, null, 2)) + } + return {}; + } catch ({ status, message }) { + return errorHandler({ status, message }); + } +} export async function checkUpdate(request: FastifyRequest) { try { const isStaging = diff --git a/apps/api/src/routes/api/v1/index.ts b/apps/api/src/routes/api/v1/index.ts index 1f5ab0696..dca169097 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, resetQueue, getCurrentUser, cleanupManually, restartCoolify } from './handlers'; +import { checkUpdate, login, showDashboard, update, resetQueue, getCurrentUser, cleanupManually, restartCoolify, refreshTemplates } from './handlers'; import { GetCurrentUser } from './types'; import pump from 'pump' import fs from 'fs' @@ -55,6 +55,10 @@ const root: FastifyPluginAsync = async (fastify): Promise => { fastify.post('/internal/cleanup', { onRequest: [fastify.authenticate] }, async (request) => await cleanupManually(request)); + + fastify.post('/internal/refreshTemplates', { + onRequest: [fastify.authenticate] + }, async (request) => await refreshTemplates(request)); }; export default root; diff --git a/apps/api/src/routes/api/v1/services/handlers.ts b/apps/api/src/routes/api/v1/services/handlers.ts index 9eff0c89e..a404a71cd 100644 --- a/apps/api/src/routes/api/v1/services/handlers.ts +++ b/apps/api/src/routes/api/v1/services/handlers.ts @@ -153,10 +153,10 @@ export async function parseAndFindServiceTemplates(service: any, workdir?: strin if (proxyValue.domain) { const variable = foundTemplate.variables.find(v => v.id === proxyValue.domain) if (variable) { - const { name, label, description, defaultValue, extras } = variable + const { id, name, label, description, defaultValue, extras } = variable const found = await prisma.serviceSetting.findFirst({ where: { variableName: proxyValue.domain } }) parsedTemplate[realKey].fqdns.push( - { name, value: found.value || '', label, description, defaultValue, extras } + { id, name, value: found?.value || '', label, description, defaultValue, extras } ) } @@ -485,27 +485,29 @@ export async function saveService(request: FastifyRequest, reply: F if (fqdn) fqdn = fqdn.toLowerCase(); if (exposePort) exposePort = Number(exposePort); type = fixType(type) - // const update = saveUpdateableFields(type, request.body[type]) + const data = { fqdn, name, exposePort, } - // if (Object.keys(update).length > 0) { - // data[type] = { update: update } - // } + const templates = await getTemplates() + const service = await prisma.service.findUnique({ where: { id } }) + const foundTemplate = templates.find(t => t.name.toLowerCase() === service.type.toLowerCase()) for (const setting of serviceSetting) { - const { id: settingId, name, value, changed = false, isNew = false, variableName } = setting + let { id: settingId, name, value, changed = false, isNew = false, variableName } = setting if (changed) { await prisma.serviceSetting.update({ where: { id: settingId }, data: { value } }) } if (isNew) { + if (!variableName) { + variableName = foundTemplate.variables.find(v => v.name === name).id + } await prisma.serviceSetting.create({ data: { name, value, variableName, service: { connect: { id } } } }) } } await prisma.service.update({ where: { id }, data - }); return reply.code(201).send() } catch ({ status, message }) { diff --git a/apps/ui/src/routes/services/[id]/__layout.svelte b/apps/ui/src/routes/services/[id]/__layout.svelte index 5dd27f648..337b56d60 100644 --- a/apps/ui/src/routes/services/[id]/__layout.svelte +++ b/apps/ui/src/routes/services/[id]/__layout.svelte @@ -65,7 +65,8 @@ status, location, setLocation, - checkIfDeploymentEnabledServices + checkIfDeploymentEnabledServices, + addToast } from '$lib/store'; import { onDestroy, onMount } from 'svelte'; import { goto } from '$app/navigation'; @@ -76,6 +77,9 @@ $isDeploymentEnabled = checkIfDeploymentEnabledServices($appSession.isAdmin, service); let statusInterval: any; + let loading = { + refreshTemplates: false + }; async function deleteService() { const sure = confirm($t('application.confirm_to_delete', { name: service.name })); @@ -97,6 +101,20 @@ await stopService(); await startService(); } + async function refreshTemplate() { + try { + loading.refreshTemplates = true; + await post(`/internal/refreshTemplates`, {}); + addToast({ + message: 'Services refreshed.', + type: 'success' + }); + } catch (error) { + return errorNotification(error); + } finally { + loading.refreshTemplates = false; + } + } async function stopService() { const sure = confirm($t('database.confirm_stop', { name: service.name })); if (sure) { @@ -187,7 +205,7 @@
-