155155 :guestOsCategories =" options.guestOsCategories"
156156 :guestOsCategoriesLoading =" loading.guestOsCategories"
157157 :selectedGuestOsCategoryId =" form.guestoscategoryid"
158- :imageItems =" imageType === 'isoid' ? options.isos : options.templates"
159- :imagesLoading =" imageType === 'isoid' ? loading.isos : loading.templates"
160- :diskSizeSelectionAllowed =" imageType !== 'isoid'"
158+ :imageItems =" imageType === 'isoid' ? options.isos : imageType === 'volumeid' ? options.volumes : imageType === 'snapshotid' ? options.snapshots : options.templates"
159+ :imagesLoading =" imageType === 'isoid' ? loading.isos : imageType === 'volumeid' ? loading.volumes : imageType === 'snapshotid' ? loading.snapshots : loading.templates"
160+ :diskSizeSelectionAllowed =" imageType !== 'isoid' && imageType !== 'volumeid' && imageType !== 'snapshotid' "
161161 :diskSizeSelectionDeployAsIsMessageVisible =" template && template.deployasis"
162162 :rootDiskOverrideDisabled =" rootDiskSizeFixed > 0 || (template && template.deployasis) || showOverrideDiskOfferingOption"
163163 :rootDiskOverrideChecked =" form.rootdisksizeitem"
248248 <a-form-item class =" form-item-hidden" >
249249 <a-input v-model:value =" form.isoid" />
250250 </a-form-item >
251+ <a-form-item class =" form-item-hidden" >
252+ <a-input v-model:value =" form.volumeid" />
253+ </a-form-item >
254+ <a-form-item class =" form-item-hidden" >
255+ <a-input v-model:value =" form.snapshotid" />
256+ </a-form-item >
251257 <a-form-item class =" form-item-hidden" >
252258 <a-input v-model:value =" form.rootdisksize" />
253259 </a-form-item >
@@ -1068,6 +1074,8 @@ export default {
10681074 },
10691075 options: {
10701076 guestOsCategories: [],
1077+ volumes: {},
1078+ snapshots: {},
10711079 templates: {},
10721080 isos: {},
10731081 hypervisors: [],
@@ -1095,6 +1103,8 @@ export default {
10951103 loading: {
10961104 deploy: false ,
10971105 guestOsCategories: false ,
1106+ volumes: false ,
1107+ snapshots: false ,
10981108 templates: false ,
10991109 isos: false ,
11001110 hypervisors: false ,
@@ -1478,6 +1488,12 @@ export default {
14781488 queryArchId () {
14791489 return this .$route .query .arch || null
14801490 },
1491+ querySnapshotId () {
1492+ return this .$route .query .snapshotid || null
1493+ },
1494+ queryVolumeId () {
1495+ return this .$route .query .volumeid || null
1496+ },
14811497 queryTemplateId () {
14821498 return this .$route .query .templateid || null
14831499 },
@@ -1601,6 +1617,9 @@ export default {
16011617 return this .$config .showAllCategoryForModernImageSelection
16021618 },
16031619 guestOsCategoriesSelectionDisallowed () {
1620+ if (this .imageType === ' volumeid' || this .imageType === ' snapshotid' ) {
1621+ return true
1622+ }
16041623 return (! this .queryGuestOsCategoryId || this .options .guestOsCategories .length === 0 ) && (!! this .queryTemplateId || !! this .queryIsoId )
16051624 },
16061625 isTemplateHypervisorExternal () {
@@ -2087,7 +2106,9 @@ export default {
20872106 this .imageType = ' templateid'
20882107 this .form .templateid = value
20892108 this .form .isoid = null
2090- this .form .volumeId = null
2109+ this .form .volumeid = null
2110+ this .form .snapshotid = null
2111+ this .resetFromTemplateConfiguration ()
20912112 let template = ' '
20922113 for (const entry of Object .values (this .options .templates )) {
20932114 template = entry? .template .find (option => option .id === value) || null
@@ -2128,6 +2149,8 @@ export default {
21282149 this .resetFromTemplateConfiguration ()
21292150 this .form .isoid = value
21302151 this .form .templateid = null
2152+ this .form .volumeid = null
2153+ this .form .snapshotid = null
21312154 let iso = null
21322155 for (const entry of Object .values (this .options .isos )) {
21332156 iso = entry? .iso .find (option => option .id === value)
@@ -2140,24 +2163,59 @@ export default {
21402163 this .updateTemplateLinkedUserData (this .iso .userdataid )
21412164 this .userdataDefaultOverridePolicy = this .iso .userdatapolicy
21422165 }
2143- } else if (name === ' volumeId' ) {
2144- this .templateConfigurations = []
2145- this .selectedTemplateConfiguration = {}
2146- this .templateNics = []
2147- this .templateLicenses = []
2148- this .templateProperties = {}
2149- this .tabKey = ' volumeId'
2150- this .resetFromTemplateConfiguration ()
2151- this .form .volumeId = value
2152- this .form .templateid = null
2153- this .form .isoid = null
2166+ } else if (name === ' volumeid' ) {
2167+ this .updateFieldValueForVolume (value)
2168+ } else if (name === ' snapshotid' ) {
2169+ this .updateFieldValueForSnapshot (value)
21542170 } else if ([' cpuspeed' , ' cpunumber' , ' memory' ].includes (name)) {
21552171 this .vm [name] = value
21562172 this .form [name] = value
21572173 } else {
21582174 this .form [name] = value
21592175 }
21602176 },
2177+ updateFieldValueForVolume (value ) {
2178+ this .imageType = ' volumeid'
2179+ this .resetTemplateAssociatedResources ()
2180+ this .resetFromTemplateConfiguration ()
2181+ this .form .templateid = null
2182+ this .form .isoid = null
2183+ this .form .volumeid = value
2184+ this .form .snapshotid = null
2185+ let volume = null
2186+ for (const entry of Object .values (this .options .volumes )) {
2187+ volume = entry? .volume .find (option => option .id === value)
2188+ if (volume) {
2189+ this .volume = volume
2190+ break
2191+ }
2192+ }
2193+ if (volume) {
2194+ this .updateTemplateLinkedUserData (this .volume .userdataid )
2195+ this .userdataDefaultOverridePolicy = this .volume .userdatapolicy
2196+ }
2197+ },
2198+ updateFieldValueForSnapshot (value ) {
2199+ this .imageType = ' snapshotid'
2200+ this .resetTemplateAssociatedResources ()
2201+ this .resetFromTemplateConfiguration ()
2202+ this .form .templateid = null
2203+ this .form .isoid = null
2204+ this .form .volumeid = null
2205+ this .form .snapshotid = value
2206+ let snapshot = null
2207+ for (const entry of Object .values (this .options .snapshots )) {
2208+ snapshot = entry? .snapshot .find (option => option .id === value)
2209+ if (snapshot) {
2210+ this .snapshot = snapshot
2211+ break
2212+ }
2213+ }
2214+ if (snapshot) {
2215+ this .updateTemplateLinkedUserData (this .snapshot .userdataid )
2216+ this .userdataDefaultOverridePolicy = this .snapshot .userdatapolicy
2217+ }
2218+ },
21612219 updateComputeOffering (id , kvdoEnable ) {
21622220 this .form .computeofferingid = id
21632221 this .form .computeOfferingKvdoEnable = kvdoEnable
@@ -2327,7 +2385,7 @@ export default {
23272385 if (this .loading .deploy ) return
23282386 this .formRef .value .validate ().then (async () => {
23292387 const values = toRaw (this .form )
2330- if (! values .templateid && ! values .isoid && ! values .volumeId ) {
2388+ if (! values .templateid && ! values .isoid && ! values .volumeid && ! values . snapshotid ) {
23312389 this .$notification .error ({
23322390 message: this .$t (' message.request.failed' ),
23332391 description: this .$t (' message.template.iso' )
@@ -2392,11 +2450,13 @@ export default {
23922450 this .loading .deploy = false
23932451 return
23942452 }
2395- } else if (this .tabKey === ' isoid' ) {
2453+ } else if (this .imageType === ' volumeid' ) {
2454+ deployVmData .volumeid = values .volumeid
2455+ } else if (this .imageType === ' snapshotid' ) {
2456+ deployVmData .snapshotid = values .snapshotid
2457+ } else {
23962458 deployVmData .templateid = values .isoid
2397- } else if (this .tabKey === ' volumeId' ) {
2398- deployVmData .volumeId = values .volumeId
2399- }
2459+ }
24002460
24012461 if (this .showRootDiskSizeChanger && values .rootdisksize && values .rootdisksize > 0 ) {
24022462 deployVmData .rootdisksize = values .rootdisksize
@@ -2830,6 +2890,88 @@ export default {
28302890 })
28312891 })
28322892 },
2893+ fetchUnattachedVolumes (volumeFilter , params ) {
2894+ const args = Object .assign ({}, params)
2895+ if (args .keyword || (args .category && args .category !== volumeFilter)) {
2896+ args .page = 1
2897+ args .pageSize = args .pageSize || 10
2898+ }
2899+ args .zoneid = _ .get (this .zone , ' id' )
2900+ if (this .isZoneSelectedMultiArch ) {
2901+ args .arch = this .selectedArchitecture
2902+ }
2903+ args .account = store .getters .project ? .id ? null : this .owner .account
2904+ args .domainid = store .getters .project ? .id ? null : this .owner .domainid
2905+ args .projectid = store .getters .project ? .id || this .owner .projectid
2906+ args .id = this .queryVolumeId
2907+ args .state = ' Ready'
2908+ const pageSize = args .pageSize ? args .pageSize : 10
2909+ const pageStart = (args .page ? args .page - 1 : 0 ) * pageSize
2910+ const pageEnd = pageSize * (pageStart + 1 )
2911+
2912+ delete args .category
2913+ delete args .public
2914+ delete args .featured
2915+ delete args .page
2916+ delete args .pageSize
2917+
2918+ return new Promise ((resolve , reject ) => {
2919+ getAPI (' listVolumes' , args).then ((response ) => {
2920+ let count = 0
2921+ const volumes = []
2922+ response .listvolumesresponse .volume .forEach (volume => {
2923+ if (! volume .virtualmachineid ) {
2924+ count += 1
2925+ volumes .push ({ ... volume, displaytext: volume .name })
2926+ }
2927+ })
2928+ resolve ({ listvolumesresponse: { count, volume: volumes .slice (pageStart, pageEnd) } })
2929+ }).catch ((reason ) => {
2930+ // ToDo: Handle errors
2931+ reject (reason)
2932+ })
2933+ })
2934+ },
2935+ fetchRootSnapshots (snapshotFilter , params ) {
2936+ const args = Object .assign ({}, params)
2937+ if (args .keyword || (args .category && args .category !== snapshotFilter)) {
2938+ args .page = 1
2939+ args .pageSize = args .pageSize || 10
2940+ }
2941+ args .zoneid = _ .get (this .zone , ' id' )
2942+ if (this .isZoneSelectedMultiArch ) {
2943+ args .arch = this .selectedArchitecture
2944+ }
2945+ args .account = store .getters .project ? .id ? null : this .owner .account
2946+ args .domainid = store .getters .project ? .id ? null : this .owner .domainid
2947+ args .projectid = store .getters .project ? .id || this .owner .projectid
2948+ const pageSize = args .pageSize ? args .pageSize : 10
2949+ const pageStart = (args .page ? args .page - 1 : 0 ) * pageSize
2950+ const pageEnd = pageSize * (pageStart + 1 )
2951+
2952+ delete args .category
2953+ delete args .public
2954+ delete args .featured
2955+ delete args .page
2956+ delete args .pageSize
2957+
2958+ return new Promise ((resolve , reject ) => {
2959+ getAPI (' listSnapshots' , args).then ((response ) => {
2960+ let count = 0
2961+ const snapshots = []
2962+ response .listsnapshotsresponse .snapshot .forEach (snapshot => {
2963+ if (snapshot .volumetype === ' ROOT' ) {
2964+ count += 1
2965+ snapshots .push ({ ... snapshot, displaytext: snapshot .name })
2966+ }
2967+ })
2968+ resolve ({ listsnapshotsresponse: { count, snapshot: snapshots .slice (pageStart, pageEnd) } })
2969+ }).catch ((reason ) => {
2970+ // ToDo: Handle errors
2971+ reject (reason)
2972+ })
2973+ })
2974+ },
28332975 fetchTemplates (templateFilter , params ) {
28342976 const args = Object .assign ({}, params)
28352977 if (this .isModernImageSelection && this .form .guestoscategoryid && ! [' -1' , ' 0' ].includes (this .form .guestoscategoryid )) {
@@ -2926,6 +3068,14 @@ export default {
29263068 this .fetchAllIsos (params)
29273069 return
29283070 }
3071+ if (this .imageType === ' volumeid' ) {
3072+ this .fetchAllVolumes (params)
3073+ return
3074+ }
3075+ if (this .imageType === ' snapshotid' ) {
3076+ this .fetchAllSnapshots (params)
3077+ return
3078+ }
29293079 this .fetchAllTemplates (params)
29303080 },
29313081 fetchAllTemplates (params ) {
@@ -2972,21 +3122,48 @@ export default {
29723122 this .loading .isos = false
29733123 })
29743124 },
2975- fetchAllRbdImage (params ) {
3125+ fetchAllVolumes (params ) {
3126+ const promises = []
3127+ const volumes = {}
3128+ this .loading .volumes = true
3129+ this .imageSearchFilters = params
3130+ const volumeFilters = this .getImageFilters (params)
3131+ volumeFilters .forEach ((filter ) => {
3132+ volumes[filter] = { count: 0 , volume: [] }
3133+ promises .push (this .fetchUnattachedVolumes (filter, params))
3134+ })
3135+ this .options .volumes = volumes
3136+ Promise .all (promises).then ((response ) => {
3137+ response .forEach ((resItem , idx ) => {
3138+ volumes[volumeFilters[idx]] = _ .isEmpty (resItem .listvolumesresponse ) ? { count: 0 , volume: [] } : resItem .listvolumesresponse
3139+ this .options .volumes = { ... volumes }
3140+ })
3141+ }).catch ((reason ) => {
3142+ console .log (reason)
3143+ }).finally (() => {
3144+ this .loading .volumes = false
3145+ })
3146+ },
3147+ fetchAllSnapshots (params ) {
29763148 const promises = []
2977- const volume = {}
2978- this .loading .volume = true
2979- promises .push (this .fetchRbdImage (params))
2980- this .options .volume = volume
3149+ const snapshots = {}
3150+ this .loading .snapshots = true
3151+ this .imageSearchFilters = params
3152+ const snapshotFilters = this .getImageFilters (params)
3153+ snapshotFilters .forEach ((filter ) => {
3154+ snapshots[filter] = { count: 0 , snapshot: [] }
3155+ promises .push (this .fetchRootSnapshots (filter, params))
3156+ })
3157+ this .options .snapshots = snapshots
29813158 Promise .all (promises).then ((response ) => {
29823159 response .forEach ((resItem , idx ) => {
2983- this . options . volume = resItem .listvolumesresponse . volume
2984- this .rowCount . volume = resItem . listvolumesresponse . count
3160+ snapshots[snapshotFilters[idx]] = _ . isEmpty ( resItem . listsnapshotsresponse ) ? { count : 0 , snapshot : [] } : resItem .listsnapshotsresponse
3161+ this .options . snapshots = { ... snapshots }
29853162 })
29863163 }).catch ((reason ) => {
29873164 console .log (reason)
29883165 }).finally (() => {
2989- this .loading .volume = false
3166+ this .loading .snapshots = false
29903167 })
29913168 },
29923169 filterOption (input , option ) {
@@ -3121,7 +3298,7 @@ export default {
31213298 }
31223299 },
31233300 updateImages () {
3124- if (this .isModernImageSelection ) {
3301+ if (this .isModernImageSelection && this . imageType !== ' snapshotid ' && this . imageType !== ' volumeid ' ) {
31253302 this .fetchGuestOsCategories ()
31263303 return
31273304 }
0 commit comments