feat: remote docker engine init

This commit is contained in:
Andras Bacsai
2022-07-18 14:02:53 +00:00
parent 0a8fd0516d
commit 537209d3fb
20 changed files with 809 additions and 429 deletions

View File

@@ -142,9 +142,6 @@
: $t('destination.force_restart_proxy')}</button
>
{/if}
<!-- <button type="button" class="bg-coollabs hover:bg-coollabs-100" on:click={scanApps}
>Scan for applications</button
> -->
</div>
<div class="grid grid-cols-2 items-center px-10 ">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
@@ -168,10 +165,6 @@
value={destination.engine}
/>
</div>
<!-- <div class="flex items-center">
<label for="remoteEngine">Remote Engine?</label>
<input name="remoteEngine" type="checkbox" bind:checked={payload.remoteEngine} />
</div> -->
<div class="grid grid-cols-2 items-center px-10">
<label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label>
<CopyPasswordField

View File

@@ -44,7 +44,7 @@
<button class="w-32" on:click={() => setPredefined('localDocker')}
>{$t('sources.local_docker')}</button
>
<!-- <button class="w-32" on:click={() => setPredefined('remoteDocker')}>Remote Docker</button> -->
<button class="w-32" on:click={() => setPredefined('remoteDocker')}>Remote Docker</button>
<!-- <button class="w-32" on:click={() => setPredefined('kubernetes')}>Kubernetes</button> -->
</div>
</div>

View File

