Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitad6b895

Browse files
committed
Merge branch 'pg-image-not-found-fallback' into 'master'
fix: white screen crash for custom Docker tagsSee merge request postgres-ai/database-lab!1043
2 parents597d1d3 +7e52d75 commitad6b895

File tree

3 files changed

+182
-58
lines changed

3 files changed

+182
-58
lines changed

‎ui/packages/shared/pages/Instance/Configuration/index.tsx‎

Lines changed: 89 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*--------------------------------------------------------------------------
66
*/
77

8-
import{useState,useEffect}from'react'
8+
import{useState,useEffect,useMemo}from'react'
99
import{observer}from'mobx-react-lite'
1010
importEditorfrom'@monaco-editor/react'
1111
import{
@@ -35,6 +35,9 @@ import {
3535
uniqueChipValue,
3636
customOrGenericImage,
3737
genericDockerImages,
38+
getImageMajorVersion,
39+
createFallbackDockerImage,
40+
createEnhancedDockerImages,
3841
}from'./utils'
3942
import{
4043
SelectWithTooltip,
@@ -194,6 +197,32 @@ export const Configuration = observer(
194197
const[{ formik, connectionData, isConnectionDataValid}]=
195198
useForm(onSubmit)
196199

200+
// Memoized enhanced Docker images to avoid recreation on every render
201+
// This combines predefined images with any custom image from configuration
202+
constenhancedDockerImages=useMemo(()=>{
203+
returncreateEnhancedDockerImages(
204+
configData?.dockerImageType==='Generic Postgres' ?configData?.dockerPath :undefined,
205+
configData?.dockerImageType==='Generic Postgres' ?configData?.dockerTag :undefined
206+
)
207+
},[configData?.dockerPath,configData?.dockerTag,configData?.dockerImageType])
208+
209+
// Memoized computed values from enhanced images
210+
constdockerImageVersions=useMemo(()=>{
211+
returnenhancedDockerImages
212+
.map((image)=>image.pg_major_version)
213+
.filter((value,index,self)=>self.indexOf(value)===index)
214+
.sort((a,b)=>Number(a)-Number(b))
215+
},[enhancedDockerImages])
216+
217+
// Memoized tags and locations for performance
218+
constdockerTags=useMemo(()=>{
219+
returnenhancedDockerImages.map((image)=>image.tag)
220+
},[enhancedDockerImages])
221+
222+
constdockerLocations=useMemo(()=>{
223+
returnenhancedDockerImages.map((image)=>image.location)
224+
},[enhancedDockerImages])
225+
197226
constscrollToField=()=>{
198227
consterrorElement=document.querySelector('.Mui-error')
199228
if(errorElement){
@@ -457,30 +486,23 @@ export const Configuration = observer(
457486
e:React.ChangeEvent<HTMLInputElement>,
458487
)=>{
459488
if(e.target.value==='Generic Postgres'){
460-
constgenericImageVersions=genericDockerImages
461-
.map((image)=>image.pg_major_version)
462-
.filter((value,index,self)=>self.indexOf(value)===index)
463-
.sort((a,b)=>Number(a)-Number(b))
464-
constcurrentDockerImage=genericImageVersions.slice(-1)[0]
489+
// Use memoized enhanced list for better performance
490+
constcurrentDockerImage=dockerImageVersions.slice(-1)[0]
465491

466492
setDockerState({
467493
...dockerState,
468-
tags:genericDockerImages
469-
.map((image)=>image.tag)
470-
.filter((tag)=>tag.startsWith(currentDockerImage)),
471-
locations:genericDockerImages
472-
.map((image)=>image.location)
473-
.filter((location)=>location?.includes(currentDockerImage)),
474-
images:genericImageVersions,
475-
data:genericDockerImages,
494+
tags:dockerTags.filter((tag)=>tag.startsWith(currentDockerImage)),
495+
locations:dockerLocations.filter((location)=>location?.includes(currentDockerImage)),
496+
images:dockerImageVersions,
497+
data:enhancedDockerImages,
476498
})
477499

478500
formik.setValues({
479501
...formik.values,
480502
dockerImage:currentDockerImage,
481503
dockerImageType:e.target.value,
482-
dockerTag:genericDockerImages.map((image)=>image.tag)[0],
483-
dockerPath:genericDockerImages.map((image)=>image.location)[0],
504+
dockerTag:dockerTags[0],
505+
dockerPath:dockerLocations[0],
484506
sharedPreloadLibraries:
485507
'pg_stat_statements,pg_stat_kcache,pg_cron,pgaudit,anon',
486508
})
@@ -520,16 +542,28 @@ export const Configuration = observer(
520542
tags:updatedDockerTags,
521543
})
522544

523-
constcurrentLocation=dockerState.data.find(
524-
(image)=>image.tag===updatedDockerTags[0],
525-
)?.locationasstring
545+
// Add safety check for empty array
546+
constfirstTag=updatedDockerTags[0]
547+
if(firstTag){
548+
constcurrentLocation=dockerState.data.find(
549+
(image)=>image.tag===firstTag,
550+
)?.location
526551

527-
formik.setValues({
528-
...formik.values,
529-
dockerTag:updatedDockerTags[0],
530-
dockerImage:e.target.value,
531-
dockerPath:currentLocation,
532-
})
552+
formik.setValues({
553+
...formik.values,
554+
dockerTag:firstTag,
555+
dockerImage:e.target.value,
556+
dockerPath:currentLocation||'',
557+
})
558+
}else{
559+
// Fallback when no matching tags found
560+
formik.setValues({
561+
...formik.values,
562+
dockerImage:e.target.value,
563+
dockerTag:'',
564+
dockerPath:'',
565+
})
566+
}
533567
}else{
534568
formik.setValues({
535569
...formik.values,
@@ -553,41 +587,46 @@ export const Configuration = observer(
553587

554588
if(customOrGenericImage(configData?.dockerImageType)){
555589
if(configData?.dockerImageType==='Generic Postgres'){
556-
constgenericImageVersions=genericDockerImages
557-
.map((image)=>image.pg_major_version)
558-
.filter((value,index,self)=>self.indexOf(value)===index)
559-
.sort((a,b)=>Number(a)-Number(b))
560-
constcurrentDockerImage=
561-
genericDockerImages.filter(
562-
(image)=>image.location===configData?.dockerPath,
563-
)[0]||
564-
genericDockerImages.filter((image)=>
565-
configData?.dockerPath?.includes(image.pg_major_version),
566-
)[0]
590+
// Use memoized enhanced list for better performance
591+
constcurrentDockerImage=enhancedDockerImages.find(
592+
(image)=>image.location===configData?.dockerPath||image.tag===configData?.dockerTag
593+
)
567594

568-
setDockerState({
569-
...dockerState,
570-
tags:genericDockerImages
571-
.map((image)=>image.tag)
572-
.filter((tag)=>
595+
if(currentDockerImage){
596+
setDockerState({
597+
...dockerState,
598+
tags:dockerTags.filter((tag)=>
573599
tag.startsWith(currentDockerImage.pg_major_version),
574600
),
575-
images:genericImageVersions,
576-
data:genericDockerImages,
577-
})
601+
images:dockerImageVersions,
602+
data:enhancedDockerImages,
603+
})
578604

579-
formik.setFieldValue('dockerTag',currentDockerImage?.tag)
580-
formik.setFieldValue(
581-
'dockerImage',
582-
currentDockerImage.pg_major_version,
583-
)
605+
formik.setFieldValue('dockerTag',currentDockerImage.tag)
606+
formik.setFieldValue('dockerImage',currentDockerImage.pg_major_version)
607+
formik.setFieldValue('dockerPath',currentDockerImage.location)
608+
}else{
609+
// Fallback: shouldn't happen with enhancedDockerImages, but keep for safety
610+
constfallbackVersion=dockerImageVersions.slice(-1)[0]
611+
612+
setDockerState({
613+
...dockerState,
614+
tags:dockerTags.filter((tag)=>tag.startsWith(fallbackVersion)),
615+
images:dockerImageVersions,
616+
data:enhancedDockerImages,
617+
})
618+
619+
formik.setFieldValue('dockerTag',configData?.dockerTag||'')
620+
formik.setFieldValue('dockerImage',fallbackVersion)
621+
formik.setFieldValue('dockerPath',configData?.dockerPath||'')
622+
}
584623
}else{
585624
formik.setFieldValue('dockerImage',configData?.dockerPath)
586625
}
587626
}
588627
}
589628
}
590-
},[config])
629+
},[config,configData?.dockerPath,configData?.dockerTag,configData?.dockerImageType])
591630

592631
useEffect(()=>{
593632
getEngine(instanceId).then((res)=>{

‎ui/packages/shared/pages/Instance/Configuration/utils/index.ts‎

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { FormValues } from '../useForm'
55

66
constseContainerRegistry='se-images'
77
constgenericImagePrefix='postgresai/extended-postgres'
8-
// since some tags are rc, we need to specify the exact tags to use
8+
// Predefined list of Docker images for UI display
9+
// This list is shown to users for convenient selection
10+
// IMPORTANT: if user specified an image in config that's not in this list,
11+
// it will be automatically added via createEnhancedDockerImages()
912
constdockerImagesConfig={
1013
'9.6':['0.5.3','0.5.2','0.5.1'],
1114
'10':['0.5.3','0.5.2','0.5.1'],
@@ -110,11 +113,22 @@ export const getImageType = (imageUrl: string) => {
110113
}
111114

112115
exportconstgetImageMajorVersion=(pgImage:string|undefined)=>{
113-
constpgImageVersion=pgImage?.split(':')[1]
114-
constpgServerVersion=pgImageVersion?.split('-')[0]
115-
returnpgServerVersion?.includes('.')
116-
?pgServerVersion?.split('.')[0]
117-
:pgServerVersion
116+
if(!pgImage)returnundefined
117+
118+
try{
119+
constpgImageVersion=pgImage.split(':')[1]
120+
if(!pgImageVersion)returnundefined
121+
122+
constpgServerVersion=pgImageVersion.split('-')[0]
123+
if(!pgServerVersion)returnundefined
124+
125+
returnpgServerVersion.includes('.')
126+
?pgServerVersion.split('.')[0]
127+
:pgServerVersion
128+
}catch(error){
129+
// Return undefined for malformed image strings
130+
returnundefined
131+
}
118132
}
119133

120134
exportconstformatDatabases=(databases:DatabaseType|null)=>{
@@ -151,3 +165,71 @@ export const postUniqueCustomOptions = (options: string) => {
151165

152166
exportconstcustomOrGenericImage=(dockerImage:string|undefined)=>
153167
dockerImage==='Generic Postgres'||dockerImage==='custom'
168+
169+
exportconstcreateFallbackDockerImage=(
170+
dockerPath:string,
171+
dockerTag:string,
172+
):DockerImage=>{
173+
constmajorVersion=getImageMajorVersion(dockerPath)||'17'// Default to 17 if version can't be extracted
174+
175+
return{
176+
package_group:'postgresai',
177+
pg_major_version:majorVersion,
178+
tag:dockerTag||`${majorVersion}-custom`,
179+
location:dockerPath,
180+
}
181+
}
182+
183+
// Creates enhanced list of Docker images, including image from configuration
184+
exportconstcreateEnhancedDockerImages=(
185+
configDockerPath?:string,
186+
configDockerTag?:string,
187+
):DockerImage[]=>{
188+
letenhancedImages=[...genericDockerImages]
189+
190+
// If there's an image in config, check if we need to add it
191+
if(configDockerPath&&configDockerTag){
192+
constexistingImage=genericDockerImages.find(
193+
(image)=>image.location===configDockerPath||image.tag===configDockerTag
194+
)
195+
196+
// If image not found in predefined list, add it
197+
if(!existingImage){
198+
// Check if this is a Generic Postgres image
199+
if(configDockerPath.includes(genericImagePrefix)){
200+
// For Generic Postgres images create proper structure
201+
constmajorVersion=getImageMajorVersion(configDockerPath)
202+
if(majorVersion){
203+
constconfigImage:DockerImage={
204+
package_group:'postgresai',
205+
pg_major_version:majorVersion,
206+
tag:configDockerTag,
207+
location:configDockerPath,
208+
}
209+
enhancedImages.push(configImage)
210+
}else{
211+
// Fallback if version extraction failed
212+
constconfigImage=createFallbackDockerImage(configDockerPath,configDockerTag)
213+
enhancedImages.push(configImage)
214+
}
215+
}else{
216+
// For custom images use fallback
217+
constconfigImage=createFallbackDockerImage(configDockerPath,configDockerTag)
218+
enhancedImages.push(configImage)
219+
}
220+
}
221+
}
222+
223+
returnenhancedImages
224+
}
225+
226+
// Checks if image is loaded from configuration (not from predefined list)
227+
exportconstisConfigLoadedImage=(
228+
dockerPath:string,
229+
dockerTag:string,
230+
):boolean=>{
231+
constexistingImage=genericDockerImages.find(
232+
(image)=>image.location===dockerPath||image.tag===dockerTag
233+
)
234+
return!existingImage
235+
}

‎ui/packages/shared/types/api/entities/config.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,15 @@ export const formatConfig = (config: configTypes) => {
6363
debug:config.global?.debug,
6464
dockerImage:isSeDockerImage(dockerImage)
6565
?getImageMajorVersion(dockerImage)
66+
:dockerImage&&getImageType(dockerImage)==='Generic Postgres'
67+
?getImageMajorVersion(dockerImage)||dockerImage
6668
:dockerImage,
6769
...(dockerImage&&{
6870
dockerImageType:getImageType(dockerImage),
6971
}),
70-
...(isSeDockerImage(dockerImage)&&{
71-
dockerTag:dockerImage?.split(':')[1],
72+
// Extract dockerTag for both SE images and Generic Postgres images
73+
...(dockerImage&&dockerImage.includes(':')&&{
74+
dockerTag:dockerImage.split(':')[1],
7275
}),
7376
dockerPath:dockerImage,
7477
tuningParams:formatTuningParams(config.databaseConfigs?.configs),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp