Merge pull request #637 from coollabsio/next

v3.10.9
This commit is contained in:
Andras Bacsai 2022-09-28 09:29:31 +02:00 committed by GitHub
commit 2b8d59dca3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 314 additions and 199 deletions

View File

@ -211,7 +211,6 @@ import * as buildpacks from '../lib/buildPacks';
// //
} }
await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage); await copyBaseConfigurationFiles(buildPack, workdir, buildId, applicationId, baseImage);
if (forceRebuild) deployNeeded = true if (forceRebuild) deployNeeded = true
if (!imageFound || deployNeeded) { if (!imageFound || deployNeeded) {
// if (true) { // if (true) {

View File

@ -472,6 +472,7 @@ export const saveBuildLog = async ({
if (isDev) { if (isDev) {
console.debug(`[${applicationId}] ${addTimestamp}`); console.debug(`[${applicationId}] ${addTimestamp}`);
return
} }
try { try {
return await got.post(`${fluentBitUrl}/${applicationId}_buildlog_${buildId}.csv`, { return await got.post(`${fluentBitUrl}/${applicationId}_buildlog_${buildId}.csv`, {
@ -586,9 +587,9 @@ export async function buildImage({
} else { } else {
await saveBuildLog({ line: `Building image started.`, buildId, applicationId }); await saveBuildLog({ line: `Building image started.`, buildId, applicationId });
} }
if (!debug && isCache) { if (!debug) {
await saveBuildLog({ await saveBuildLog({
line: `Debug turned off. To see more details, allow it in the configuration.`, line: `Debug turned off. To see more details, allow it in the features tab.`,
buildId, buildId,
applicationId applicationId
}); });
@ -607,30 +608,6 @@ export async function buildImage({
} }
} }
export async function streamEvents({ stream, docker, buildId, applicationId, debug }) {
await new Promise((resolve, reject) => {
docker.engine.modem.followProgress(stream, onFinished, onProgress);
function onFinished(err, res) {
if (err) reject(err);
resolve(res);
}
async function onProgress(event) {
if (event.error) {
reject(event.error);
} else if (event.stream) {
if (event.stream !== '\n') {
if (debug)
await saveBuildLog({
line: `${event.stream.replace('\n', '')}`,
buildId,
applicationId
});
}
}
}
});
}
export function makeLabelForStandaloneApplication({ export function makeLabelForStandaloneApplication({
applicationId, applicationId,
fqdn, fqdn,
@ -721,6 +698,7 @@ export async function buildCacheImageWithNode(data, imageForBuild) {
if (installCommand) { if (installCommand) {
Dockerfile.push(`RUN ${installCommand}`); Dockerfile.push(`RUN ${installCommand}`);
} }
// Dockerfile.push(`ARG CACHEBUST=1`);
Dockerfile.push(`RUN ${buildCommand}`); Dockerfile.push(`RUN ${buildCommand}`);
await fs.writeFile(`${workdir}/Dockerfile-cache`, Dockerfile.join('\n')); await fs.writeFile(`${workdir}/Dockerfile-cache`, Dockerfile.join('\n'));
await buildImage({ ...data, isCache: true }); await buildImage({ ...data, isCache: true });

View File

@ -13,10 +13,10 @@ export default async function (data) {
pullmergeRequestId, pullmergeRequestId,
dockerFileLocation dockerFileLocation
} = data } = data
try {
const file = `${workdir}${baseDirectory}${dockerFileLocation}`; const file = `${workdir}${baseDirectory}${dockerFileLocation}`;
data.workdir = `${workdir}${baseDirectory}`; data.workdir = `${workdir}${baseDirectory}`;
const Dockerfile: Array<string> = (await fs.readFile(`${file}`, 'utf8')) const DockerfileRaw = await fs.readFile(`${file}`, 'utf8')
const Dockerfile: Array<string> = DockerfileRaw
.toString() .toString()
.trim() .trim()
.split('\n'); .split('\n');
@ -42,7 +42,4 @@ export default async function (data) {
await fs.writeFile(`${workdir}${dockerFileLocation}`, Dockerfile.join('\n')); await fs.writeFile(`${workdir}${dockerFileLocation}`, Dockerfile.join('\n'));
await buildImage(data); await buildImage(data);
} catch (error) {
throw error;
}
} }

View File

@ -21,7 +21,7 @@ import { scheduler } from './scheduler';
import { supportedServiceTypesAndVersions } from './services/supportedVersions'; import { supportedServiceTypesAndVersions } from './services/supportedVersions';
import { includeServices } from './services/common'; import { includeServices } from './services/common';
export const version = '3.10.8'; export const version = '3.10.9';
export const isDev = process.env.NODE_ENV === 'development'; export const isDev = process.env.NODE_ENV === 'development';
const algorithm = 'aes-256-ctr'; const algorithm = 'aes-256-ctr';
@ -1651,10 +1651,10 @@ export async function cleanupDockerStorage(dockerId, lowDiskSpace, force) {
} }
} catch (error) { } } catch (error) { }
if (lowDiskSpace || force) { if (lowDiskSpace || force) {
if (isDev) { // if (isDev) {
if (!force) console.log(`[DEV MODE] Low disk space: ${lowDiskSpace}`); // if (!force) console.log(`[DEV MODE] Low disk space: ${lowDiskSpace}`);
return; // return;
} // }
try { try {
await executeDockerCmd({ await executeDockerCmd({
dockerId, dockerId,

View File

@ -18,8 +18,8 @@
<div class="dropdown dropdown-bottom"> <div class="dropdown dropdown-bottom">
<slot> <slot>
<label for="new" tabindex="0" class="btn btn-square btn-sm bg-coollabs"> <label for="new" tabindex="0" class="btn btn-sm text-sm bg-coollabs hover:bg-coollabs-100">
<svg Create New Resource <svg
class="h-6 w-6" class="h-6 w-6"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
@ -35,11 +35,7 @@
> >
</slot> </slot>
<ul <ul id="new" tabindex="0" class="dropdown-content menu p-2 shadow bg-coolgray-300 rounded w-52">
id="new"
tabindex="0"
class="dropdown-content menu p-2 shadow bg-coolgray-300 rounded w-52"
>
<li> <li>
<button on:click={newApplication} class="no-underline hover:bg-applications rounded-none "> <button on:click={newApplication} class="no-underline hover:bg-applications rounded-none ">
<svg <svg

View File

@ -59,6 +59,7 @@
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from 'svelte';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import DeleteIcon from '$lib/components/DeleteIcon.svelte';
import { import {
appSession, appSession,
status, status,
@ -75,10 +76,25 @@
let statusInterval: any; let statusInterval: any;
let forceDelete = false; let forceDelete = false;
const { id } = $page.params;
const { id } = $page.params;
$isDeploymentEnabled = checkIfDeploymentEnabledApplications($appSession.isAdmin, application); $isDeploymentEnabled = checkIfDeploymentEnabledApplications($appSession.isAdmin, application);
async function deleteApplication(name: string, force: boolean) {
const sure = confirm($t('application.confirm_to_delete', { name }));
if (sure) {
try {
await del(`/applications/${id}`, { id, force });
return await goto('/');
} catch (error) {
if (error.message.startsWith(`Command failed: SSH_AUTH_SOCK=/tmp/coolify-ssh-agent.pid`)) {
forceDelete = true;
}
return errorNotification(error);
}
}
}
async function handleDeploySubmit(forceRebuild = false) { async function handleDeploySubmit(forceRebuild = false) {
if (!$isDeploymentEnabled) return; if (!$isDeploymentEnabled) return;
try { try {
@ -172,7 +188,7 @@
</script> </script>
<div class="mx-auto max-w-screen-2xl px-6 grid grid-cols-1 lg:grid-cols-2"> <div class="mx-auto max-w-screen-2xl px-6 grid grid-cols-1 lg:grid-cols-2">
<nav class="header flex flex-row order-2 lg:order-1 px-0 lg:px-4"> <nav class="header flex flex-row order-2 lg:order-1 px-0 lg:px-4 items-start">
<div class="title lg:pb-10"> <div class="title lg:pb-10">
{#if $page.url.pathname === `/applications/${id}/configuration/source`} {#if $page.url.pathname === `/applications/${id}/configuration/source`}
Select a Source Select a Source
@ -195,6 +211,32 @@
</div> </div>
{/if} {/if}
</div> </div>
{#if $page.url.pathname.startsWith(`/applications/${id}/configuration/`)}
<div class="px-2">
{#if forceDelete}
<button
on:click={() => deleteApplication(application.name, true)}
disabled={!$appSession.isAdmin}
class:bg-red-600={$appSession.isAdmin}
class:hover:bg-red-500={$appSession.isAdmin}
class="btn btn-sm btn-error text-sm"
>
Force Delete Application
</button>
{:else}
<button
on:click={() => deleteApplication(application.name, false)}
disabled={!$appSession.isAdmin}
class:bg-red-600={$appSession.isAdmin}
class:hover:bg-red-500={$appSession.isAdmin}
class="btn btn-sm btn-error text-sm"
>
Delete Application
</button>
{/if}
</div>
{/if}
</nav> </nav>
<div <div
class="pt-4 flex flex-row items-start justify-center lg:justify-end space-x-2 order-1 lg:order-2" class="pt-4 flex flex-row items-start justify-center lg:justify-end space-x-2 order-1 lg:order-2"
@ -320,8 +362,7 @@
</svg> </svg>
</button> </button>
<Tooltip triggeredBy="#forceredeploy">Force Redeploy (without cache)</Tooltip> <Tooltip triggeredBy="#forceredeploy">Force Redeploy (without cache)</Tooltip>
{:else} {:else if $isDeploymentEnabled}
{#if $isDeploymentEnabled}
<button <button
class="icons flex items-center font-bold" class="icons flex items-center font-bold"
disabled={!$isDeploymentEnabled} disabled={!$isDeploymentEnabled}
@ -343,7 +384,6 @@
Deploy Deploy
</button> </button>
{/if} {/if}
{/if}
{#if $location && $status.application.isRunning} {#if $location && $status.application.isRunning}
<a id="openApplication" href={$location} target="_blank" class="icons bg-transparent " <a id="openApplication" href={$location} target="_blank" class="icons bg-transparent "

View File

@ -266,7 +266,6 @@
await getBaseBuildImages(); await getBaseBuildImages();
await handleSubmit(); await handleSubmit();
} }
async function isDNSValid(domain: any, isWWW: any) { async function isDNSValid(domain: any, isWWW: any) {
try { try {
await get(`/applications/${id}/check?domain=${domain}`); await get(`/applications/${id}/check?domain=${domain}`);
@ -707,24 +706,6 @@
/> />
</div> </div>
{/if} {/if}
{#if application.buildPack === 'docker'}
<div class="grid grid-cols-2 items-center pt-4">
<label for="dockerFileLocation"
>Dockerfile Location <Explainer
explanation={"Should be absolute path, like <span class='text-settings font-bold'>/data/Dockerfile</span> or <span class='text-settings font-bold'>/Dockerfile.</span>"}
/></label
>
<input
class="w-full"
disabled={isDisabled}
readonly={!$appSession.isAdmin}
name="dockerFileLocation"
id="dockerFileLocation"
bind:value={application.dockerFileLocation}
placeholder="default: /Dockerfile"
/>
</div>
{/if}
{#if application.buildPack === 'deno'} {#if application.buildPack === 'deno'}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="denoMainFile">Main File</label> <label for="denoMainFile">Main File</label>
@ -776,6 +757,31 @@
/> />
</div> </div>
{/if} {/if}
{#if application.buildPack === 'docker'}
<div class="grid grid-cols-2 items-center pb-4">
<label for="dockerFileLocation"
class="mb-10"
>Dockerfile Location <Explainer
explanation={"Should be absolute path, like <span class='text-settings font-bold'>/data/Dockerfile</span> or <span class='text-settings font-bold'>/Dockerfile.</span>"}
/></label
>
<div class="form-control w-full">
<input
class="w-full input"
disabled={isDisabled}
readonly={!$appSession.isAdmin}
name="dockerFileLocation"
id="dockerFileLocation"
bind:value={application.dockerFileLocation}
placeholder="default: /Dockerfile"
/>
<label class="label">
<span class="label-text-alt text-xs">Path: {application.baseDirectory.replace(/^\/$/,'')}{application.dockerFileLocation}</span>
</label>
</div>
</div>
{/if}
{#if !notNodeDeployments.includes(application.buildPack)} {#if !notNodeDeployments.includes(application.buildPack)}
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<div class="flex-col"> <div class="flex-col">

View File

@ -7,6 +7,7 @@
import Tooltip from '$lib/components/Tooltip.svelte'; import Tooltip from '$lib/components/Tooltip.svelte';
import { day } from '$lib/dayjs'; import { day } from '$lib/dayjs';
import { selectedBuildId } from '$lib/store'; import { selectedBuildId } from '$lib/store';
import { dev } from '$app/env';
let logs: any = []; let logs: any = [];
let currentStatus: any; let currentStatus: any;
@ -104,7 +105,7 @@
}); });
</script> </script>
<div class="flex justify-start top-0 pb-2 space-x-2"> <div class="flex justify-start top-0 pb-2 space-x-2">
<button <button
on:click={followBuild} on:click={followBuild}
class="btn btn-sm bg-coollabs" class="btn btn-sm bg-coollabs"
@ -159,14 +160,14 @@
<button id="streaming" class="btn btn-sm bg-transparent border-none loading" /> <button id="streaming" class="btn btn-sm bg-transparent border-none loading" />
<Tooltip triggeredBy="#streaming">Streaming logs</Tooltip> <Tooltip triggeredBy="#streaming">Streaming logs</Tooltip>
{/if} {/if}
</div> </div>
{#if currentStatus === 'queued'} {#if currentStatus === 'queued'}
<div <div
class="font-mono w-full bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded mb-20 flex flex-col whitespace-nowrap scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1" class="font-mono w-full bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded mb-20 flex flex-col whitespace-nowrap scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1"
> >
{$t('application.build.queued_waiting_exec')} {$t('application.build.queued_waiting_exec')}
</div> </div>
{:else if logs.length > 0} {:else if logs.length > 0}
<div <div
bind:this={logsEl} bind:this={logsEl}
on:scroll={detect} on:scroll={detect}
@ -180,10 +181,10 @@
{/if} {/if}
{/each} {/each}
</div> </div>
{:else} {:else}
<div <div
class="font-mono w-full bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded mb-20 flex flex-col whitespace-nowrap scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1" class="font-mono w-full bg-coolgray-200 p-5 overflow-x-auto overflox-y-auto max-h-[80vh] rounded mb-20 flex flex-col whitespace-nowrap scrollbar-thumb-coollabs scrollbar-track-coolgray-200 scrollbar-w-1"
> >
No logs found yet. {dev ? 'In development, logs are shown in the console.' : 'No logs found yet.'}
</div> </div>
{/if} {/if}

View File

@ -309,6 +309,128 @@
{/if} {/if}
</nav> </nav>
<div class="container lg:mx-auto lg:p-0 px-8 pt-5"> <div class="container lg:mx-auto lg:p-0 px-8 pt-5">
<div class="space-x-2 lg:flex lg:justify-center text-center mb-4 ">
<button
class="btn btn-sm btn-ghost"
class:bg-applications={$search === '!app'}
class:hover:bg-coollabs={$search !== '!app'}
on:click={() => doSearch('!app')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mr-2 hidden lg:block "
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentcolor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<rect x="4" y="4" width="6" height="6" rx="1" />
<rect x="4" y="14" width="6" height="6" rx="1" />
<rect x="14" y="14" width="6" height="6" rx="1" />
<line x1="14" y1="7" x2="20" y2="7" />
<line x1="17" y1="4" x2="17" y2="10" />
</svg> Applications</button
>
<button
class="btn btn-sm btn-ghost"
class:bg-services={$search === '!service'}
class:hover:bg-coollabs={$search !== '!service'}
on:click={() => doSearch('!service')}
><svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mr-2 hidden lg:block"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M7 18a4.6 4.4 0 0 1 0 -9a5 4.5 0 0 1 11 2h1a3.5 3.5 0 0 1 0 7h-12" />
</svg> Services</button
>
<button
class="btn btn-sm btn-ghost "
class:bg-databases={$search === '!db'}
class:hover:bg-coollabs={$search !== '!db'}
on:click={() => doSearch('!db')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mr-2 hidden lg:block"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<ellipse cx="12" cy="6" rx="8" ry="3" />
<path d="M4 6v6a8 3 0 0 0 16 0v-6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />
</svg> Databases</button
>
<button
class="btn btn-sm btn-ghost"
class:bg-sources={$search === '!git'}
class:hover:bg-coollabs={$search !== '!git'}
on:click={() => doSearch('!git')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mr-2 hidden lg:block"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<circle cx="6" cy="6" r="2" />
<circle cx="18" cy="18" r="2" />
<path d="M11 6h5a2 2 0 0 1 2 2v8" />
<polyline points="14 9 11 6 14 3" />
<path d="M13 18h-5a2 2 0 0 1 -2 -2v-8" />
<polyline points="10 15 13 18 10 21" />
</svg> Git Sources</button
>
<button
class="btn btn-sm btn-ghost"
class:bg-destinations={$search === '!destination'}
class:hover:bg-coollabs={$search !== '!destination'}
on:click={() => doSearch('!destination')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-6 w-6 mr-2 hidden lg:block"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
d="M22 12.54c-1.804 -.345 -2.701 -1.08 -3.523 -2.94c-.487 .696 -1.102 1.568 -.92 2.4c.028 .238 -.32 1.002 -.557 1h-14c0 5.208 3.164 7 6.196 7c4.124 .022 7.828 -1.376 9.854 -5c1.146 -.101 2.296 -1.505 2.95 -2.46z"
/>
<path d="M5 10h3v3h-3z" />
<path d="M8 10h3v3h-3z" />
<path d="M11 10h3v3h-3z" />
<path d="M8 7h3v3h-3z" />
<path d="M11 7h3v3h-3z" />
<path d="M11 4h3v3h-3z" />
<path d="M4.571 18c1.5 0 2.047 -.074 2.958 -.78" />
<line x1="10" y1="16" x2="10" y2="16.01" />
</svg>Destinations</button
>
</div>
{#if applications.length !== 0 || destinations.length !== 0 || databases.length !== 0 || services.length !== 0 || gitSources.length !== 0 || destinations.length !== 0} {#if applications.length !== 0 || destinations.length !== 0 || databases.length !== 0 || services.length !== 0 || gitSources.length !== 0 || destinations.length !== 0}
<div class="form-control"> <div class="form-control">
<div class="input-group flex w-full"> <div class="input-group flex w-full">
@ -343,40 +465,16 @@
</div> </div>
<label for="search" class="label w-full mt-3"> <label for="search" class="label w-full mt-3">
<span class="label-text text-xs flex flex-wrap gap-2 items-center"> <span class="label-text text-xs flex flex-wrap gap-2 items-center">
<button
class:bg-coollabs={$search === '!notmine'}
class="badge badge-lg text-white text-xs rounded"
on:click={() => doSearch('!notmine')}>Other Teams</button
>
<button
class:bg-coollabs={$search === '!app'}
class="badge badge-lg text-white text-xs rounded"
on:click={() => doSearch('!app')}>Applications</button
>
<button <button
class:bg-coollabs={$search === '!bot'} class:bg-coollabs={$search === '!bot'}
class="badge badge-lg text-white text-xs rounded" class="badge badge-lg text-white text-xs rounded"
on:click={() => doSearch('!bot')}>Bots</button on:click={() => doSearch('!bot')}>Bots</button
> >
<button <button
class:bg-coollabs={$search === '!service'} class:bg-coollabs={$search === '!notmine'}
class="badge badge-lg text-white text-xs rounded" class="badge badge-lg text-white text-xs rounded"
on:click={() => doSearch('!service')}>Services</button on:click={() => doSearch('!notmine')}>Other Teams</button
>
<button
class:bg-coollabs={$search === '!db'}
class="badge badge-lg text-white text-xs rounded"
on:click={() => doSearch('!db')}>Databases</button
>
<button
class:bg-coollabs={$search === '!git'}
class="badge badge-lg text-white text-xs rounded"
on:click={() => doSearch('!git')}>Git Sources</button
>
<button
class:bg-coollabs={$search === '!destination'}
class="badge badge-lg text-white text-xs rounded"
on:click={() => doSearch('!destination')}>Destinations</button
> >
<button <button
class:bg-coollabs={$search === '!running'} class:bg-coollabs={$search === '!running'}
@ -408,7 +506,7 @@
{#if filtered.applications.length > 0 && applications.length > 0} {#if filtered.applications.length > 0 && applications.length > 0}
<div class="divider" /> <div class="divider" />
<div <div
class="grid grid-col gap-8 auto-cols-max grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 p-4" class="grid grid-col gap-2 lg:gap-8 auto-cols-max grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 p-4"
> >
{#if filtered.applications.length > 0} {#if filtered.applications.length > 0}
{#each filtered.applications as application} {#each filtered.applications as application}

View File

@ -1,7 +1,7 @@
{ {
"name": "coolify", "name": "coolify",
"description": "An open-source & self-hostable Heroku / Netlify alternative.", "description": "An open-source & self-hostable Heroku / Netlify alternative.",
"version": "3.10.8", "version": "3.10.9",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": "github:coollabsio/coolify", "repository": "github:coollabsio/coolify",
"scripts": { "scripts": {