@@ -11,13 +11,19 @@
let loading = false;
async function handleSubmit() {
if (loading) return;
try {
const { id } = await post('/new/destination/docker', {
loading = true;
await post(`/destinations/check`, { network: payload.network });
const { id } = await post(`/destinations/new`, {
...payload
});
return await goto(`/destinations/${id}`);
await goto(`/destinations/${id}`);
window.location.reload();
} catch (error) {
return errorNotification(error);
} finally {
loading = false;
}
}
</script>
@@ -64,20 +70,6 @@
<label for="port" class="text-base font-bold text-stone-100">{$t('forms.port')}</label>
<input required name="port" placeholder="{$t('forms.eg')}: 22" bind:value={payload.port} />
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="sshPrivateKey" class="text-base font-bold text-stone-100"
>{$t('forms.ssh_private_key')}</label
>
<textarea
rows="10"
class="resize-none"
required
name="sshPrivateKey"
placeholder="{$t('forms.eg')}: -----BEGIN...."
bind:value={payload.sshPrivateKey}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label>
<input

View File

@@ -1,7 +1,7 @@
<script lang="ts">
export let destination: any;
export let settings: any
export let state: any
export let settings: any;
export let state: any;
import { toast } from '@zerodevx/svelte-toast';
import { page, session } from '$app/stores';
@@ -10,50 +10,45 @@
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import { onMount } from 'svelte';
import { t } from '$lib/translations';
import { errorNotification, generateRemoteEngine } from '$lib/common';
import { appSession } from '$lib/store';
import { errorNotification, generateRemoteEngine } from '$lib/common';
import { appSession } from '$lib/store';
const { id } = $page.params;
let cannotDisable = settings.fqdn && destination.engine === '/var/run/docker.sock';
// let scannedApps = [];
let loading = false;
let restarting = false;
$: isDisabled = !$appSession.isAdmin;
async function handleSubmit() {
loading = true;
try {
return await post(`/destinations/${id}.json`, { ...destination });
} catch (error ) {
return await post(`/destinations/${id}`, { ...destination });
} catch (error) {
return errorNotification(error);
} finally {
loading = false;
}
}
// async function scanApps() {
// scannedApps = [];
// const data = await fetch(`/destinations/${id}/scan.json`);
// const { containers } = await data.json();
// scannedApps = containers;
// }
onMount(async () => {
if (state === false && destination.isCoolifyProxyUsed === true) {
destination.isCoolifyProxyUsed = !destination.isCoolifyProxyUsed;
try {
await post(`/destinations/${id}/settings.json`, {
await post(`/destinations/${id}/settings`, {
isCoolifyProxyUsed: destination.isCoolifyProxyUsed,
engine: destination.engine
});
await stopProxy();
} catch (error ) {
} catch (error) {
return errorNotification(error);
}
} else if (state === true && destination.isCoolifyProxyUsed === false) {
destination.isCoolifyProxyUsed = !destination.isCoolifyProxyUsed;
try {
await post(`/destinations/${id}/settings.json`, {
await post(`/destinations/${id}/settings`, {
isCoolifyProxyUsed: destination.isCoolifyProxyUsed,
engine: destination.engine
});
await startProxy();
} catch ( error ) {
} catch (error) {
return errorNotification(error);
}
}
@@ -73,7 +68,7 @@ import { appSession } from '$lib/store';
}
destination.isCoolifyProxyUsed = !destination.isCoolifyProxyUsed;
try {
await post(`/destinations/${id}/settings.json`, {
await post(`/destinations/${id}/settings`, {
isCoolifyProxyUsed: destination.isCoolifyProxyUsed,
engine: destination.engine
});
@@ -89,8 +84,7 @@ import { appSession } from '$lib/store';
}
async function stopProxy() {
try {
const engine = generateRemoteEngine(destination);
await post(`/destinations/${id}/stop.json`, { engine });
await post(`/destinations/${id}/stop`, { engine: destination.engine });
return toast.push($t('destination.coolify_proxy_stopped'));
} catch (error) {
return errorNotification(error);
@@ -98,8 +92,7 @@ import { appSession } from '$lib/store';
}
async function startProxy() {
try {
const engine = generateRemoteEngine(destination);
await post(`/destinations/${id}/start.json`, { engine });
await post(`/destinations/${id}/start`, { engine: destination.engine });
return toast.push($t('destination.coolify_proxy_started'));
} catch (error) {
return errorNotification(error);
@@ -111,7 +104,7 @@ import { appSession } from '$lib/store';
try {
restarting = true;
toast.push($t('destination.coolify_proxy_restarting'));
await post(`/destinations/${id}/restart.json`, {
await post(`/destinations/${id}/restart`, {
engine: destination.engine,
fqdn: settings.fqdn
});
@@ -119,9 +112,21 @@ import { appSession } from '$lib/store';
setTimeout(() => {
window.location.reload();
}, 5000);
} finally {
restarting = false;
}
}
}
async function verifyRemoteDocker() {
try {
loading = true;
return await post(`/destinations/${id}/verify`, {});
} catch (error) {
return errorNotification(error);
} finally {
loading = false;
}
}
</script>
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4">
@@ -136,6 +141,11 @@ import { appSession } from '$lib/store';
disabled={loading}
>{loading ? $t('forms.saving') : $t('forms.save')}
</button>
{#if !destination.remoteVerified}
<button on:click|preventDefault|stopPropagation={verifyRemoteDocker}
>Verify Remote Docker Engine</button
>
{/if}
<button
class={restarting ? '' : 'bg-red-600 hover:bg-red-500'}
disabled={restarting}
@@ -145,9 +155,6 @@ import { appSession } from '$lib/store';
: $t('destination.force_restart_proxy')}</button
>
{/if}
<!-- <button type="button" class="bg-coollabs hover:bg-coollabs-100" on:click={scanApps}
>Scan for applications</button
> -->
</div>
<div class="grid grid-cols-2 items-center px-10 ">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
@@ -159,22 +166,6 @@ import { appSession } from '$lib/store';
bind:value={destination.name}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="engine" class="text-base font-bold text-stone-100">{$t('forms.engine')}</label>
<CopyPasswordField
id="engine"
readonly
disabled
name="engine"
placeholder="{$t('forms.eg')}: /var/run/docker.sock"
value={destination.engine}
/>
</div>
<!-- <div class="flex items-center">
<label for="remoteEngine">Remote Engine?</label>
<input name="remoteEngine" type="checkbox" bind:checked={payload.remoteEngine} />
</div> -->
<div class="grid grid-cols-2 items-center px-10">
<label for="network" class="text-base font-bold text-stone-100">{$t('forms.network')}</label>
<CopyPasswordField
@@ -186,6 +177,49 @@ import { appSession } from '$lib/store';
value={destination.network}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="remoteIpAddress" class="text-base font-bold text-stone-100">IP Address</label>
<CopyPasswordField
id="remoteIpAddress"
readonly
disabled
name="remoteIpAddress"
value={destination.remoteIpAddress}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="remoteUser" class="text-base font-bold text-stone-100">User</label>
<CopyPasswordField
id="remoteUser"
readonly
disabled
name="remoteUser"
value={destination.remoteUser}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="remotePort" class="text-base font-bold text-stone-100">Port</label>
<CopyPasswordField
id="remotePort"
readonly
disabled
name="remotePort"
value={destination.remotePort}
/>
</div>
<div class="grid grid-cols-2 items-center px-10">
<label for="sshKey" class="text-base font-bold text-stone-100">SSH Key</label>
<a
href={!isDisabled ? `/destinations/${id}/configuration/sshkey?from=/destinations/${id}` : ''}
class="no-underline"
><input
value={destination.sshKey.name}
id="sshKey"
disabled
class="cursor-pointer hover:bg-coolgray-500"
/></a
>
</div>
<div class="grid grid-cols-2 items-center">
<Setting
disabled={cannotDisable}
@@ -200,27 +234,3 @@ import { appSession } from '$lib/store';
/>
</div>
</form>
<!-- <div class="flex justify-center">
{#if payload.isCoolifyProxyUsed}
{#if state}
<button on:click={stopProxy}>Stop proxy</button>
{:else}
<button on:click={startProxy}>Start proxy</button>
{/if}
{/if}
</div> -->
<!-- {#if scannedApps.length > 0}
<div class="flex justify-center px-6 pb-10">
<div class="flex space-x-2 h-8 items-center">
<div class="font-bold text-xl text-white">Found applications</div>
</div>
</div>
<div class="max-w-4xl mx-auto px-6">
<div class="flex space-x-2 justify-center">
{#each scannedApps as app}
<FoundApp {app} />
{/each}
</div>
</div>
{/if} -->

View File

@@ -1,6 +1,14 @@
<script context="module" lang="ts">
import type { Load } from '@sveltejs/kit';
export const load: Load = async ({ fetch, url, params }) => {
function checkConfiguration(destination: any): string | null {
let configurationPhase = null;
if (!destination?.remoteEngine) return configurationPhase;
if (!destination?.sshKey) {
configurationPhase = 'sshkey';
}
return configurationPhase;
}
export const load: Load = async ({ url, params }) => {
try {
const { id } = params;
const response = await get(`/destinations/${id}`);
@@ -11,6 +19,17 @@
redirect: '/destinations'
};
}
const configurationPhase = checkConfiguration(destination);
if (
configurationPhase &&
url.pathname !== `/destinations/${params.id}/configuration/${configurationPhase}`
) {
return {
status: 302,
redirect: `/destinations/${params.id}/configuration/${configurationPhase}`
};
}
return {
props: {
destination
@@ -22,6 +41,7 @@
}
};
} catch (error) {
console.log(error)
return handlerNotFoundLoad(error, url);
}
};

View File

@@ -0,0 +1,59 @@
<script context="module" lang="ts">
import type { Load } from '@sveltejs/kit';
export const load: Load = async ({ fetch, params, url, stuff }) => {
try {
const response = await get(`/settings`);
return {
props: {
...response
}
};
} catch (error) {
return {
status: 500,
error: new Error(`Could not load ${url}`)
};
}
};
</script>
<script lang="ts">
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { get, post } from '$lib/api';
import { errorNotification } from '$lib/common';
const { id } = $page.params;
const from = $page.url.searchParams.get('from');
export let sshKeys: any;
async function handleSubmit(sshKeyId: string) {
try {
await post(`/destinations/${id}/configuration/sshKey`, { id: sshKeyId });
return await goto(from || `/destinations/${id}`);
} catch (error) {
return errorNotification(error);
}
}
</script>
<div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">SSH Keys</div>
</div>
<div class="flex flex-col justify-center">
<div class="flex flex-col flex-wrap justify-center px-2 md:flex-row ">
{#each sshKeys as sshKey}
<div class="p-2 relative">
<form on:submit|preventDefault={() => handleSubmit(sshKey.id)}>
<button
type="submit"
class="disabled:opacity-95 bg-coolgray-200 disabled:text-white box-selection hover:bg-orange-700 group"
>
<div class="font-bold text-xl text-center truncate">{sshKey.name}</div>
</button>
</form>
</div>
{/each}
</div>
</div>

View File

@@ -73,6 +73,9 @@
<div class="truncate text-center">{destination.teams[0].name}</div>
{/if}
<div class="truncate text-center">{destination.network}</div>
{#if $appSession.teamId === '0' && destination.remoteVerified === false && destination.remoteEngine}
<div class="truncate text-center text-sm text-red-500">Not verified yet</div>
{/if}
</div>
</a>
{/each}