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 >
@@ -979,6 +985,8 @@ export default {
979985 },
980986 options: {
981987 guestOsCategories: [],
988+ volumes: {},
989+ snapshots: {},
982990 templates: {},
983991 isos: {},
984992 hypervisors: [],
@@ -1003,6 +1011,8 @@ export default {
10031011 loading: {
10041012 deploy: false ,
10051013 guestOsCategories: false ,
1014+ volumes: false ,
1015+ snapshots: false ,
10061016 templates: false ,
10071017 isos: false ,
10081018 hypervisors: false ,
@@ -1381,6 +1391,12 @@ export default {
13811391 queryArchId () {
13821392 return this .$route .query .arch || null
13831393 },
1394+ querySnapshotId () {
1395+ return this .$route .query .snapshotid | null
1396+ },
1397+ queryVolumeId () {
1398+ return this .$route .query .volumeid || null
1399+ },
13841400 queryTemplateId () {
13851401 return this .$route .query .templateid || null
13861402 },
@@ -1923,6 +1939,8 @@ export default {
19231939 this .imageType = ' templateid'
19241940 this .form .templateid = value
19251941 this .form .isoid = null
1942+ this .form .volumeid = null
1943+ this .form .snapshotid = null
19261944 this .resetFromTemplateConfiguration ()
19271945 let template = ' '
19281946 for (const entry of Object .values (this .options .templates )) {
@@ -1958,6 +1976,8 @@ export default {
19581976 this .resetFromTemplateConfiguration ()
19591977 this .form .isoid = value
19601978 this .form .templateid = null
1979+ this .form .volumeid = null
1980+ this .form .snapshotid = null
19611981 let iso = null
19621982 for (const entry of Object .values (this .options .isos )) {
19631983 iso = entry? .iso .find (option => option .id === value)
@@ -1970,6 +1990,46 @@ export default {
19701990 this .updateTemplateLinkedUserData (this .iso .userdataid )
19711991 this .userdataDefaultOverridePolicy = this .iso .userdatapolicy
19721992 }
1993+ } else if (name === ' volumeid' ) {
1994+ this .imageType = ' volumeid'
1995+ this .resetTemplateAssociatedResources ()
1996+ this .resetFromTemplateConfiguration ()
1997+ this .form .templateid = null
1998+ this .form .isoid = null
1999+ this .form .volumeid = value
2000+ this .form .snapshotid = null
2001+ let volume = null
2002+ for (const entry of Object .values (this .options .volumes )) {
2003+ volume = entry? .volume .find (option => option .id === value)
2004+ if (volume) {
2005+ this .volume = volume
2006+ break
2007+ }
2008+ }
2009+ if (volume) {
2010+ this .updateTemplateLinkedUserData (this .volume .userdataid )
2011+ this .userdataDefaultOverridePolicy = this .volume .userdatapolicy
2012+ }
2013+ } else if (name === ' snapshotid' ) {
2014+ this .imageType = ' snapshotid'
2015+ this .resetTemplateAssociatedResources ()
2016+ this .resetFromTemplateConfiguration ()
2017+ this .form .templateid = null
2018+ this .form .isoid = null
2019+ this .form .volumeid = null
2020+ this .form .snapshotid = value
2021+ let snapshot = null
2022+ for (const entry of Object .values (this .options .snapshots )) {
2023+ snapshot = entry? .snapshot .find (option => option .id === value)
2024+ if (snapshot) {
2025+ this .snapshot = snapshot
2026+ break
2027+ }
2028+ }
2029+ if (snapshot) {
2030+ this .updateTemplateLinkedUserData (this .snapshot .userdataid )
2031+ this .userdataDefaultOverridePolicy = this .snapshot .userdatapolicy
2032+ }
19732033 } else if ([' cpuspeed' , ' cpunumber' , ' memory' ].includes (name)) {
19742034 this .vm [name] = value
19752035 this .form [name] = value
@@ -2147,7 +2207,7 @@ export default {
21472207 if (this .loading .deploy ) return
21482208 this .formRef .value .validate ().then (async () => {
21492209 const values = toRaw (this .form )
2150- if (! values .templateid && ! values .isoid ) {
2210+ if (! values .templateid && ! values .isoid && ! values . volumeid && ! values . snapshotid ) {
21512211 this .$notification .error ({
21522212 message: this .$t (' message.request.failed' ),
21532213 description: this .$t (' message.template.iso' )
@@ -2203,6 +2263,10 @@ export default {
22032263 if (this .imageType === ' templateid' ) {
22042264 deployVmData .templateid = values .templateid
22052265 values .hypervisor = null
2266+ } else if (this .imageType === ' volumeid' ) {
2267+ deployVmData .volumeid = values .volumeid
2268+ } else if (this .imageType === ' snapshotid' ) {
2269+ deployVmData .snapshotid = values .snapshotid
22062270 } else {
22072271 deployVmData .templateid = values .isoid
22082272 }
@@ -2560,6 +2624,89 @@ export default {
25602624 })
25612625 })
25622626 },
2627+ fetchUnattachedVolumes (volumeFilter , params ) {
2628+ const args = Object .assign ({}, params)
2629+ if (this .isModernImageSelection && this .form .guestoscategoryid ) {
2630+ args .oscategoryid = this .form .guestoscategoryid
2631+ }
2632+ if (args .keyword || (args .category && args .category !== volumeFilter)) {
2633+ args .page = 1
2634+ args .pageSize = args .pageSize || 10
2635+ }
2636+ args .zoneid = _ .get (this .zone , ' id' )
2637+ if (this .isZoneSelectedMultiArch ) {
2638+ args .arch = this .selectedArchitecture
2639+ }
2640+ args .account = store .getters .project ? .id ? null : this .owner .account
2641+ args .domainid = store .getters .project ? .id ? null : this .owner .domainid
2642+ args .projectid = store .getters .project ? .id || this .owner .projectid
2643+ args .volumefilter = volumeFilter
2644+ args .details = ' all'
2645+ args .showicon = ' true'
2646+ args .id = this .queryVolumeId
2647+ args .isvnf = false
2648+
2649+ delete args .category
2650+ delete args .public
2651+ delete args .featured
2652+
2653+ return new Promise ((resolve , reject ) => {
2654+ getAPI (' listVolumes' , args).then ((response ) => {
2655+ const listvolumesresponse = { count: 0 , volume: [] }
2656+ response .listvolumesresponse .volume .forEach (volume => {
2657+ if (! volume .virtualmachineid && volume .state === ' Ready' ) {
2658+ listvolumesresponse .count += 1
2659+ listvolumesresponse .volume .push ({ ... volume, displaytext: volume .name })
2660+ }
2661+ })
2662+ resolve ({ listvolumesresponse })
2663+ }).catch ((reason ) => {
2664+ // ToDo: Handle errors
2665+ reject (reason)
2666+ })
2667+ })
2668+ },
2669+ fetchRootSnapshots (snapshotFilter , params ) {
2670+ const args = Object .assign ({}, params)
2671+ if (this .isModernImageSelection && this .form .guestoscategoryid ) {
2672+ args .oscategoryid = this .form .guestoscategoryid
2673+ }
2674+ if (args .keyword || (args .category && args .category !== snapshotFilter)) {
2675+ args .page = 1
2676+ args .pageSize = args .pageSize || 10
2677+ }
2678+ args .zoneid = _ .get (this .zone , ' id' )
2679+ if (this .isZoneSelectedMultiArch ) {
2680+ args .arch = this .selectedArchitecture
2681+ }
2682+ args .account = store .getters .project ? .id ? null : this .owner .account
2683+ args .domainid = store .getters .project ? .id ? null : this .owner .domainid
2684+ args .projectid = store .getters .project ? .id || this .owner .projectid
2685+ args .snapshotfilter = snapshotFilter
2686+ args .details = ' all'
2687+ args .showicon = ' true'
2688+ args .isvnf = false
2689+
2690+ delete args .category
2691+ delete args .public
2692+ delete args .featured
2693+
2694+ return new Promise ((resolve , reject ) => {
2695+ getAPI (' listSnapshots' , args).then ((response ) => {
2696+ const listsnapshotsresponse = { count: 0 , snapshot: [] }
2697+ response .listsnapshotsresponse .snapshot .forEach (snapshot => {
2698+ if (snapshot .volumetype === ' ROOT' ) {
2699+ listsnapshotsresponse .count += 1
2700+ listsnapshotsresponse .snapshot .push ({ ... snapshot, displaytext: snapshot .name })
2701+ }
2702+ })
2703+ resolve ({ listsnapshotsresponse })
2704+ }).catch ((reason ) => {
2705+ // ToDo: Handle errors
2706+ reject (reason)
2707+ })
2708+ })
2709+ },
25632710 fetchTemplates (templateFilter , params ) {
25642711 const args = Object .assign ({}, params)
25652712 if (this .isModernImageSelection && this .form .guestoscategoryid && ! [' -1' , ' 0' ].includes (this .form .guestoscategoryid )) {
@@ -2634,6 +2781,14 @@ export default {
26342781 this .fetchAllIsos (params)
26352782 return
26362783 }
2784+ if (this .imageType === ' volumeid' ) {
2785+ this .fetchAllVolumes (params)
2786+ return
2787+ }
2788+ if (this .imageType === ' snapshotid' ) {
2789+ this .fetchAllSnapshots (params)
2790+ return
2791+ }
26372792 this .fetchAllTemplates (params)
26382793 },
26392794 fetchAllTemplates (params ) {
@@ -2680,6 +2835,50 @@ export default {
26802835 this .loading .isos = false
26812836 })
26822837 },
2838+ fetchAllVolumes (params ) {
2839+ const promises = []
2840+ const volumes = {}
2841+ this .loading .volumes = true
2842+ this .imageSearchFilters = params
2843+ const volumeFilters = this .getImageFilters (params)
2844+ volumeFilters .forEach ((filter ) => {
2845+ volumes[filter] = { count: 0 , iso: [] }
2846+ promises .push (this .fetchUnattachedVolumes (filter, params))
2847+ })
2848+ this .options .volumes = volumes
2849+ Promise .all (promises).then ((response ) => {
2850+ response .forEach ((resItem , idx ) => {
2851+ volumes[volumeFilters[idx]] = _ .isEmpty (resItem .listvolumesresponse ) ? { count: 0 , volume: [] } : resItem .listvolumesresponse
2852+ this .options .volumes = { ... volumes }
2853+ })
2854+ }).catch ((reason ) => {
2855+ console .log (reason)
2856+ }).finally (() => {
2857+ this .loading .volumes = false
2858+ })
2859+ },
2860+ fetchAllSnapshots (params ) {
2861+ const promises = []
2862+ const snapshots = {}
2863+ this .loading .snapshots = true
2864+ this .imageSearchFilters = params
2865+ const snapshotFilters = this .getImageFilters (params)
2866+ snapshotFilters .forEach ((filter ) => {
2867+ snapshots[filter] = { count: 0 , iso: [] }
2868+ promises .push (this .fetchRootSnapshots (filter, params))
2869+ })
2870+ this .options .snapshots = snapshots
2871+ Promise .all (promises).then ((response ) => {
2872+ response .forEach ((resItem , idx ) => {
2873+ snapshots[snapshotFilters[idx]] = _ .isEmpty (resItem .listsnapshotsresponse ) ? { count: 0 , snapshot: [] } : resItem .listsnapshotsresponse
2874+ this .options .snapshots = { ... snapshots }
2875+ })
2876+ }).catch ((reason ) => {
2877+ console .log (reason)
2878+ }).finally (() => {
2879+ this .loading .snapshots = false
2880+ })
2881+ },
26832882 filterOption (input , option ) {
26842883 return option .label .toUpperCase ().indexOf (input .toUpperCase ()) >= 0
26852884 },
0 commit comments