133133 :guestOsCategories =" options.guestOsCategories"
134134 :guestOsCategoriesLoading =" loading.guestOsCategories"
135135 :selectedGuestOsCategoryId =" form.guestoscategoryid"
136- :imageItems =" imageType === 'isoid' ? options.isos : options.templates"
137- :imagesLoading =" imageType === 'isoid' ? loading.isos : loading.templates"
138- :diskSizeSelectionAllowed =" imageType !== 'isoid'"
136+ :imageItems =" imageType === 'isoid' ? options.isos : imageType === 'volumeid' ? options.volumes : imageType === 'snapshotid' ? options.snapshots : options.templates"
137+ :imagesLoading =" imageType === 'isoid' ? loading.isos : imageType === 'volumeid' ? loading.volumes : imageType === 'snapshotid' ? loading.snapshots : loading.templates"
138+ :diskSizeSelectionAllowed =" imageType !== 'isoid' && imageType !== 'volumeid' && imageType !== 'snapshotid' "
139139 :diskSizeSelectionDeployAsIsMessageVisible =" template && template.deployasis"
140140 :rootDiskOverrideDisabled =" rootDiskSizeFixed > 0 || (template && template.deployasis) || showOverrideDiskOfferingOption"
141141 :rootDiskOverrideChecked =" form.rootdisksizeitem"
211211 <a-form-item class =" form-item-hidden" >
212212 <a-input v-model:value =" form.isoid" />
213213 </a-form-item >
214+ <a-form-item class =" form-item-hidden" >
215+ <a-input v-model:value =" form.volumeid" />
216+ </a-form-item >
217+ <a-form-item class =" form-item-hidden" >
218+ <a-input v-model:value =" form.snapshotid" />
219+ </a-form-item >
214220 <a-form-item class =" form-item-hidden" >
215221 <a-input v-model:value =" form.rootdisksize" />
216222 </a-form-item >
@@ -997,6 +1003,8 @@ export default {
9971003 },
9981004 options: {
9991005 guestOsCategories: [],
1006+ volumes: {},
1007+ snapshots: {},
10001008 templates: {},
10011009 isos: {},
10021010 hypervisors: [],
@@ -1020,6 +1028,8 @@ export default {
10201028 loading: {
10211029 deploy: false ,
10221030 guestOsCategories: false ,
1031+ volumes: false ,
1032+ snapshots: false ,
10231033 templates: false ,
10241034 isos: false ,
10251035 hypervisors: false ,
@@ -1400,6 +1410,12 @@ export default {
14001410 queryArchId () {
14011411 return this .$route .query .arch || null
14021412 },
1413+ querySnapshotId () {
1414+ return this .$route .query .snapshotid || null
1415+ },
1416+ queryVolumeId () {
1417+ return this .$route .query .volumeid || null
1418+ },
14031419 queryTemplateId () {
14041420 return this .$route .query .templateid || null
14051421 },
@@ -1492,6 +1508,9 @@ export default {
14921508 return this .$config .showAllCategoryForModernImageSelection
14931509 },
14941510 guestOsCategoriesSelectionDisallowed () {
1511+ if (this .imageType === ' volumeid' || this .imageType === ' snapshotid' ) {
1512+ return true
1513+ }
14951514 return (! this .queryGuestOsCategoryId || this .options .guestOsCategories .length === 0 ) && (!! this .queryTemplateId || !! this .queryIsoId )
14961515 },
14971516 isTemplateHypervisorExternal () {
@@ -1955,6 +1974,8 @@ export default {
19551974 this .imageType = ' templateid'
19561975 this .form .templateid = value
19571976 this .form .isoid = null
1977+ this .form .volumeid = null
1978+ this .form .snapshotid = null
19581979 this .resetFromTemplateConfiguration ()
19591980 let template = ' '
19601981 for (const entry of Object .values (this .options .templates )) {
@@ -1991,6 +2012,8 @@ export default {
19912012 this .resetFromTemplateConfiguration ()
19922013 this .form .isoid = value
19932014 this .form .templateid = null
2015+ this .form .volumeid = null
2016+ this .form .snapshotid = null
19942017 let iso = null
19952018 for (const entry of Object .values (this .options .isos )) {
19962019 iso = entry? .iso .find (option => option .id === value)
@@ -2003,13 +2026,59 @@ export default {
20032026 this .updateTemplateLinkedUserData (this .iso .userdataid )
20042027 this .userdataDefaultOverridePolicy = this .iso .userdatapolicy
20052028 }
2029+ } else if (name === ' volumeid' ) {
2030+ this .updateFieldValueForVolume (value)
2031+ } else if (name === ' snapshotid' ) {
2032+ this .updateFieldValueForSnapshot (value)
20062033 } else if ([' cpuspeed' , ' cpunumber' , ' memory' ].includes (name)) {
20072034 this .vm [name] = value
20082035 this .form [name] = value
20092036 } else {
20102037 this .form [name] = value
20112038 }
20122039 },
2040+ updateFieldValueForVolume (value ) {
2041+ this .imageType = ' volumeid'
2042+ this .resetTemplateAssociatedResources ()
2043+ this .resetFromTemplateConfiguration ()
2044+ this .form .templateid = null
2045+ this .form .isoid = null
2046+ this .form .volumeid = value
2047+ this .form .snapshotid = null
2048+ let volume = null
2049+ for (const entry of Object .values (this .options .volumes )) {
2050+ volume = entry? .volume .find (option => option .id === value)
2051+ if (volume) {
2052+ this .volume = volume
2053+ break
2054+ }
2055+ }
2056+ if (volume) {
2057+ this .updateTemplateLinkedUserData (this .volume .userdataid )
2058+ this .userdataDefaultOverridePolicy = this .volume .userdatapolicy
2059+ }
2060+ },
2061+ updateFieldValueForSnapshot (value ) {
2062+ this .imageType = ' snapshotid'
2063+ this .resetTemplateAssociatedResources ()
2064+ this .resetFromTemplateConfiguration ()
2065+ this .form .templateid = null
2066+ this .form .isoid = null
2067+ this .form .volumeid = null
2068+ this .form .snapshotid = value
2069+ let snapshot = null
2070+ for (const entry of Object .values (this .options .snapshots )) {
2071+ snapshot = entry? .snapshot .find (option => option .id === value)
2072+ if (snapshot) {
2073+ this .snapshot = snapshot
2074+ break
2075+ }
2076+ }
2077+ if (snapshot) {
2078+ this .updateTemplateLinkedUserData (this .snapshot .userdataid )
2079+ this .userdataDefaultOverridePolicy = this .snapshot .userdatapolicy
2080+ }
2081+ },
20132082 updateComputeOffering (id ) {
20142083 this .form .computeofferingid = id
20152084 setTimeout (() => {
@@ -2171,7 +2240,7 @@ export default {
21712240 if (this .loading .deploy ) return
21722241 this .formRef .value .validate ().then (async () => {
21732242 const values = toRaw (this .form )
2174- if (! values .templateid && ! values .isoid ) {
2243+ if (! values .templateid && ! values .isoid && ! values . volumeid && ! values . snapshotid ) {
21752244 this .$notification .error ({
21762245 message: this .$t (' message.request.failed' ),
21772246 description: this .$t (' message.template.iso' )
@@ -2227,6 +2296,10 @@ export default {
22272296 if (this .imageType === ' templateid' ) {
22282297 deployVmData .templateid = values .templateid
22292298 values .hypervisor = null
2299+ } else if (this .imageType === ' volumeid' ) {
2300+ deployVmData .volumeid = values .volumeid
2301+ } else if (this .imageType === ' snapshotid' ) {
2302+ deployVmData .snapshotid = values .snapshotid
22302303 } else {
22312304 deployVmData .templateid = values .isoid
22322305 }
@@ -2599,6 +2672,88 @@ export default {
25992672 })
26002673 })
26012674 },
2675+ fetchUnattachedVolumes (volumeFilter , params ) {
2676+ const args = Object .assign ({}, params)
2677+ if (args .keyword || (args .category && args .category !== volumeFilter)) {
2678+ args .page = 1
2679+ args .pageSize = args .pageSize || 10
2680+ }
2681+ args .zoneid = _ .get (this .zone , ' id' )
2682+ if (this .isZoneSelectedMultiArch ) {
2683+ args .arch = this .selectedArchitecture
2684+ }
2685+ args .account = store .getters .project ? .id ? null : this .owner .account
2686+ args .domainid = store .getters .project ? .id ? null : this .owner .domainid
2687+ args .projectid = store .getters .project ? .id || this .owner .projectid
2688+ args .id = this .queryVolumeId
2689+ args .state = ' Ready'
2690+ const pageSize = args .pageSize ? args .pageSize : 10
2691+ const pageStart = (args .page ? args .page - 1 : 0 ) * pageSize
2692+ const pageEnd = pageSize * (pageStart + 1 )
2693+
2694+ delete args .category
2695+ delete args .public
2696+ delete args .featured
2697+ delete args .page
2698+ delete args .pageSize
2699+
2700+ return new Promise ((resolve , reject ) => {
2701+ getAPI (' listVolumes' , args).then ((response ) => {
2702+ let count = 0
2703+ const volumes = []
2704+ response .listvolumesresponse .volume .forEach (volume => {
2705+ if (! volume .virtualmachineid ) {
2706+ count += 1
2707+ volumes .push ({ ... volume, displaytext: volume .name })
2708+ }
2709+ })
2710+ resolve ({ listvolumesresponse: { count, volume: volumes .slice (pageStart, pageEnd) } })
2711+ }).catch ((reason ) => {
2712+ // ToDo: Handle errors
2713+ reject (reason)
2714+ })
2715+ })
2716+ },
2717+ fetchRootSnapshots (snapshotFilter , params ) {
2718+ const args = Object .assign ({}, params)
2719+ if (args .keyword || (args .category && args .category !== snapshotFilter)) {
2720+ args .page = 1
2721+ args .pageSize = args .pageSize || 10
2722+ }
2723+ args .zoneid = _ .get (this .zone , ' id' )
2724+ if (this .isZoneSelectedMultiArch ) {
2725+ args .arch = this .selectedArchitecture
2726+ }
2727+ args .account = store .getters .project ? .id ? null : this .owner .account
2728+ args .domainid = store .getters .project ? .id ? null : this .owner .domainid
2729+ args .projectid = store .getters .project ? .id || this .owner .projectid
2730+ const pageSize = args .pageSize ? args .pageSize : 10
2731+ const pageStart = (args .page ? args .page - 1 : 0 ) * pageSize
2732+ const pageEnd = pageSize * (pageStart + 1 )
2733+
2734+ delete args .category
2735+ delete args .public
2736+ delete args .featured
2737+ delete args .page
2738+ delete args .pageSize
2739+
2740+ return new Promise ((resolve , reject ) => {
2741+ getAPI (' listSnapshots' , args).then ((response ) => {
2742+ let count = 0
2743+ const snapshots = []
2744+ response .listsnapshotsresponse .snapshot .forEach (snapshot => {
2745+ if (snapshot .volumetype === ' ROOT' ) {
2746+ count += 1
2747+ snapshots .push ({ ... snapshot, displaytext: snapshot .name })
2748+ }
2749+ })
2750+ resolve ({ listsnapshotsresponse: { count, snapshot: snapshots .slice (pageStart, pageEnd) } })
2751+ }).catch ((reason ) => {
2752+ // ToDo: Handle errors
2753+ reject (reason)
2754+ })
2755+ })
2756+ },
26022757 fetchTemplates (templateFilter , params ) {
26032758 const args = Object .assign ({}, params)
26042759 if (this .isModernImageSelection && this .form .guestoscategoryid && ! [' -1' , ' 0' ].includes (this .form .guestoscategoryid )) {
@@ -2678,6 +2833,14 @@ export default {
26782833 this .fetchAllIsos (params)
26792834 return
26802835 }
2836+ if (this .imageType === ' volumeid' ) {
2837+ this .fetchAllVolumes (params)
2838+ return
2839+ }
2840+ if (this .imageType === ' snapshotid' ) {
2841+ this .fetchAllSnapshots (params)
2842+ return
2843+ }
26812844 this .fetchAllTemplates (params)
26822845 },
26832846 fetchAllTemplates (params ) {
@@ -2724,6 +2887,50 @@ export default {
27242887 this .loading .isos = false
27252888 })
27262889 },
2890+ fetchAllVolumes (params ) {
2891+ const promises = []
2892+ const volumes = {}
2893+ this .loading .volumes = true
2894+ this .imageSearchFilters = params
2895+ const volumeFilters = this .getImageFilters (params)
2896+ volumeFilters .forEach ((filter ) => {
2897+ volumes[filter] = { count: 0 , volume: [] }
2898+ promises .push (this .fetchUnattachedVolumes (filter, params))
2899+ })
2900+ this .options .volumes = volumes
2901+ Promise .all (promises).then ((response ) => {
2902+ response .forEach ((resItem , idx ) => {
2903+ volumes[volumeFilters[idx]] = _ .isEmpty (resItem .listvolumesresponse ) ? { count: 0 , volume: [] } : resItem .listvolumesresponse
2904+ this .options .volumes = { ... volumes }
2905+ })
2906+ }).catch ((reason ) => {
2907+ console .log (reason)
2908+ }).finally (() => {
2909+ this .loading .volumes = false
2910+ })
2911+ },
2912+ fetchAllSnapshots (params ) {
2913+ const promises = []
2914+ const snapshots = {}
2915+ this .loading .snapshots = true
2916+ this .imageSearchFilters = params
2917+ const snapshotFilters = this .getImageFilters (params)
2918+ snapshotFilters .forEach ((filter ) => {
2919+ snapshots[filter] = { count: 0 , snapshot: [] }
2920+ promises .push (this .fetchRootSnapshots (filter, params))
2921+ })
2922+ this .options .snapshots = snapshots
2923+ Promise .all (promises).then ((response ) => {
2924+ response .forEach ((resItem , idx ) => {
2925+ snapshots[snapshotFilters[idx]] = _ .isEmpty (resItem .listsnapshotsresponse ) ? { count: 0 , snapshot: [] } : resItem .listsnapshotsresponse
2926+ this .options .snapshots = { ... snapshots }
2927+ })
2928+ }).catch ((reason ) => {
2929+ console .log (reason)
2930+ }).finally (() => {
2931+ this .loading .snapshots = false
2932+ })
2933+ },
27272934 filterOption (input , option ) {
27282935 return option .label .toUpperCase ().indexOf (input .toUpperCase ()) >= 0
27292936 },
@@ -2830,7 +3037,7 @@ export default {
28303037 }
28313038 },
28323039 updateImages () {
2833- if (this .isModernImageSelection ) {
3040+ if (this .isModernImageSelection && this . imageType !== ' snapshotid ' && this . imageType !== ' volumeid ' ) {
28343041 this .fetchGuestOsCategories ()
28353042 return
28363043 }
0 commit comments