feat: specific git commit deployment
feat: revert to specific image fix: no system wide docker registries
This commit is contained in:
@@ -268,7 +268,7 @@
|
||||
<a
|
||||
id="settings"
|
||||
sveltekit:prefetch
|
||||
href={$appSession.teamId === '0' ? '/settings/coolify' : '/settings/ssh'}
|
||||
href={$appSession.teamId === '0' ? '/settings/coolify' : '/settings/docker'}
|
||||
class="icons hover:text-settings"
|
||||
class:text-settings={$page.url.pathname.startsWith('/settings')}
|
||||
class:bg-coolgray-500={$page.url.pathname.startsWith('/settings')}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<a
|
||||
id="git"
|
||||
href="{application.gitSource.htmlUrl}/{application.repository}/tree/{application.branch}"
|
||||
target="_blank"
|
||||
target="_blank noreferrer"
|
||||
class="no-underline"
|
||||
>
|
||||
{#if application.gitSource?.type === 'gitlab'}
|
||||
@@ -165,7 +165,9 @@
|
||||
class:bg-coollabs={$page.url.pathname === `/applications/${$page.params.id}/logs`}
|
||||
>
|
||||
<a
|
||||
href={$status.application.overallStatus !== 'stopped' ? `/applications/${$page.params.id}/logs` : ''}
|
||||
href={$status.application.overallStatus !== 'stopped'
|
||||
? `/applications/${$page.params.id}/logs`
|
||||
: ''}
|
||||
class="no-underline w-full"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -216,12 +218,38 @@
|
||||
<li class="menu-title">
|
||||
<span>Advanced</span>
|
||||
</li>
|
||||
<li
|
||||
class="rounded"
|
||||
class:bg-coollabs={$page.url.pathname === `/applications/${$page.params.id}/revert`}
|
||||
>
|
||||
<a href={`/applications/${$page.params.id}/revert`} class="no-underline w-full">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
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="M20 5v14l-12 -7z" />
|
||||
<line x1="4" y1="5" x2="4" y2="19" />
|
||||
</svg>
|
||||
Revert</a
|
||||
>
|
||||
</li>
|
||||
<li
|
||||
class="rounded"
|
||||
class:text-stone-600={$status.application.overallStatus !== 'healthy'}
|
||||
class:bg-coollabs={$page.url.pathname === `/applications/${$page.params.id}/usage`}
|
||||
>
|
||||
<a href={$status.application.overallStatus === 'healthy' ? `/applications/${$page.params.id}/usage` : ''} class="no-underline w-full"
|
||||
<a
|
||||
href={$status.application.overallStatus === 'healthy'
|
||||
? `/applications/${$page.params.id}/usage`
|
||||
: ''}
|
||||
class="no-underline w-full"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
|
||||
@@ -96,6 +96,18 @@
|
||||
|
||||
async function handleDeploySubmit(forceRebuild = false) {
|
||||
if (!$isDeploymentEnabled) return;
|
||||
if (application.gitCommitHash && !application.settings.isPublicRepository) {
|
||||
const sure = await confirm(
|
||||
`Are you sure you want to deploy a specific commit (${application.gitCommitHash})? This will disable the "Automatic Deployment" feature to prevent accidental overwrites of incoming commits.`
|
||||
);
|
||||
if (!sure) {
|
||||
return;
|
||||
} else {
|
||||
await post(`/applications/${id}/settings`, {
|
||||
autodeploy: false
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!statusInterval) {
|
||||
statusInterval = setInterval(async () => {
|
||||
await getStatus();
|
||||
|
||||
@@ -46,73 +46,48 @@
|
||||
|
||||
<div class="flex flex-col justify-center w-full">
|
||||
<div class="flex flex-col flex-wrap justify-center px-2 md:flex-row mx-auto gap-4">
|
||||
{#each registries.public as registry}
|
||||
<button
|
||||
on:click={() => handleSubmit(registry.id)}
|
||||
class="box-selection hover:bg-primary relative"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="absolute top-0 left-0 -m-4 h-12 w-12 text-sky-500"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
{#if registries.length > 0}
|
||||
{#each registries as registry}
|
||||
<button
|
||||
on:click={() => handleSubmit(registry.id)}
|
||||
class="box-selection hover:bg-primary relative"
|
||||
>
|
||||
<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>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="absolute top-0 left-0 -m-4 h-12 w-12 text-sky-500"
|
||||
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>
|
||||
|
||||
<div class="font-bold text-xl text-center truncate">{registry.name}</div>
|
||||
<div class="text-center truncate">{registry.url}</div>
|
||||
<div>public</div>
|
||||
</button>
|
||||
{/each}
|
||||
{#each registries.private as registry}
|
||||
<button
|
||||
on:click={() => handleSubmit(registry.id)}
|
||||
class="box-selection hover:bg-primary relative"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="absolute top-0 left-0 -m-4 h-12 w-12 text-sky-500"
|
||||
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>
|
||||
|
||||
<div class="font-bold text-xl text-center truncate">{registry.name}</div>
|
||||
<div class="text-center truncate">{registry.url}</div>
|
||||
<div>private</div>
|
||||
</button>
|
||||
{/each}
|
||||
<div class="font-bold text-xl text-center truncate">{registry.name}</div>
|
||||
<div class="text-center truncate">{registry.url}</div>
|
||||
</button>
|
||||
{/each}
|
||||
{:else}
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<div class="text-center text-xl font-bold pb-4">No registries found.</div>
|
||||
<div class="flex gap-2">
|
||||
<a class="btn btn-sm" href={from || `/applications/${id}`}>Go back</a>
|
||||
<a class="btn btn-sm btn-primary" href={`/settings/docker`}>Add a Docker Registry</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -515,40 +515,37 @@
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
{#if application.settings.isPublicRepository}
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="repository">Git commit</label>
|
||||
<div class="flex gap-2">
|
||||
<input
|
||||
class="w-full"
|
||||
disabled={isDisabled}
|
||||
placeholder="default: latest commit"
|
||||
bind:value={application.gitCommitHash}
|
||||
/>
|
||||
<a
|
||||
href="{application.gitSource
|
||||
.htmlUrl}/{application.repository}/commits/{application.branch}"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
class="btn btn-primary text-xs"
|
||||
>Commits<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="3"
|
||||
stroke="currentColor"
|
||||
class="w-3 h-3 text-white ml-2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M4.5 19.5l15-15m0 0H8.25m11.25 0v11.25"
|
||||
/>
|
||||
</svg></a
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="repository">Git commit</label>
|
||||
<div class="flex gap-2">
|
||||
<input
|
||||
class="w-full"
|
||||
disabled={isDisabled}
|
||||
placeholder="default: latest commit"
|
||||
bind:value={application.gitCommitHash}
|
||||
/>
|
||||
<a
|
||||
href="{application.gitSource
|
||||
.htmlUrl}/{application.repository}/commits/{application.branch}"
|
||||
target="_blank noreferrer"
|
||||
class="btn btn-primary text-xs"
|
||||
>Commits<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="3"
|
||||
stroke="currentColor"
|
||||
class="w-3 h-3 text-white ml-2"
|
||||
>
|
||||
</div>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M4.5 19.5l15-15m0 0H8.25m11.25 0v11.25"
|
||||
/>
|
||||
</svg></a
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="grid grid-cols-2 items-center">
|
||||
<label for="repository">{$t('application.git_repository')}</label>
|
||||
{#if isDisabled || application.settings.isPublicRepository}
|
||||
@@ -575,7 +572,7 @@
|
||||
<input
|
||||
class="capitalize w-full"
|
||||
disabled={isDisabled}
|
||||
value={application.dockerRegistry.name}
|
||||
value={application.dockerRegistry?.name || 'DockerHub (unauthenticated)'}
|
||||
/>
|
||||
{:else}
|
||||
<a
|
||||
@@ -583,7 +580,7 @@
|
||||
class="no-underline"
|
||||
>
|
||||
<input
|
||||
value={application.dockerRegistry.name}
|
||||
value={application.dockerRegistry?.name || 'DockerHub (unauthenticated)'}
|
||||
id="registry"
|
||||
class="cursor-pointer hover:bg-coolgray-500 capitalize w-full"
|
||||
/></a
|
||||
|
||||
119
apps/ui/src/routes/applications/[id]/revert.svelte
Normal file
119
apps/ui/src/routes/applications/[id]/revert.svelte
Normal file
@@ -0,0 +1,119 @@
|
||||
<script context="module" lang="ts">
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
export const load: Load = async ({ fetch, params, stuff, url }) => {
|
||||
try {
|
||||
const response = await get(`/applications/${params.id}/images`);
|
||||
return {
|
||||
props: {
|
||||
application: stuff.application,
|
||||
...response
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
status: 500,
|
||||
error: new Error(`Could not load ${url}`)
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let application: any;
|
||||
export let imagesAvailables: any;
|
||||
export let runningImage: any;
|
||||
import { page } from '$app/stores';
|
||||
import { get, post } from '$lib/api';
|
||||
import { status, addToast } from '$lib/store';
|
||||
import { errorNotification } from '$lib/common';
|
||||
|
||||
const { id } = $page.params;
|
||||
|
||||
async function revertApplication(image: any) {
|
||||
const sure = confirm(`Are you sure you want to revert to ${image.tag} ?`);
|
||||
if (sure) {
|
||||
try {
|
||||
$status.application.initialLoading = true;
|
||||
$status.application.loading = true;
|
||||
const imageId = `${image.repository}:${image.tag}`;
|
||||
await post(`/applications/${id}/restart`, { imageId });
|
||||
addToast({
|
||||
type: 'success',
|
||||
message: 'Revert successful.'
|
||||
});
|
||||
} catch (error) {
|
||||
return errorNotification(error);
|
||||
} finally {
|
||||
$status.application.initialLoading = false;
|
||||
$status.application.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full">
|
||||
<div class="mx-auto w-full">
|
||||
<div class="flex flex-row border-b border-coolgray-500 mb-6 space-x-2">
|
||||
<div class="title font-bold pb-3">Revert Application</div>
|
||||
</div>
|
||||
<div>
|
||||
You can revert application to a previously built image. Currently only locally stored images
|
||||
supported.
|
||||
</div>
|
||||
<br />
|
||||
<div class="pb-4">
|
||||
If you do not want the next commit to overwrite the reverted application, temporary disable <span
|
||||
class="text-yellow-400 font-bold">Automatic Deployment</span
|
||||
>
|
||||
feature <a href={`/applications/${id}/features`}>here</a>.
|
||||
</div>
|
||||
<div
|
||||
class="px-4 lg:pb-10 pb-6 flex flex-wrap items-center justify-center lg:justify-start gap-8"
|
||||
>
|
||||
{#each imagesAvailables as image}
|
||||
<div class="gap-2 py-4 m-2">
|
||||
<div class="flex flex-col justify-center items-center">
|
||||
<div class="text-xl font-bold">
|
||||
{image.tag}
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
class="flex no-underline text-xs my-4"
|
||||
href="{application.gitSource.htmlUrl}/{application.repository}/commit/{image.tag}"
|
||||
target="_blank noreferrer"
|
||||
>
|
||||
<button class="btn btn-sm">
|
||||
Check Commit
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="3"
|
||||
stroke="currentColor"
|
||||
class="w-3 h-3 text-white ml-2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M4.5 19.5l15-15m0 0H8.25m11.25 0v11.25"
|
||||
/>
|
||||
</svg>
|
||||
</button></a
|
||||
>
|
||||
{#if image.repository + ':' + image.tag !== runningImage}
|
||||
<button
|
||||
class="btn btn-sm btn-primary w-full"
|
||||
on:click={() => revertApplication(image)}>Revert Now</button
|
||||
>
|
||||
{:else}
|
||||
<button class="btn btn-sm btn-primary w-full btn-disabled bg-transparent underline"
|
||||
>Currently Used</button
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,10 +4,10 @@
|
||||
</script>
|
||||
|
||||
<ul class="menu border bg-coolgray-100 border-coolgray-200 rounded p-2 space-y-2">
|
||||
<li class="menu-title">
|
||||
<span>General</span>
|
||||
</li>
|
||||
{#if $appSession.teamId === '0'}
|
||||
<li class="menu-title">
|
||||
<span>General</span>
|
||||
</li>
|
||||
<li class="rounded" class:bg-coollabs={$page.url.pathname === `/settings/coolify`}>
|
||||
<a href={`/settings/coolify`} class="no-underline w-full"
|
||||
><svg
|
||||
@@ -27,35 +27,35 @@
|
||||
</svg>Coolify Settings</a
|
||||
>
|
||||
</li>
|
||||
|
||||
<li class="rounded" class:bg-coollabs={$page.url.pathname === `/settings/docker`}>
|
||||
<a href={`/settings/docker`} class="no-underline w-full">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
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>Docker Registries</a
|
||||
>
|
||||
</li>
|
||||
{/if}
|
||||
<li class="rounded" class:bg-coollabs={$page.url.pathname === `/settings/docker`}>
|
||||
<a href={`/settings/docker`} class="no-underline w-full">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6"
|
||||
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>Docker Registries</a
|
||||
>
|
||||
</li>
|
||||
|
||||
<li class="menu-title">
|
||||
<span>Keys & Certificates</span>
|
||||
</li>
|
||||
|
||||
@@ -22,17 +22,13 @@
|
||||
import { errorNotification } from '$lib/common';
|
||||
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
|
||||
import { addToast } from '$lib/store';
|
||||
const publicRegistries = registries.public;
|
||||
const privateRegistries = registries.private;
|
||||
|
||||
let isModalActive = false;
|
||||
|
||||
let newRegistry = {
|
||||
name: '',
|
||||
username: '',
|
||||
password: '',
|
||||
url: '',
|
||||
isSystemWide: false
|
||||
url: ''
|
||||
};
|
||||
|
||||
async function handleSubmit() {
|
||||
@@ -71,6 +67,37 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
async function addRegistry(type: string) {
|
||||
switch (type) {
|
||||
case 'dockerhub':
|
||||
newRegistry = {
|
||||
name: 'Docker Hub',
|
||||
username: '',
|
||||
password: '',
|
||||
url: 'https://index.docker.io/v1/'
|
||||
};
|
||||
await handleSubmit();
|
||||
break;
|
||||
case 'gcrio':
|
||||
newRegistry = {
|
||||
name: 'Google Container Registry',
|
||||
username: '',
|
||||
password: '',
|
||||
url: 'https://gcr.io'
|
||||
};
|
||||
await handleSubmit();
|
||||
break;
|
||||
case 'github':
|
||||
newRegistry = {
|
||||
name: 'GitHub Container Registry',
|
||||
username: '',
|
||||
password: '',
|
||||
url: 'https://ghcr.io'
|
||||
};
|
||||
await handleSubmit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="w-full">
|
||||
@@ -81,57 +108,34 @@
|
||||
>Add Docker Registry</label
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center pb-4 gap-2">
|
||||
<div class="text-xs">Quick Action</div>
|
||||
<button class="btn btn-sm text-xs" on:click={() => addRegistry('dockerhub')}>DockerHub</button>
|
||||
<button class="btn btn-sm text-xs" on:click={() => addRegistry('gcrio')}
|
||||
>Google Container Registry (gcr.io)</button
|
||||
>
|
||||
<button class="btn btn-sm text-xs" on:click={() => addRegistry('github')}
|
||||
>GitHub Container Registry (ghcr.io)</button
|
||||
>
|
||||
</div>
|
||||
{#if registries.length > 0}
|
||||
<div class="mx-auto w-full">
|
||||
<table class="table w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>SystemWide</th>
|
||||
<th>Username</th>
|
||||
<th>Password</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each publicRegistries as registry}
|
||||
{#each registries as registry}
|
||||
<tr>
|
||||
<td>{registry.name}<div class="text-xs">{registry.url}</div></td>
|
||||
<td>{(registry.isSystemWide && 'Yes') || 'No'}</td>
|
||||
<td>
|
||||
<CopyPasswordField
|
||||
name="username"
|
||||
id="Username"
|
||||
bind:value={registry.username}
|
||||
placeholder="Username"
|
||||
/></td
|
||||
>
|
||||
<td
|
||||
><CopyPasswordField
|
||||
isPasswordField={true}
|
||||
name="Password"
|
||||
id="Password"
|
||||
bind:value={registry.password}
|
||||
placeholder="Password"
|
||||
/></td
|
||||
>{registry.name}
|
||||
<div class="text-xs">{registry.url}</div></td
|
||||
>
|
||||
<td>
|
||||
<button on:click={() => setRegistry(registry)} class="btn btn-sm btn-primary"
|
||||
>Set</button
|
||||
>
|
||||
{#if registry.id !== '0'}
|
||||
<button
|
||||
on:click={() => deleteDockerRegistry(registry.id)}
|
||||
class="btn btn-sm btn-error">Delete</button
|
||||
>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
{#each privateRegistries as registry}
|
||||
<tr>
|
||||
<td>{registry.name} <div class="text-xs">{registry.url}</div></td>
|
||||
<td>{(registry.isSystemWide && 'Yes') || 'No'}</td>
|
||||
<td>
|
||||
<CopyPasswordField
|
||||
name="username"
|
||||
@@ -166,6 +170,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if isModalActive}
|
||||
|
||||
Reference in New Issue
Block a user