Skip to content

Commit f4a3e3b

Browse files
joaomariolagopatrickelectric
authored andcommitted
core:frontend: Add Load/Install ext frontend
1 parent 2fd7752 commit f4a3e3b

4 files changed

Lines changed: 754 additions & 21 deletions

File tree

core/frontend/src/components/kraken/KrakenManager.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import {
22
ExtensionData,
3+
ExtensionUploadResponse,
34
InstalledExtensionData,
45
Manifest,
56
ManifestSource,
67
RunningContainer,
8+
UploadProgressEvent,
79
} from '@/types/kraken'
810
import back_axios from '@/utils/api'
911

@@ -335,6 +337,74 @@ export async function getContainerLogs(
335337
})
336338
}
337339

340+
/**
341+
* Upload a tar file containing a Docker image and extract metadata
342+
* @param {File} file The tar file to upload
343+
* @returns {Promise<{temp_tag: string, metadata: any, image_name: string}>}
344+
*/
345+
export async function uploadExtensionTarFile(
346+
file: File,
347+
progressHandler?: (event: UploadProgressEvent) => void,
348+
): Promise<ExtensionUploadResponse> {
349+
const formData = new FormData()
350+
formData.append('file', file)
351+
352+
const response = await back_axios({
353+
method: 'POST',
354+
url: `${KRAKEN_API_V2_URL}/extension/upload`,
355+
data: formData,
356+
headers: {
357+
'Content-Type': 'multipart/form-data',
358+
},
359+
timeout: 120000,
360+
onUploadProgress: progressHandler,
361+
})
362+
363+
return response.data
364+
}
365+
366+
/**
367+
* Keep a temporary uploaded extension alive while the user configures metadata.
368+
* @param {string} tempTag The temporary tag returned by the upload endpoint
369+
* @returns {Promise<void>}
370+
*/
371+
export async function keepTemporaryExtensionAlive(tempTag: string): Promise<void> {
372+
await back_axios({
373+
method: 'POST',
374+
url: `${KRAKEN_API_V2_URL}/extension/upload/keep-alive?temp_tag=${tempTag}`,
375+
timeout: 10000,
376+
})
377+
}
378+
379+
/**
380+
* Finalize a temporary extension by assigning a valid identifier and installing it
381+
* @param {InstalledExtensionData} extension The extension data to finalize
382+
* @param {string} tempTag The temporary tag from upload response
383+
* @param {function} progressHandler The progress handler for the download
384+
* @returns {Promise<void>}
385+
*/
386+
export async function finalizeExtension(
387+
extension: InstalledExtensionData,
388+
tempTag: string,
389+
progressHandler: (event: any) => void,
390+
): Promise<void> {
391+
await back_axios({
392+
method: 'POST',
393+
url: `${KRAKEN_API_V2_URL}/extension/upload/finalize?temp_tag=${tempTag}`,
394+
data: {
395+
identifier: extension.identifier,
396+
name: extension.name,
397+
docker: extension.docker,
398+
tag: extension.tag,
399+
enabled: true,
400+
permissions: extension?.permissions ?? '',
401+
user_permissions: extension?.user_permissions ?? '',
402+
},
403+
timeout: 120000,
404+
onDownloadProgress: progressHandler,
405+
})
406+
}
407+
338408
export default {
339409
fetchManifestSources,
340410
fetchManifestSource,
@@ -357,4 +427,7 @@ export default {
357427
listContainers,
358428
getContainersStats,
359429
getContainerLogs,
430+
uploadExtensionTarFile,
431+
keepTemporaryExtensionAlive,
432+
finalizeExtension,
360433
}

core/frontend/src/components/kraken/modals/ExtensionCreationModal.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
>
1010
<v-card>
1111
<v-card-title class="d-flex align-center justify-space-between">
12-
<span>{{ is_editing ? 'Edit' : 'Create' }} Extension</span>
12+
<span>{{ is_editing ? 'Edit' : (is_from_upload ? 'Configure Uploaded' : 'Create') }} Extension</span>
1313
<v-btn
1414
icon
1515
x-small
@@ -89,7 +89,7 @@
8989
:disabled="!valid_permissions"
9090
@click="saveExtension"
9191
>
92-
{{ is_editing ? 'Save' : 'Create' }}
92+
{{ is_editing ? 'Save' : (is_from_upload ? 'Install' : 'Create') }}
9393
</v-btn>
9494
</v-card-actions>
9595
</v-card>
@@ -118,6 +118,10 @@ export default Vue.extend({
118118
type: Object as PropType<InstalledExtensionData & { editing: boolean } | null>,
119119
default: null,
120120
},
121+
tempTag: {
122+
type: String,
123+
default: null,
124+
},
121125
},
122126
123127
data() {
@@ -141,6 +145,9 @@ export default Vue.extend({
141145
is_editing() {
142146
return this.extension?.editing ?? false
143147
},
148+
is_from_upload() {
149+
return Boolean(this.tempTag)
150+
},
144151
is_reset_editing_permissions_visible() {
145152
return this.new_permissions !== this.extension?.permissions
146153
},

core/frontend/src/types/kraken.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,27 @@ export interface Manifest extends ManifestSource {
9494
data?: [ExtensionData]
9595
}
9696

97-
export interface ProgressEvent {
97+
export interface StreamProgressEvent {
9898
currentTarget: {
9999
response: string
100100
}
101-
}
101+
}
102+
103+
export interface UploadProgressEvent {
104+
loaded: number
105+
total?: number
106+
}
107+
108+
export interface ExtensionUploadMetadata {
109+
identifier?: string
110+
name?: string
111+
docker?: string
112+
tag?: string
113+
permissions?: JSONValue
114+
}
115+
116+
export interface ExtensionUploadResponse {
117+
temp_tag: string
118+
metadata: ExtensionUploadMetadata
119+
image_name: string
120+
}

0 commit comments

Comments
 (0)