| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| (function(cloudStack) { |
| var migrateVolumeCreateFormAction = { |
| title: 'label.migrate.volume', |
| fields: { |
| storagePool: { |
| label: 'label.storage.pool', |
| validation: { |
| required: true |
| }, |
| select: function(args) { |
| var mapStoragePoolsByUuid = new Map(); |
| var volumeId = args.context.volumes[0].id; |
| var volumeBeingMigrated = undefined; |
| $.ajax({ |
| url: createURL("listVolumes&id=" + volumeId), |
| dataType: "json", |
| async: false, |
| success: function(json){ |
| volumeBeingMigrated = json.listvolumesresponse.volume[0]; |
| } |
| }); |
| var currentStoragePool = undefined; |
| $.ajax({ |
| url: createURL("listStoragePools&id=" + volumeBeingMigrated.storageid), |
| dataType: "json", |
| async: false, |
| success: function(json){ |
| currentStoragePool = json.liststoragepoolsresponse.storagepool[0]; |
| } |
| }); |
| var isVolumeNotAttachedToVm = volumeBeingMigrated.virtualmachineid == undefined; |
| var urlToRetrieveStoragePools = "findStoragePoolsForMigration&id=" + args.context.volumes[0].id; |
| if(isVolumeNotAttachedToVm){ |
| urlToRetrieveStoragePools = "listStoragePools&zoneid=" + args.context.volumes[0].zoneid; |
| } |
| $.ajax({ |
| url: createURL(urlToRetrieveStoragePools), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var pools = undefined; |
| if(isVolumeNotAttachedToVm){ |
| pools = json.liststoragepoolsresponse.storagepool; |
| }else{ |
| pools = json.findstoragepoolsformigrationresponse.storagepool; |
| } |
| var items = []; |
| $(pools).each(function() { |
| mapStoragePoolsByUuid.set(this.id, this); |
| var description = this.name; |
| if(!isVolumeNotAttachedToVm){ |
| description = description + " (" + (this.suitableformigration ? "Suitable" : "Not Suitable") + ")"; |
| } |
| items.push({ |
| id: this.id, |
| description: description |
| }); |
| }); |
| args.response.success({ |
| data: items |
| }); |
| var diskOfferings = cloudStack.listDiskOfferings({listAll: true}); |
| $('select[name=storagePool]').change(function(){ |
| var uuidOfStoragePoolSelected = $(this).val(); |
| var storagePoolSelected = mapStoragePoolsByUuid.get(uuidOfStoragePoolSelected); |
| if(currentStoragePool.scope === storagePoolSelected.scope){ |
| $('div[rel=newDiskOffering],div[rel=useNewDiskOffering]').hide(); |
| }else{ |
| $('div[rel=newDiskOffering],div[rel=useNewDiskOffering]').show(); |
| } |
| var storageType = 'shared'; |
| if(storagePoolSelected.scope == 'HOST'){ |
| storageType = 'local'; |
| } |
| $(diskOfferings).each(function(){ |
| var diskOfferingOption = $('option[value=' + this.id + ']'); |
| if(this.storagetype == storageType){ |
| diskOfferingOption.show(); |
| }else{ |
| diskOfferingOption.hide(); |
| } |
| }); |
| var firstAvailableDiskOfferingForStorageType = $('select#label_disk_newOffering').children('option:visible').first().attr('value'); |
| $('select#label_disk_newOffering').attr('value', firstAvailableDiskOfferingForStorageType); |
| }); |
| var functionHideShowNewDiskOfferint = function(){ |
| if($('div[rel=useNewDiskOffering] input[type=checkbox]').is(':checked')){ |
| $('div[rel=newDiskOffering]').show(); |
| }else{ |
| $('div[rel=newDiskOffering]').hide(); |
| } |
| }; |
| $('div[rel=useNewDiskOffering] input[type=checkbox]').click(functionHideShowNewDiskOfferint); |
| $('select[name=storagePool]').change(); |
| functionHideShowNewDiskOfferint(); |
| } |
| }); |
| } |
| }, |
| useNewDiskOffering:{ |
| label: 'label.migrate.volume.newDiskOffering', |
| desc: 'label.migrate.volume.newDiskOffering.desc', |
| validation: { |
| required: false |
| }, |
| isEditable: true, |
| isBoolean: true, |
| defaultValue: 'Yes' |
| }, |
| newDiskOffering: { |
| label: 'label.disk.newOffering', |
| desc: 'label.disk.newOffering.description', |
| validation: { |
| required: false |
| }, |
| select: function(args){ |
| var diskOfferings = cloudStack.listDiskOfferings({listAll: true}); |
| var items = []; |
| $(diskOfferings).each(function() { |
| items.push({ |
| id: this.id, |
| description: this.name |
| }); |
| }); |
| args.response.success({ |
| data: items |
| }); |
| } |
| } |
| } |
| }; |
| var functionMigrateVolume = function(args) { |
| var volumeBeingMigrated = args.context.volumes[0]; |
| var isLiveMigrate = volumeBeingMigrated.vmstate == 'Running'; |
| var migrateVolumeUrl = "migrateVolume&livemigrate="+ isLiveMigrate +"&storageid=" + args.data.storagePool + "&volumeid=" + volumeBeingMigrated.id; |
| if($('div[rel=useNewDiskOffering] input[name=useNewDiskOffering]:checkbox').is(':checked')){ |
| migrateVolumeUrl = migrateVolumeUrl + '&newdiskofferingid=' + $('div[rel=newDiskOffering] select').val(); |
| } |
| $.ajax({ |
| url: createURL(migrateVolumeUrl), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| $(window).trigger('cloudStack.fullRefresh'); |
| var jid = json.migratevolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| } |
| |
| var diskOfferingsObjList, selectedDiskOfferingObj = null; |
| |
| cloudStack.sections.storage = { |
| title: 'label.storage', |
| id: 'storage', |
| sectionSelect: { |
| label: 'label.select-view' |
| }, |
| sections: { |
| /** |
| * Volumes |
| */ |
| volumes: { |
| type: 'select', |
| title: 'label.volumes', |
| listView: { |
| id: 'volumes', |
| label: 'label.volumes', |
| preFilter: function(args) { |
| var hiddenFields = []; |
| if (isAdmin() != true) { |
| hiddenFields.push('hypervisor'); |
| hiddenFields.push('account'); |
| } |
| return hiddenFields; |
| }, |
| fields: { |
| name: { |
| label: 'label.name' |
| }, |
| type: { |
| label: 'label.type' |
| }, |
| vmdisplayname: { |
| label: 'label.vm.display.name' |
| }, |
| hypervisor: { |
| label: 'label.hypervisor' |
| }, |
| account: { |
| label: 'label.account' |
| }, |
| zonename: { |
| label: 'label.zone' |
| }, |
| vmdisplayname: { |
| label: 'label.vm.display.name' |
| }, |
| state: { |
| label: 'label.metrics.state', |
| converter: function (str) { |
| // For localization |
| return str; |
| }, |
| indicator: { |
| 'Allocated': 'on', |
| 'Ready': 'on', |
| 'Destroy': 'off', |
| 'Expunging': 'off', |
| 'Expunged': 'off', |
| 'Migrating': 'warning', |
| 'UploadOp': 'warning', |
| 'Snapshotting': 'warning', |
| } |
| } |
| }, |
| |
| // List view actions |
| actions: { |
| // Add volume |
| add: { |
| label: 'label.add', |
| |
| preFilter: function(args) { |
| return !args.context.instances; |
| }, |
| |
| messages: { |
| confirm: function(args) { |
| return 'message.add.volume'; |
| }, |
| notification: function(args) { |
| return 'label.add.volume'; |
| } |
| }, |
| |
| createForm: { |
| title: 'label.add.volume', |
| desc: 'message.add.volume', |
| fields: { |
| name: { |
| docID: 'helpVolumeName', |
| label: 'label.name' |
| }, |
| availabilityZone: { |
| label: 'label.availability.zone', |
| docID: 'helpVolumeAvailabilityZone', |
| select: function(args) { |
| $.ajax({ |
| url: createURL("listZones&available=true"), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var zoneObjs = json.listzonesresponse.zone; |
| args.response.success({ |
| descriptionField: 'name', |
| data: zoneObjs |
| }); |
| } |
| }); |
| args.$select.change(function() { |
| var diskOfferingSelect = $(this).closest('form').find('select[name=diskOffering]'); |
| if(diskOfferingSelect) { |
| $(diskOfferingSelect).find('option').remove().end(); |
| var data = { |
| zoneid: $(this).val(), |
| }; |
| console.log(data); |
| var diskOfferings = cloudStack.listDiskOfferings({ data: data }); |
| diskOfferingsObjList = diskOfferings; |
| $(diskOfferings).each(function() { |
| $(diskOfferingSelect).append(new Option(this.displaytext, this.id)); |
| }); |
| } |
| }); |
| } |
| }, |
| diskOffering: { |
| label: 'label.disk.offering', |
| docID: 'helpVolumeDiskOffering', |
| select: function(args) { |
| var diskOfferings = cloudStack.listDiskOfferings({}); |
| diskOfferingsObjList = diskOfferings; |
| var items = []; |
| $(diskOfferings).each(function() { |
| items.push({ |
| id: this.id, |
| description: this.displaytext |
| }); |
| }); |
| args.response.success({ |
| data: items |
| }); |
| args.$select.change(function() { |
| var diskOfferingId = $(this).val(); |
| $(diskOfferingsObjList).each(function() { |
| if (this.id == diskOfferingId) { |
| selectedDiskOfferingObj = this; |
| return false; //break the $.each() loop |
| } |
| }); |
| if (selectedDiskOfferingObj == null){ |
| return; |
| } |
| var $form = $(this).closest('form'); |
| var $diskSize = $form.find('.form-item[rel=diskSize]'); |
| if (selectedDiskOfferingObj.iscustomized == true) { |
| $diskSize.css('display', 'inline-block'); |
| } else { |
| $diskSize.hide(); |
| } |
| var $minIops = $form.find('.form-item[rel=minIops]'); |
| var $maxIops = $form.find('.form-item[rel=maxIops]'); |
| if (selectedDiskOfferingObj.iscustomizediops == true) { |
| $minIops.css('display', 'inline-block'); |
| $maxIops.css('display', 'inline-block'); |
| } else { |
| $minIops.hide(); |
| $maxIops.hide(); |
| } |
| }); |
| } |
| } |
| |
| , |
| diskSize: { |
| label: 'label.disk.size.gb', |
| docID: 'helpVolumeSizeGb', |
| validation: { |
| required: true, |
| number: true |
| }, |
| isHidden: true |
| }, |
| |
| minIops: { |
| label: 'label.disk.iops.min', |
| validation: { |
| required: false, |
| number: true |
| }, |
| isHidden: true |
| }, |
| |
| maxIops: { |
| label: 'label.disk.iops.max', |
| validation: { |
| required: false, |
| number: true |
| }, |
| isHidden: true |
| } |
| |
| } |
| }, |
| |
| action: function(args) { |
| var data = { |
| name: args.data.name, |
| zoneId: args.data.availabilityZone, |
| diskOfferingId: args.data.diskOffering |
| }; |
| |
| // if(thisDialog.find("#size_container").css("display") != "none") { //wait for Brian to include $form in args |
| if (selectedDiskOfferingObj.iscustomized == true) { |
| $.extend(data, { |
| size: args.data.diskSize |
| }); |
| } |
| |
| if (selectedDiskOfferingObj.iscustomizediops == true) { |
| if (args.data.minIops != "" && args.data.minIops > 0) { |
| $.extend(data, { |
| miniops: args.data.minIops |
| }); |
| } |
| |
| if (args.data.maxIops != "" && args.data.maxIops > 0) { |
| $.extend(data, { |
| maxiops: args.data.maxIops |
| }); |
| } |
| } |
| |
| $.ajax({ |
| url: createURL('createVolume'), |
| data: data, |
| success: function(json) { |
| var jid = json.createvolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, |
| getUpdatedItem: function(json) { |
| return json.queryasyncjobresultresponse.jobresult.volume; |
| }, |
| getActionFilter: function() { |
| return volumeActionfilter; |
| } |
| } |
| }); |
| }, |
| error: function(json) { |
| args.response.error(parseXMLHttpResponse(json)); |
| } |
| }); |
| }, |
| |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| viewMetrics: { |
| label: 'label.metrics', |
| isHeader: true, |
| addRow: false, |
| action: { |
| custom: cloudStack.uiCustom.metricsView({resource: 'volumes'}) |
| }, |
| messages: { |
| notification: function (args) { |
| return 'label.metrics'; |
| } |
| } |
| }, |
| |
| uploadVolume: { |
| isHeader: true, |
| label: 'label.upload', |
| preFilter: function(args) { |
| return !args.context.instances; |
| }, |
| messages: { |
| notification: function() { |
| return 'label.upload.volume.from.url'; |
| } |
| }, |
| createForm: { |
| title: 'label.upload.volume.from.url', |
| fields: { |
| url: { |
| label: 'label.url', |
| docID: 'helpUploadVolumeURL', |
| validation: { |
| required: true |
| } |
| }, |
| name: { |
| label: 'label.name', |
| validation: { |
| required: true |
| }, |
| docID: 'helpUploadVolumeName' |
| }, |
| availabilityZone: { |
| label: 'label.availability.zone', |
| docID: 'helpUploadVolumeZone', |
| select: function(args) { |
| $.ajax({ |
| url: createURL("listZones&available=true"), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var zoneObjs = json.listzonesresponse.zone; |
| args.response.success({ |
| descriptionField: 'name', |
| data: zoneObjs |
| }); |
| } |
| }); |
| } |
| }, |
| format: { |
| label: 'label.format', |
| docID: 'helpUploadVolumeFormat', |
| select: function(args) { |
| var items = []; |
| items.push({ |
| id: 'RAW', |
| description: 'RAW' |
| }); |
| items.push({ |
| id: 'VHD', |
| description: 'VHD' |
| }); |
| items.push({ |
| id: 'VHDX', |
| description: 'VHDX' |
| }); |
| items.push({ |
| id: 'OVA', |
| description: 'OVA' |
| }); |
| items.push({ |
| id: 'QCOW2', |
| description: 'QCOW2' |
| }); |
| args.response.success({ |
| data: items |
| }); |
| } |
| |
| }, |
| diskOffering: { |
| label: 'label.custom.disk.offering', |
| docID: 'helpVolumeDiskOffering', |
| select: function(args) { |
| var diskOfferings = cloudStack.listDiskOfferings({}); |
| var items = [{ |
| id: '', |
| description: '' |
| }]; |
| $(diskOfferings).each(function() { |
| if (this.iscustomized == true) { |
| items.push({ |
| id: this.id, |
| description: this.name |
| }); |
| } |
| }); |
| args.response.success({ |
| data: items |
| }); |
| } |
| }, |
| checksum: { |
| docID: 'helpUploadVolumeChecksum', |
| label: 'label.md5.checksum' |
| } |
| } |
| }, |
| |
| action: function(args) { |
| var data = { |
| name: args.data.name, |
| zoneId: args.data.availabilityZone, |
| format: args.data.format, |
| url: args.data.url |
| }; |
| |
| if (args.data.diskOffering != '' && args.data.diskOffering.length > 0) { |
| $.extend(data, { |
| diskofferingid: args.data.diskOffering |
| }); |
| } |
| |
| if (args.data.checksum != null && args.data.checksum.length > 0) { |
| $.extend(data, { |
| checksum: args.data.checksum |
| }); |
| } |
| |
| $.ajax({ |
| url: createURL('uploadVolume'), |
| data: data, |
| success: function(json) { |
| var jid = json.uploadvolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, |
| getUpdatedItem: function(json) { |
| return json.queryasyncjobresultresponse.jobresult.volume; |
| }, |
| getActionFilter: function() { |
| return volumeActionfilter; |
| } |
| } |
| }); |
| }, |
| error: function(json) { |
| args.response.error(parseXMLHttpResponse(json)); |
| } |
| }); |
| }, |
| |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| uploadVolumefromLocal: { |
| isHeader: true, |
| label: 'label.upload.from.local', |
| preFilter: function(args) { |
| return !args.context.instances; |
| }, |
| messages: { |
| notification: function() { |
| return 'label.upload.volume.from.local'; |
| } |
| }, |
| createForm: { |
| title: 'label.upload.volume.from.local', |
| fileUpload: { |
| getURL: function(args) { |
| args.data = args.formData; |
| |
| var data = { |
| name: args.data.name, |
| zoneId: args.data.availabilityZone, |
| format: args.data.format, |
| url: args.data.url |
| }; |
| |
| if (args.data.checksum != null && args.data.checksum.length > 0) { |
| $.extend(data, { |
| checksum: args.data.checksum |
| }); |
| } |
| |
| $.ajax({ |
| url: createURL('getUploadParamsForVolume'), |
| data: data, |
| async: false, |
| success: function(json) { |
| var uploadparams = json.postuploadvolumeresponse.getuploadparams; //son.postuploadvolumeresponse.getuploadparams is an object, not an array of object. |
| var volumeId = uploadparams.id; |
| |
| args.response.success({ |
| url: uploadparams.postURL, |
| ajaxPost: true, |
| data: { |
| 'X-signature': uploadparams.signature, |
| 'X-expires': uploadparams.expires, |
| 'X-metadata': uploadparams.metadata |
| } |
| }); |
| } |
| }); |
| }, |
| postUpload: function(args) { |
| if(args.error) { |
| args.response.error(args.errorMsg); |
| } else { |
| cloudStack.dialog.notice({ |
| message: "This volume file has been uploaded. Please check its status at Stroage menu > Volumes > " + args.data.name + " > Status field." |
| }); |
| args.response.success(); |
| } |
| } |
| }, |
| fields: { |
| volumeFileUpload: { |
| label: 'label.local.file', |
| isFileUpload: true, |
| validation: { |
| required: true |
| } |
| }, |
| name: { |
| label: 'label.name', |
| validation: { |
| required: true |
| }, |
| docID: 'helpUploadVolumeName' |
| }, |
| availabilityZone: { |
| label: 'label.availability.zone', |
| docID: 'helpUploadVolumeZone', |
| select: function(args) { |
| $.ajax({ |
| url: createURL("listZones&available=true"), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var zoneObjs = json.listzonesresponse.zone; |
| args.response.success({ |
| descriptionField: 'name', |
| data: zoneObjs |
| }); |
| } |
| }); |
| } |
| }, |
| format: { |
| label: 'label.format', |
| docID: 'helpUploadVolumeFormat', |
| select: function(args) { |
| var items = []; |
| items.push({ |
| id: 'RAW', |
| description: 'RAW' |
| }); |
| items.push({ |
| id: 'VHD', |
| description: 'VHD' |
| }); |
| items.push({ |
| id: 'VHDX', |
| description: 'VHDX' |
| }); |
| items.push({ |
| id: 'OVA', |
| description: 'OVA' |
| }); |
| items.push({ |
| id: 'QCOW2', |
| description: 'QCOW2' |
| }); |
| args.response.success({ |
| data: items |
| }); |
| } |
| }, |
| checksum: { |
| docID: 'helpUploadVolumeChecksum', |
| label: 'label.md5.checksum' |
| } |
| } |
| }, |
| |
| action: function(args) { |
| return; //createForm.fileUpload.getURL() has executed the whole action. Therefore, nothing needs to be done here. |
| }, |
| |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| } |
| }, |
| |
| advSearchFields: { |
| name: { |
| label: 'label.name' |
| }, |
| zoneid: { |
| label: 'label.zone', |
| select: function(args) { |
| $.ajax({ |
| url: createURL('listZones'), |
| data: {}, |
| success: function(json) { |
| var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : []; |
| |
| args.response.success({ |
| data: $.map(zones, function(zone) { |
| return { |
| id: zone.id, |
| description: zone.name |
| }; |
| }) |
| }); |
| } |
| }); |
| } |
| }, |
| |
| domainid: { |
| label: 'label.domain', |
| select: function(args) { |
| if (isAdmin() || isDomainAdmin()) { |
| $.ajax({ |
| url: createURL('listDomains'), |
| data: { |
| listAll: true, |
| details: 'min' |
| }, |
| success: function(json) { |
| var array1 = [{ |
| id: '', |
| description: '' |
| }]; |
| var domains = json.listdomainsresponse.domain; |
| if (domains != null && domains.length > 0) { |
| for (var i = 0; i < domains.length; i++) { |
| array1.push({ |
| id: domains[i].id, |
| description: domains[i].path |
| }); |
| } |
| } |
| array1.sort(function(a, b) { |
| return a.description.localeCompare(b.description); |
| }); |
| args.response.success({ |
| data: array1 |
| }); |
| } |
| }); |
| } else { |
| args.response.success({ |
| data: null |
| }); |
| } |
| }, |
| isHidden: function(args) { |
| if (isAdmin() || isDomainAdmin()) |
| return false; |
| else |
| return true; |
| } |
| }, |
| |
| account: { |
| label: 'label.account', |
| isHidden: function(args) { |
| if (isAdmin() || isDomainAdmin()) |
| return false; |
| else |
| return true; |
| } |
| }, |
| |
| state: { |
| label: 'label.state', |
| select: function(args) { |
| args.response.success({ |
| data: [{ |
| name: '', |
| description: '' |
| }, { |
| name: 'Allocated', |
| description: 'state.Allocated' |
| }, { |
| name: 'Ready', |
| description: 'state.Ready' |
| }, { |
| name: 'Destroy', |
| description: 'state.Destroy' |
| }, { |
| name: 'Expunging', |
| description: 'state.Expunging' |
| }, { |
| name: 'Expunged', |
| description: 'state.Expunged' |
| }] |
| }); |
| } |
| }, |
| |
| tagKey: { |
| label: 'label.tag.key' |
| }, |
| tagValue: { |
| label: 'label.tag.value' |
| } |
| }, |
| |
| dataProvider: function(args) { |
| var data = {}; |
| listViewDataProvider(args, data); |
| |
| if (args.context != null) { |
| if ("instances" in args.context) { |
| $.extend(data, { |
| virtualMachineId: args.context.instances[0].id |
| }); |
| } |
| if ("primarystorages" in args.context) { |
| $.extend(data, { |
| storageid: args.context.primarystorages[0].id |
| }); |
| } |
| } |
| |
| $.ajax({ |
| url: createURL('listVolumes'), |
| data: data, |
| success: function(json) { |
| var items = json.listvolumesresponse.volume; |
| args.response.success({ |
| actionFilter: volumeActionfilter, |
| data: items |
| }); |
| }, |
| error: function(XMLHttpResponse) { |
| cloudStack.dialog.notice({ |
| message: parseXMLHttpResponse(XMLHttpResponse) |
| }); |
| args.response.error(); |
| } |
| }); |
| }, |
| |
| detailView: { |
| name: 'label.volume.details', |
| viewAll: { |
| path: 'storage.snapshots', |
| label: 'label.snapshots' |
| }, |
| actions: { |
| migrateVolume: { |
| label: 'label.migrate.volume', |
| messages: { |
| confirm: function(args) { |
| return 'message.confirm.migrate.volume'; |
| }, |
| notification: function(args) { |
| return 'label.volume.migrated'; |
| } |
| }, |
| |
| createForm: migrateVolumeCreateFormAction, |
| |
| action: functionMigrateVolume, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| |
| }, |
| |
| takeSnapshot: { |
| label: 'label.action.take.snapshot', |
| messages: { |
| notification: function(args) { |
| return 'label.action.take.snapshot'; |
| } |
| }, |
| createForm: { |
| title: 'label.action.take.snapshot', |
| desc: 'message.action.take.snapshot', |
| fields: { |
| quiescevm: { |
| label: 'label.quiesce.vm', |
| isBoolean: true, |
| isHidden: function(args) { |
| if (args.context.volumes[0].quiescevm == true) |
| return false; |
| else |
| return true; |
| } |
| }, |
| name: { |
| label: 'label.name' |
| }, |
| asyncBackup: { |
| label: 'label.async.backup', |
| isBoolean: true |
| }, |
| tags: { |
| label: 'label.tags', |
| tagger: true |
| } |
| } |
| }, |
| action: function(args) { |
| var data = { |
| volumeId: args.context.volumes[0].id, |
| quiescevm: (args.data.quiescevm == 'on' ? true: false), |
| asyncBackup: (args.data.asyncBackup == 'on' ? true: false) |
| }; |
| if (args.data.name != null && args.data.name.length > 0) { |
| $.extend(data, { |
| name: args.data.name |
| }); |
| } |
| if (!$.isEmptyObject(args.data.tags)) { |
| $(args.data.tags).each(function(idx, tagData) { |
| var formattedTagData = {}; |
| formattedTagData["tags[" + _s(idx) + "].key"] = _s(tagData.key); |
| formattedTagData["tags[" + _s(idx) + "].value"] = _s(tagData.value); |
| $.extend(data, formattedTagData); |
| }); |
| } |
| |
| $.ajax({ |
| url: createURL("createSnapshot"), |
| data: data, |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.createsnapshotresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, //take snapshot from a volume doesn't change any property in this volume. So, don't need to specify getUpdatedItem() to return updated volume. Besides, createSnapshot API doesn't return updated volume. |
| onComplete: function(json, customData) { |
| var volumeId = json.queryasyncjobresultresponse.jobresult.snapshot.volumeid; |
| var snapshotId = json.queryasyncjobresultresponse.jobresult.snapshot.id; |
| cloudStack.dialog.notice({ |
| message: "Created snapshot for volume " + volumeId + " with snapshot ID " + snapshotId |
| }); |
| } |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| recurringSnapshot: { |
| label: 'label.snapshot.schedule', |
| action: { |
| custom: cloudStack.uiCustom.recurringSnapshots({ |
| desc: 'message.snapshot.schedule', |
| dataProvider: function(args) { |
| $.ajax({ |
| url: createURL('listSnapshotPolicies'), |
| data: { |
| volumeid: args.context.volumes[0].id |
| }, |
| async: true, |
| dataType: 'json', |
| success: function(data) { |
| args.response.success({ |
| data: $.map( |
| data.listsnapshotpoliciesresponse.snapshotpolicy ? data.listsnapshotpoliciesresponse.snapshotpolicy : [], |
| function(snapshot, index) { |
| return { |
| id: snapshot.id, |
| type: snapshot.intervaltype, |
| time: snapshot.intervaltype > 0 ? snapshot.schedule.split(':')[1] + ':' + snapshot.schedule.split(':')[0] : snapshot.schedule, |
| timezone: snapshot.timezone, |
| keep: snapshot.maxsnaps, |
| 'day-of-week': snapshot.intervaltype == 2 ? snapshot.schedule.split(':')[2] : null, |
| 'day-of-month': snapshot.intervaltype == 3 ? snapshot.schedule.split(':')[2] : null |
| }; |
| } |
| ) |
| }); |
| } |
| }); |
| }, |
| actions: { |
| add: function(args) { |
| var snap = args.snapshot; |
| |
| var data = { |
| volumeid: args.context.volumes[0].id, |
| intervaltype: snap['snapshot-type'], |
| maxsnaps: snap.maxsnaps, |
| timezone: snap.timezone |
| }; |
| |
| var convertTime = function(minute, hour, meridiem, extra) { |
| var convertedHour = meridiem == 'PM' ? |
| (hour != 12 ? parseInt(hour) + 12 : 12) : (hour != 12 ? hour : '00'); |
| var time = minute + ':' + convertedHour; |
| if (extra) time += ':' + extra; |
| |
| return time; |
| }; |
| |
| switch (snap['snapshot-type']) { |
| case 'hourly': // Hourly |
| $.extend(data, { |
| schedule: snap.schedule |
| }); |
| break; |
| |
| case 'daily': // Daily |
| $.extend(data, { |
| schedule: convertTime( |
| snap['time-minute'], |
| snap['time-hour'], |
| snap['time-meridiem'] |
| ) |
| }); |
| break; |
| |
| case 'weekly': // Weekly |
| $.extend(data, { |
| schedule: convertTime( |
| snap['time-minute'], |
| snap['time-hour'], |
| snap['time-meridiem'], |
| snap['day-of-week'] |
| ) |
| }); |
| break; |
| |
| case 'monthly': // Monthly |
| $.extend(data, { |
| schedule: convertTime( |
| snap['time-minute'], |
| snap['time-hour'], |
| snap['time-meridiem'], |
| snap['day-of-month'] |
| ) |
| }); |
| break; |
| } |
| |
| if (!$.isEmptyObject(snap.tags)) { |
| $(snap.tags).each(function(idx, tagData) { |
| var formattedTagData = {}; |
| formattedTagData["tags[" + _s(idx) + "].key"] = _s(tagData.key); |
| formattedTagData["tags[" + _s(idx) + "].value"] = _s(tagData.value); |
| $.extend(data, formattedTagData); |
| }); |
| } |
| |
| $.ajax({ |
| url: createURL('createSnapshotPolicy'), |
| data: data, |
| dataType: 'json', |
| async: true, |
| success: function(successData) { |
| var snapshot = successData.createsnapshotpolicyresponse.snapshotpolicy; |
| |
| args.response.success({ |
| data: { |
| id: snapshot.id, |
| type: snapshot.intervaltype, |
| time: snapshot.intervaltype > 0 ? snapshot.schedule.split(':')[1] + ':' + snapshot.schedule.split(':')[0] : snapshot.schedule, |
| timezone: snapshot.timezone, |
| keep: snapshot.maxsnaps, |
| 'day-of-week': snapshot.intervaltype == 2 ? snapshot.schedule.split(':')[2] : null, |
| 'day-of-month': snapshot.intervaltype == 3 ? snapshot.schedule.split(':')[2] : null |
| } |
| }); |
| } |
| }); |
| }, |
| remove: function(args) { |
| $.ajax({ |
| url: createURL('deleteSnapshotPolicies'), |
| data: { |
| id: args.snapshot.id |
| }, |
| dataType: 'json', |
| async: true, |
| success: function(data) { |
| args.response.success(); |
| } |
| }); |
| } |
| }, |
| |
| // Select data |
| selects: { |
| schedule: function(args) { |
| var time = []; |
| |
| for (var i = 1; i <= 59; i++) { |
| time.push({ |
| id: i, |
| name: i |
| }); |
| } |
| |
| args.response.success({ |
| data: time |
| }); |
| }, |
| timezone: function(args) { |
| args.response.success({ |
| data: $.map(timezoneMap, function(value, key) { |
| return { |
| id: key, |
| name: value |
| }; |
| }) |
| }); |
| }, |
| 'day-of-week': function(args) { |
| args.response.success({ |
| data: [{ |
| id: 1, |
| name: 'label.sunday' |
| }, { |
| id: 2, |
| name: 'label.monday' |
| }, { |
| id: 3, |
| name: 'label.tuesday' |
| }, { |
| id: 4, |
| name: 'label.wednesday' |
| }, { |
| id: 5, |
| name: 'label.thursday' |
| }, { |
| id: 6, |
| name: 'label.friday' |
| }, { |
| id: 7, |
| name: 'label.saturday' |
| }] |
| }); |
| }, |
| |
| 'day-of-month': function(args) { |
| var time = []; |
| |
| for (var i = 1; i <= 28; i++) { |
| time.push({ |
| id: i, |
| name: i |
| }); |
| } |
| |
| args.response.success({ |
| data: time |
| }); |
| }, |
| |
| 'time-hour': function(args) { |
| var time = []; |
| |
| for (var i = 1; i <= 12; i++) { |
| time.push({ |
| id: i, |
| name: i |
| }); |
| } |
| |
| args.response.success({ |
| data: time |
| }); |
| }, |
| |
| 'time-minute': function(args) { |
| var time = []; |
| |
| for (var i = 0; i <= 59; i++) { |
| time.push({ |
| id: i < 10 ? '0' + i : i, |
| name: i < 10 ? '0' + i : i |
| }); |
| } |
| |
| args.response.success({ |
| data: time |
| }); |
| }, |
| |
| 'time-meridiem': function(args) { |
| args.response.success({ |
| data: [{ |
| id: 'AM', |
| name: 'AM' |
| }, { |
| id: 'PM', |
| name: 'PM' |
| }] |
| }); |
| } |
| } |
| }) |
| }, |
| messages: { |
| notification: function(args) { |
| return 'label.snapshot.schedule'; |
| } |
| } |
| }, |
| |
| attachDisk: { |
| addRow: 'false', |
| label: 'label.action.attach.disk', |
| messages: { |
| confirm: function(args) { |
| return 'message.confirm.attach.disk'; |
| }, |
| notification: function(args) { |
| return 'label.action.attach.disk'; |
| } |
| }, |
| createForm: { |
| title: 'label.action.attach.disk', |
| desc: 'label.action.attach.disk', |
| fields: { |
| virtualMachineId: { |
| label: 'label.instance', |
| select: function(args) { |
| var zoneid = args.context.volumes[0].zoneid; |
| var items = []; |
| var data; |
| |
| if (!args.context.projects) { |
| data = { |
| zoneid: zoneid, |
| domainid: args.context.volumes[0].domainid, |
| account: args.context.volumes[0].account |
| }; |
| } else { |
| data = { |
| zoneid: zoneid, |
| projectid: args.context.projects[0].id |
| }; |
| } |
| |
| if (args.context.volumes[0].hypervisor != null && args.context.volumes[0].hypervisor.length > 0 && args.context.volumes[0].hypervisor != 'None') { |
| data = $.extend(data, { |
| hypervisor: args.context.volumes[0].hypervisor |
| }); |
| } |
| |
| $(['Running', 'Stopped']).each(function() { |
| $.ajax({ |
| url: createURL('listVirtualMachines'), |
| data: $.extend(data, { |
| state: this.toString() |
| }), |
| async: false, |
| success: function(json) { |
| var instanceObjs = json.listvirtualmachinesresponse.virtualmachine; |
| $(instanceObjs).each(function() { |
| items.push({ |
| id: this.id, |
| description: this.displayname ? this.displayname : this.name |
| }); |
| }); |
| } |
| }); |
| }); |
| |
| args.response.success({ |
| data: items |
| }); |
| } |
| } |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("attachVolume&id=" + args.context.volumes[0].id + '&virtualMachineId=' + args.data.virtualMachineId), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.attachvolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, |
| getUpdatedItem: function(json) { |
| return json.queryasyncjobresultresponse.jobresult.volume; |
| }, |
| getActionFilter: function() { |
| return volumeActionfilter; |
| } |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| detachDisk: { |
| label: 'label.action.detach.disk', |
| messages: { |
| confirm: function(args) { |
| return 'message.detach.disk'; |
| }, |
| notification: function(args) { |
| return 'label.action.detach.disk'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("detachVolume&id=" + args.context.volumes[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.detachvolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, |
| getUpdatedItem: function(json) { |
| return { |
| virtualmachineid: null, |
| vmdisplayname: null |
| }; |
| }, |
| getActionFilter: function() { |
| return volumeActionfilter; |
| } |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| downloadVolume: { |
| label: 'label.action.download.volume', |
| messages: { |
| confirm: function(args) { |
| return 'message.download.volume.confirm'; |
| }, |
| notification: function(args) { |
| return 'label.action.download.volume'; |
| }, |
| complete: function(args) { |
| var url = args.url; |
| var htmlMsg = _l('message.download.volume'); |
| var htmlMsg2 = htmlMsg.replace(/#/, url).replace(/00000/, url); |
| //$infoContainer.find("#info").html(htmlMsg2); |
| return htmlMsg2; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("extractVolume&id=" + args.context.volumes[0].id + "&zoneid=" + args.context.volumes[0].zoneid + "&mode=HTTP_DOWNLOAD"), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.extractvolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, |
| getUpdatedItem: function(json) { |
| return json.queryasyncjobresultresponse.jobresult.volume; |
| }, |
| getActionFilter: function() { |
| return volumeActionfilter; |
| } |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| createTemplate: cloudStack.createTemplateMethod(false), |
| migrateToAnotherStorage: { |
| label: 'label.migrate.volume.to.primary.storage', |
| messages: { |
| confirm: function(args) { |
| return 'message.migrate.volume'; |
| }, |
| notification: function(args) { |
| return 'label.migrate.volume.to.primary.storage'; |
| } |
| }, |
| createForm: $.extend({}, migrateVolumeCreateFormAction, {title: 'label.migrate.volume.to.primary.storage'}), |
| action: functionMigrateVolume, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| remove: { |
| label: 'label.action.delete.volume', |
| messages: { |
| confirm: function(args) { |
| return 'message.action.delete.volume'; |
| }, |
| notification: function(args) { |
| return 'label.action.delete.volume'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("deleteVolume&id=" + args.context.volumes[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| args.response.success(); |
| } |
| }); |
| }, |
| notification: { |
| poll: function(args) { |
| args.complete(); |
| } |
| } |
| }, |
| |
| destroy: { |
| label: 'label.action.destroy.volume', |
| createForm: { |
| title: 'label.action.destroy.volume', |
| desc: 'message.action.destroy.volume', |
| isWarning: true, |
| preFilter: function(args) { |
| if (!isAdmin() && ! g_allowUserExpungeRecoverVolume) { |
| args.$form.find('.form-item[rel=expunge]').hide(); |
| } |
| }, |
| fields: { |
| expunge: { |
| label: 'label.expunge', |
| isBoolean: true, |
| isChecked: false |
| } |
| } |
| }, |
| messages: { |
| confirm: function(args) { |
| return 'message.action.destroy.volume'; |
| }, |
| notification: function(args) { |
| return 'label.action.destroy.volume'; |
| } |
| }, |
| action: function(args) { |
| var data = { |
| id: args.context.volumes[0].id |
| }; |
| if (args.data.expunge == 'on') { |
| $.extend(data, { |
| expunge: true |
| }); |
| } |
| $.ajax({ |
| url: createURL("destroyVolume"), |
| data: data, |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.destroyvolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, |
| getUpdatedItem: function(json) { |
| if ('volume' in json.queryasyncjobresultresponse.jobresult) { //destroy without expunge |
| var volume = json.queryasyncjobresultresponse.jobresult.volume; |
| if (volume.state == 'Expunged') { |
| return { 'toRemove': true }; |
| } else { |
| return volume; |
| } |
| } else //destroy with expunge |
| return { 'toRemove': true }; |
| }, |
| getActionFilter: function() { |
| return volumeActionfilter; |
| } |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| recover: { |
| label: 'label.action.recover.volume', |
| messages: { |
| confirm: function(args) { |
| return 'message.action.recover.volume'; |
| }, |
| notification: function(args) { |
| return 'label.action.recover.volume'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("recoverVolume&id=" + args.context.volumes[0].id), |
| dataType: "json", |
| success: function(json) { |
| args.response.success(); |
| } |
| }); |
| }, |
| notification: { |
| poll: function(args) { |
| args.complete(); |
| } |
| } |
| }, |
| |
| resize: { |
| label: 'label.action.resize.volume', |
| messages: { |
| notification: function(args) { |
| return 'label.action.resize.volume'; |
| } |
| }, |
| createForm: { |
| title: 'label.action.resize.volume', |
| preFilter: function(args) { |
| var vol; |
| if (args.context.volumes != null) vol = args.context.volumes[0]; |
| if (vol.type == "ROOT" && (vol.hypervisor == "XenServer" || vol.hypervisor == "KVM" || vol.hypervisor == "VMware")) { |
| args.$form.find('.form-item[rel=newdiskoffering]').hide(); |
| args.$form.find('.form-item[rel=newsize]').css('display', 'inline-block'); |
| } else { |
| args.$form.find('.form-item[rel=newdiskoffering]').css('display', 'inline-block'); |
| args.$form.find('.form-item[rel=newsize]').hide(); |
| } |
| }, |
| fields: { |
| newdiskoffering: { |
| label: 'label.resize.new.offering.id', |
| isHidden: true, |
| select: function(args) { |
| if (args.context.volumes != null && args.context.volumes[0].type == 'ROOT') { |
| args.response.success({ |
| data: [] |
| }); |
| return; |
| } |
| var diskOfferings = cloudStack.listDiskOfferings({}); |
| var items = []; |
| $(diskOfferings).each(function() { |
| items.push({ |
| id: this.id, |
| description: this.displaytext |
| }); |
| }); |
| args.response.success({ |
| data: items |
| }); |
| args.$select.change(function() { |
| if(args.context.volumes[0].type == "ROOT") { |
| selectedDiskOfferingObj = null; |
| return; |
| } |
| |
| var diskOfferingId = $(this).val(); |
| $(diskOfferings).each(function() { |
| if (this.id == diskOfferingId) { |
| selectedDiskOfferingObj = this; |
| return false; //break the $.each() loop |
| } |
| }); |
| if (selectedDiskOfferingObj == null){ |
| return; |
| } |
| var $form = $(this).closest('form'); |
| |
| var $shrinkok = $form.find('.form-item[rel=shrinkok]'); |
| //unit of args.context.volumes[0].size is "byte" |
| //unit of selectedDiskOfferingObj.disksize is "gigabyte" ("GB"), so transfer it into "byte" by multiply (1024 * 1024 * 1024) |
| if (args.context.volumes[0].size > selectedDiskOfferingObj.disksize * (1024 * 1024 * 1024)) { //if original disk size > new disk size |
| $shrinkok.css('display', 'inline-block'); |
| } else { |
| $shrinkok.hide(); |
| } |
| |
| var $newsize = $form.find('.form-item[rel=newsize]'); |
| if (selectedDiskOfferingObj.iscustomized == true) { |
| $newsize.css('display', 'inline-block'); |
| } else { |
| $newsize.hide(); |
| } |
| |
| var $minIops = $form.find('.form-item[rel=minIops]'); |
| var $maxIops = $form.find('.form-item[rel=maxIops]'); |
| if (selectedDiskOfferingObj.iscustomizediops == true) { |
| $minIops.css('display', 'inline-block'); |
| $maxIops.css('display', 'inline-block'); |
| } else { |
| $minIops.hide(); |
| $maxIops.hide(); |
| } |
| }); |
| } |
| }, |
| newsize: { |
| label: 'label.resize.new.size', |
| validation: { |
| required: true, |
| number: true |
| } |
| }, |
| shrinkok: { |
| label: 'label.resize.shrink.ok', |
| isBoolean: true, |
| isChecked: false, |
| isHidden: true |
| }, |
| minIops: { |
| label: 'label.disk.iops.min', |
| validation: { |
| required: false, |
| number: true |
| }, |
| isHidden: true |
| }, |
| maxIops: { |
| label: 'label.disk.iops.max', |
| validation: { |
| required: false, |
| number: true |
| }, |
| isHidden: true |
| } |
| } |
| }, |
| action: function(args) { |
| var array1 = []; |
| if(args.$form.find('.form-item[rel=shrinkok]').css("display") != "none") { |
| array1.push("&shrinkok=" + (args.data.shrinkok == "on")); |
| } |
| |
| var newDiskOffering = args.data.newdiskoffering; |
| if (newDiskOffering != null && newDiskOffering.length > 0) { |
| array1.push("&diskofferingid=" + encodeURIComponent(newDiskOffering)); |
| } |
| if (args.context.volumes[0].type == "ROOT" || selectedDiskOfferingObj.iscustomized == true) { |
| cloudStack.addNewSizeToCommandUrlParameterArrayIfItIsNotNullAndHigherThanZero(array1, args.data.newsize); |
| } |
| |
| var minIops; |
| var maxIops |
| if (selectedDiskOfferingObj != null && selectedDiskOfferingObj.iscustomizediops == true) { |
| minIops = args.data.minIops; |
| maxIops = args.data.maxIops; |
| } |
| |
| if (minIops != null && minIops.length > 0) { |
| array1.push("&miniops=" + encodeURIComponent(minIops)); |
| } |
| |
| if (maxIops != null && maxIops.length > 0) { |
| array1.push("&maxiops=" + encodeURIComponent(maxIops)); |
| } |
| //if original disk size > new disk size |
| if (args.context.volumes[0].type == "ROOT" && |
| args.context.volumes[0].size > (args.data.newsize * (1024 * 1024 * 1024))) { |
| return args.response.error('message.volume.root.shrink.disk.size'); |
| } |
| |
| $.ajax({ |
| url: createURL("resizeVolume&id=" + args.context.volumes[0].id + array1.join("")), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.resizevolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, |
| getUpdatedItem: function(json) { |
| return json.queryasyncjobresultresponse.jobresult.volume; |
| }, |
| getActionFilter: function() { |
| return volumeActionfilter; |
| } |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| } |
| }, |
| tabs: { |
| details: { |
| title: 'label.details', |
| |
| preFilter: function(args) { |
| var hiddenFields; |
| if (isAdmin()) { |
| hiddenFields = []; |
| } else { |
| hiddenFields = ['storage', 'hypervisor', 'virtualsize', 'physicalsize', 'utilization', 'clusterid', 'clustername']; |
| } |
| return hiddenFields; |
| }, |
| |
| fields: [{ |
| name: { |
| label: 'label.name', |
| isEditable: true |
| } |
| }, { |
| id: { |
| label: 'label.id' |
| }, |
| zonename: { |
| label: 'label.zone' |
| }, |
| state: { |
| label: 'label.state', |
| pollAgainIfValueIsIn: { |
| 'UploadNotStarted': 1 |
| }, |
| pollAgainFn: function(context) { |
| var toClearInterval = false; |
| $.ajax({ |
| url: createURL("listVolumes&id=" + context.volumes[0].id), |
| dataType: "json", |
| async: false, |
| success: function(json) { |
| var jsonObj = json.listvolumesresponse.volume[0]; |
| if (jsonObj.state != context.volumes[0].state) { |
| toClearInterval = true; //to clear interval |
| } |
| } |
| }); |
| return toClearInterval; |
| } |
| }, |
| status: { |
| label: 'label.status' |
| }, |
| diskofferingdisplaytext: { |
| label: 'label.disk.offering' |
| }, |
| type: { |
| label: 'label.type' |
| }, |
| storagetype: { |
| label: 'label.storage.type' |
| }, |
| provisioningtype: { |
| label: 'label.disk.provisioningtype' |
| }, |
| hypervisor: { |
| label: 'label.hypervisor' |
| }, |
| size: { |
| label: 'label.size', |
| converter: function(args) { |
| if (args == null || args == 0) |
| return ""; |
| else |
| return cloudStack.converters.convertBytes(args); |
| } |
| }, |
| clusterid: { |
| label: 'label.cluster' |
| }, |
| clustername: { |
| label: 'label.cluster.name' |
| }, |
| physicalsize: { |
| label: 'label.disk.physicalsize', |
| converter: function(args) { |
| if (args == null || args == 0) |
| return ""; |
| else |
| return cloudStack.converters.convertBytes(args); |
| } |
| }, |
| utilization: { |
| label: 'label.disk.utilisation' |
| }, |
| virtualsize: { |
| label: 'label.disk.virtualsize', |
| converter: function(args) { |
| if (args == null || args == 0) |
| return ""; |
| else |
| return cloudStack.converters.convertBytes(args); |
| } |
| }, |
| miniops: { |
| label: 'label.disk.iops.min', |
| converter: function(args) { |
| if (args == null || args == 0) |
| return ""; |
| else |
| return args; |
| } |
| }, |
| maxiops: { |
| label: 'label.disk.iops.max', |
| converter: function(args) { |
| if (args == null || args == 0) |
| return ""; |
| else |
| return args; |
| } |
| }, |
| virtualmachineid: { |
| label: 'label.vm.id', |
| converter: function(args) { |
| if (args == null) |
| return _l('state.detached'); |
| else |
| return args; |
| } |
| }, |
| //vmname: { label: 'label.vm.name' }, |
| vmdisplayname: { |
| label: 'label.vm.display.name' |
| }, |
| vmstate: { |
| label: 'label.vm.state' |
| }, |
| deviceid: { |
| label: 'label.device.id' |
| }, |
| storage: { |
| label: 'label.storage' |
| }, |
| created: { |
| label: 'label.created', |
| converter: cloudStack.converters.toLocalDate |
| }, |
| domain: { |
| label: 'label.domain' |
| }, |
| account: { |
| label: 'label.account' |
| } |
| }], |
| |
| tags: cloudStack.api.tags({ |
| resourceType: 'Volume', |
| contextId: 'volumes' |
| }), |
| |
| |
| dataProvider: function(args) { |
| $.ajax({ |
| url: createURL("listVolumes&id=" + args.context.volumes[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jsonObj = json.listvolumesresponse.volume[0]; |
| |
| $(window).trigger('cloudStack.module.sharedFunctions.addExtraProperties', { |
| obj: jsonObj, |
| objType: "Volume" |
| }); |
| |
| args.response.success({ |
| actionFilter: volumeActionfilter, |
| data: jsonObj |
| }); |
| } |
| }); |
| } |
| } |
| } |
| } |
| } |
| }, |
| |
| /** |
| * Snapshots |
| */ |
| snapshots: { |
| type: 'select', |
| title: 'label.snapshots', |
| listView: { |
| id: 'snapshots', |
| label: 'label.snapshots', |
| fields: { |
| volumename: { |
| label: 'label.volume' |
| }, |
| name: { |
| label: 'label.name' |
| }, |
| intervaltype: { |
| label: 'label.interval.type' |
| }, |
| created: { |
| label: 'label.created', |
| converter: cloudStack.converters.toLocalDate |
| }, |
| state: { |
| label: 'label.state', |
| indicator: { |
| 'BackedUp': 'on', |
| 'Destroyed': 'off' |
| } |
| } |
| }, |
| |
| advSearchFields: { |
| name: { |
| label: 'label.name' |
| }, |
| |
| domainid: { |
| label: 'label.domain', |
| select: function(args) { |
| if (isAdmin() || isDomainAdmin()) { |
| $.ajax({ |
| url: createURL('listDomains'), |
| data: { |
| listAll: true, |
| details: 'min' |
| }, |
| success: function(json) { |
| var array1 = [{ |
| id: '', |
| description: '' |
| }]; |
| var domains = json.listdomainsresponse.domain; |
| if (domains != null && domains.length > 0) { |
| for (var i = 0; i < domains.length; i++) { |
| array1.push({ |
| id: domains[i].id, |
| description: domains[i].path |
| }); |
| } |
| } |
| array1.sort(function(a, b) { |
| return a.description.localeCompare(b.description); |
| }); |
| args.response.success({ |
| data: array1 |
| }); |
| } |
| }); |
| } else { |
| args.response.success({ |
| data: null |
| }); |
| } |
| }, |
| isHidden: function(args) { |
| if (isAdmin() || isDomainAdmin()) |
| return false; |
| else |
| return true; |
| } |
| }, |
| |
| account: { |
| label: 'label.account', |
| isHidden: function(args) { |
| if (isAdmin() || isDomainAdmin()) |
| return false; |
| else |
| return true; |
| } |
| }, |
| tagKey: { |
| label: 'label.tag.key' |
| }, |
| tagValue: { |
| label: 'label.tag.value' |
| } |
| }, |
| |
| dataProvider: function(args) { |
| var data = {}; |
| var instanceVolumeIds = []; |
| listViewDataProvider(args, data); |
| |
| if (args.context != null) { |
| if ("volumes" in args.context) { |
| $.extend(data, { |
| volumeid: args.context.volumes[0].id |
| }); |
| } else if (args.context.instances) { |
| $.ajax({ |
| url: createURL('listVolumes'), |
| data: { |
| virtualmachineid: args.context.instances[0].id, |
| listAll: true |
| }, |
| async: false, |
| success: function(json) { |
| instanceVolumeIds = $.map(json.listvolumesresponse.volume, function(volume) { |
| return volume.id; |
| }) |
| } |
| }); |
| data.volumeid = instanceVolumeIds.join(','); |
| } |
| } |
| |
| $.ajax({ |
| url: createURL('listSnapshots'), |
| data: data, |
| success: function(json) { |
| var items = json.listsnapshotsresponse.snapshot; |
| args.response.success({ |
| actionFilter: snapshotActionfilter, |
| data: items |
| }); |
| }, |
| error: function(XMLHttpResponse) { |
| cloudStack.dialog.notice({ |
| message: parseXMLHttpResponse(XMLHttpResponse) |
| }); |
| args.response.error(); |
| } |
| }); |
| }, |
| |
| detailView: { |
| name: 'Snapshot detail', |
| actions: { |
| createTemplate: cloudStack.createTemplateFromSnapshotMethod(), |
| |
| createVolume: { |
| label: 'label.action.create.volume', |
| messages: { |
| confirm: function(args) { |
| return 'message.confirm.create.volume'; |
| }, |
| notification: function(args) { |
| return 'label.action.create.volume'; |
| } |
| }, |
| createForm: { |
| title: 'label.action.create.volume', |
| desc: '', |
| preFilter: function(args) { |
| if (g_regionsecondaryenabled == true) { |
| args.$form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); |
| } else { |
| args.$form.find('.form-item[rel=zoneid]').hide(); |
| } |
| if(args.context.snapshots[0].volumetype!='ROOT') { |
| args.$form.find('.form-item[rel=diskOffering]').hide(); |
| } |
| }, |
| fields: { |
| name: { |
| label: 'label.name', |
| validation: { |
| required: true |
| } |
| }, |
| zoneid: { |
| label: 'label.availability.zone', |
| isHidden: true, |
| select: function(args) { |
| $.ajax({ |
| url: createURL("listZones&available=true"), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var zoneObjs = json.listzonesresponse.zone; |
| var items = [{ |
| id: '', |
| description: '' |
| }]; |
| if (zoneObjs != null) { |
| for (i = 0; i < zoneObjs.length; i++) { |
| items.push({ |
| id: zoneObjs[i].id, |
| description: zoneObjs[i].name |
| }); |
| } |
| } |
| args.response.success({ |
| data: items |
| }); |
| } |
| }); |
| } |
| }, |
| diskOffering: { |
| label: 'label.disk.offering', |
| docID: 'helpVolumeDiskOffering', |
| select: function(args) { |
| var snapshotSizeInGB = Math.floor(args.context.snapshots[0].virtualsize/(1024 * 1024 * 1024)) |
| $.ajax({ |
| url: createURL("listDiskOfferings"), |
| dataType: "json", |
| async: false, |
| success: function(json) { |
| diskofferingObjs = json.listdiskofferingsresponse.diskoffering; |
| var items = []; |
| // Sort offerings list with size and keep custom offerings at end |
| for(var i=0;i<diskofferingObjs.length;i++) { |
| for(var j=i+1;j<diskofferingObjs.length;j++) { |
| if((diskofferingObjs[i].disksize>diskofferingObjs[j].disksize && |
| diskofferingObjs[j].disksize!=0) || |
| (diskofferingObjs[i].disksize==0 && |
| diskofferingObjs[j].disksize!=0)) { |
| var temp = diskofferingObjs[i]; |
| diskofferingObjs[i] = diskofferingObjs[j]; |
| diskofferingObjs[j] = temp; |
| } |
| } |
| } |
| $(diskofferingObjs).each(function() { |
| if(this.disksize==0 || this.disksize>=snapshotSizeInGB) { |
| items.push({ |
| id: this.id, |
| description: this.displaytext |
| }); |
| } |
| }); |
| args.response.success({ |
| data: items |
| }); |
| } |
| }); |
| |
| args.$select.change(function() { |
| var diskOfferingId = $(this).val(); |
| selectedDiskOfferingObj = null; |
| $(diskofferingObjs).each(function() { |
| if (this.id == diskOfferingId) { |
| selectedDiskOfferingObj = this; |
| return false; |
| } |
| }); |
| |
| if (selectedDiskOfferingObj == null) return; |
| |
| var $form = $(this).closest('form'); |
| var $diskSize = $form.find('.form-item[rel=diskSize]'); |
| if (selectedDiskOfferingObj.iscustomized == true) { |
| $diskSize.css('display', 'inline-block'); |
| $form.find('input[name=diskSize]').val(''+snapshotSizeInGB); |
| } else { |
| $diskSize.hide(); |
| } |
| |
| var $minIops = $form.find('.form-item[rel=minIops]'); |
| var $maxIops = $form.find('.form-item[rel=maxIops]'); |
| if (selectedDiskOfferingObj.iscustomizediops == true) { |
| $minIops.css('display', 'inline-block'); |
| $maxIops.css('display', 'inline-block'); |
| } else { |
| $minIops.hide(); |
| $maxIops.hide(); |
| } |
| }); |
| } |
| }, |
| diskSize: { |
| label: 'label.disk.size.gb', |
| docID: 'helpVolumeSizeGb', |
| validation: { |
| required: true, |
| number: true |
| }, |
| isHidden: true |
| }, |
| minIops: { |
| label: 'label.disk.iops.min', |
| validation: { |
| required: false, |
| number: true |
| }, |
| isHidden: true |
| }, |
| maxIops: { |
| label: 'label.disk.iops.max', |
| validation: { |
| required: false, |
| number: true |
| }, |
| isHidden: true |
| } |
| } |
| }, |
| action: function(args) { |
| var data = { |
| name: args.data.name, |
| snapshotid: args.context.snapshots[0].id |
| }; |
| |
| if (args.$form.find('.form-item[rel=zoneid]').css("display") != "none" && args.data.zoneid != '') { |
| $.extend(data, { |
| zoneId: args.data.zoneid |
| }); |
| } |
| |
| if (args.$form.find('.form-item[rel=diskOffering]').css("display") != "none") { |
| if (args.data.diskOffering) { |
| $.extend(data, { |
| diskofferingid: args.data.diskOffering |
| }); |
| } |
| if (selectedDiskOfferingObj) { |
| if(selectedDiskOfferingObj.iscustomized == true) { |
| $.extend(data, { |
| size: args.data.diskSize |
| }); |
| } |
| |
| if (selectedDiskOfferingObj.iscustomizediops == true) { |
| if (args.data.minIops != "" && args.data.minIops > 0) { |
| $.extend(data, { |
| miniops: args.data.minIops |
| }); |
| } |
| |
| if (args.data.maxIops != "" && args.data.maxIops > 0) { |
| $.extend(data, { |
| maxiops: args.data.maxIops |
| }); |
| } |
| } |
| } |
| } |
| |
| $.ajax({ |
| url: createURL('createVolume'), |
| data: data, |
| success: function(json) { |
| var jid = json.createvolumeresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid, |
| getUpdatedItem: function(json) { |
| return {}; //nothing in this snapshot needs to be updated |
| }, |
| getActionFilter: function() { |
| return snapshotActionfilter; |
| } |
| } |
| }); |
| }, |
| error: function(json) { |
| args.response.error(parseXMLHttpResponse(json)); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| revertSnapshot: { |
| label: 'label.action.revert.snapshot', |
| messages: { |
| confirm: function(args) { |
| return 'message.action.revert.snapshot'; |
| }, |
| notification: function(args) { |
| return 'label.action.revert.snapshot'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("revertSnapshot&id="+args.context.snapshots[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.revertsnapshotresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| remove: { |
| label: 'label.action.delete.snapshot', |
| messages: { |
| confirm: function(args) { |
| return 'message.action.delete.snapshot'; |
| }, |
| notification: function(args) { |
| return 'label.action.delete.snapshot'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("deleteSnapshot&id=" + args.context.snapshots[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.deletesnapshotresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| } |
| }, |
| tabs: { |
| details: { |
| title: 'label.details', |
| fields: [{ |
| name: { |
| label: 'label.name' |
| } |
| }, { |
| id: { |
| label: 'label.id' |
| }, |
| volumename: { |
| label: 'label.volume.name' |
| }, |
| state: { |
| label: 'label.state' |
| }, |
| intervaltype: { |
| label: 'label.interval.type' |
| }, |
| domain: { |
| label: 'label.domain' |
| }, |
| account: { |
| label: 'label.account' |
| }, |
| created: { |
| label: 'label.created', |
| converter: cloudStack.converters.toLocalDate |
| } |
| }], |
| |
| tags: cloudStack.api.tags({ |
| resourceType: 'Snapshot', |
| contextId: 'snapshots' |
| }), |
| |
| dataProvider: function(args) { |
| $.ajax({ |
| url: createURL("listSnapshots&id=" + args.context.snapshots[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jsonObj = json.listsnapshotsresponse.snapshot[0]; |
| args.response.success({ |
| actionFilter: snapshotActionfilter, |
| data: jsonObj |
| }); |
| } |
| }); |
| } |
| } |
| } |
| } |
| }, |
| }, |
| |
| /** |
| * VM Snapshots |
| */ |
| vmsnapshots: { |
| type: 'select', |
| title: 'label.vmsnapshot', |
| listView: { |
| id: 'vmsnapshots', |
| isMaximized: true, |
| fields: { |
| displayname: { |
| label: 'label.name' |
| }, |
| state: { |
| label: 'label.state', |
| indicator: { |
| 'Ready': 'on', |
| 'Error': 'off' |
| } |
| }, |
| type: { |
| label: 'label.vmsnapshot.type' |
| }, |
| current: { |
| label: 'label.vmsnapshot.current', |
| converter: cloudStack.converters.toBooleanText |
| }, |
| parentName: { |
| label: 'label.vmsnapshot.parentname' |
| }, |
| created: { |
| label: 'label.date', |
| converter: cloudStack.converters.toLocalDate |
| } |
| }, |
| |
| advSearchFields: { |
| name: { |
| label: 'label.name' |
| }, |
| |
| domainid: { |
| label: 'label.domain', |
| select: function(args) { |
| if (isAdmin() || isDomainAdmin()) { |
| $.ajax({ |
| url: createURL('listDomains'), |
| data: { |
| listAll: true, |
| details: 'min' |
| }, |
| success: function(json) { |
| var array1 = [{ |
| id: '', |
| description: '' |
| }]; |
| var domains = json.listdomainsresponse.domain; |
| if (domains != null && domains.length > 0) { |
| for (var i = 0; i < domains.length; i++) { |
| array1.push({ |
| id: domains[i].id, |
| description: domains[i].path |
| }); |
| } |
| } |
| array1.sort(function(a, b) { |
| return a.description.localeCompare(b.description); |
| }); |
| args.response.success({ |
| data: array1 |
| }); |
| } |
| }); |
| } else { |
| args.response.success({ |
| data: null |
| }); |
| } |
| }, |
| isHidden: function(args) { |
| if (isAdmin() || isDomainAdmin()) |
| return false; |
| else |
| return true; |
| } |
| }, |
| |
| account: { |
| label: 'label.account', |
| isHidden: function(args) { |
| if (isAdmin() || isDomainAdmin()) |
| return false; |
| else |
| return true; |
| } |
| }, |
| tagKey: { |
| label: 'label.tag.key' |
| }, |
| tagValue: { |
| label: 'label.tag.value' |
| } |
| }, |
| |
| dataProvider: function(args) { |
| var data = { |
| listAll: true |
| }; |
| listViewDataProvider(args, data); |
| |
| if (args.context != null) { |
| if ("instances" in args.context) { |
| $.extend(data, { |
| virtualMachineId: args.context.instances[0].id |
| }); |
| } |
| } |
| $.ajax({ |
| url: createURL('listVMSnapshot'), |
| data: data, |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jsonObj; |
| jsonObj = json.listvmsnapshotresponse.vmSnapshot; |
| args.response.success({ |
| actionFilter: vmSnapshotActionfilter, |
| data: jsonObj |
| }); |
| } |
| }); |
| }, |
| //dataProvider end |
| detailView: { |
| tabs: { |
| details: { |
| title: 'label.details', |
| fields: { |
| id: { |
| label: 'label.id' |
| }, |
| name: { |
| label: 'label.name' |
| }, |
| displayname: { |
| label: 'label.display.name' |
| }, |
| type: { |
| label: 'label.vmsnapshot.type' |
| }, |
| description: { |
| label: 'label.description' |
| }, |
| state: { |
| label: 'label.state', |
| indicator: { |
| 'Ready': 'on', |
| 'Error': 'off' |
| } |
| }, |
| current: { |
| label: 'label.vmsnapshot.current', |
| converter: cloudStack.converters.toBooleanText |
| }, |
| parentName: { |
| label: 'label.vmsnapshot.parentname' |
| }, |
| domain: { |
| label: 'label.domain' |
| }, |
| account: { |
| label: 'label.account' |
| }, |
| virtualmachineid: { |
| label: 'label.vm.id' |
| }, |
| created: { |
| label: 'label.date', |
| converter: cloudStack.converters.toLocalDate |
| } |
| }, |
| dataProvider: function(args) { |
| $.ajax({ |
| url: createURL("listVMSnapshot&listAll=true&vmsnapshotid=" + args.context.vmsnapshots[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jsonObj; |
| jsonObj = json.listvmsnapshotresponse.vmSnapshot[0]; |
| args.response.success({ |
| actionFilter: vmSnapshotActionfilter, |
| data: jsonObj |
| }); |
| } |
| }); |
| }, |
| tags: cloudStack.api.tags({ |
| resourceType: 'VMSnapshot', |
| contextId: 'vmsnapshots' |
| }) |
| } |
| }, |
| actions: { |
| //delete a snapshot |
| remove: { |
| label: 'label.action.vmsnapshot.delete', |
| messages: { |
| confirm: function(args) { |
| return 'message.action.vmsnapshot.delete'; |
| }, |
| notification: function(args) { |
| return 'label.action.vmsnapshot.delete'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("deleteVMSnapshot&vmsnapshotid=" + args.context.vmsnapshots[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.deletevmsnapshotresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| revertToVMSnapshot: { |
| label: 'label.action.vmsnapshot.revert', |
| messages: { |
| confirm: function(args) { |
| return 'label.action.vmsnapshot.revert'; |
| }, |
| notification: function(args) { |
| return 'message.action.vmsnapshot.revert'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("revertToVMSnapshot&vmsnapshotid=" + args.context.vmsnapshots[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.reverttovmsnapshotresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| takeSnapshot: { |
| label: 'Create Snapshot From VM Snapshot', |
| messages: { |
| confirm: function(args) { |
| return 'Please confirm that you want to create a volume snapshot from the vm snapshot.'; |
| }, |
| notification: function(args) { |
| return 'Volume snapshot is created from vm snapshot'; |
| } |
| }, |
| createForm: { |
| title: 'label.action.take.snapshot', |
| desc: 'message.action.take.snapshot', |
| fields: { |
| name: { |
| label: 'label.name', |
| }, |
| volume: { |
| label: 'label.volume', |
| validation: { |
| required: true |
| }, |
| select: function(args) { |
| $.ajax({ |
| url: createURL("listVolumes&virtualMachineId=" + args.context.vmsnapshots[0].virtualmachineid), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var volumes = json.listvolumesresponse.volume; |
| var items = []; |
| $(volumes).each(function() { |
| items.push({ |
| id: this.id, |
| description: this.name |
| }); |
| }); |
| args.response.success({ |
| data: items |
| }); |
| |
| } |
| }); |
| } |
| } |
| } |
| }, |
| action: function(args) { |
| var data = { |
| volumeid: args.data.volume, |
| vmsnapshotid: args.context.vmsnapshots[0].id |
| }; |
| if (args.data.name != null && args.data.name.length > 0) { |
| $.extend(data, { |
| name: args.data.name |
| }); |
| } |
| $.ajax({ |
| url: createURL("createSnapshotFromVMSnapshot"), |
| data: data, |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.createsnapshotfromvmsnapshotresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| } |
| } |
| } |
| //detailview end |
| } |
| }, |
| |
| /** |
| * Backups |
| */ |
| backups: { |
| type: 'select', |
| title: 'label.backup', |
| listView: { |
| id: 'backups', |
| isMaximized: true, |
| fields: { |
| virtualmachinename: { |
| label: 'label.vm.name' |
| }, |
| status: { |
| label: 'label.state', |
| indicator: { |
| 'BackedUp': 'on', |
| 'Failed': 'off', |
| 'Error': 'off' |
| } |
| }, |
| type: { |
| label: 'label.type' |
| }, |
| created: { |
| label: 'label.date' |
| }, |
| account: { |
| label: 'label.account' |
| }, |
| zone: { |
| label: 'label.zone' |
| } |
| }, |
| |
| dataProvider: function(args) { |
| var data = { |
| listAll: true |
| }; |
| listViewDataProvider(args, data); |
| |
| if (args.context != null) { |
| if ("instances" in args.context) { |
| $.extend(data, { |
| virtualmachineid: args.context.instances[0].id |
| }); |
| } |
| } |
| |
| $.ajax({ |
| url: createURL('listBackups'), |
| data: data, |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jsonObj; |
| jsonObj = json.listbackupsresponse.backup; |
| args.response.success({ |
| actionFilter: backupActionfilter, |
| data: jsonObj |
| }); |
| } |
| }); |
| }, |
| //dataProvider end |
| detailView: { |
| tabs: { |
| details: { |
| title: 'label.details', |
| fields: { |
| id: { |
| label: 'label.id' |
| }, |
| virtualmachinename: { |
| label: 'label.vm.name' |
| }, |
| virtualmachineid: { |
| label: 'label.vm.id' |
| }, |
| status: { |
| label: 'label.state' |
| }, |
| externalid: { |
| label: 'label.external.id' |
| }, |
| type: { |
| label: 'label.type' |
| }, |
| size: { |
| label: 'label.size' |
| }, |
| virtualsize: { |
| label: 'label.virtual.size' |
| }, |
| volumes: { |
| label: 'label.volumes' |
| }, |
| account: { |
| label: 'label.account' |
| }, |
| domain: { |
| label: 'label.domain' |
| }, |
| zone: { |
| label: 'label.zone' |
| }, |
| created: { |
| label: 'label.date' |
| } |
| }, |
| dataProvider: function(args) { |
| $.ajax({ |
| url: createURL("listBackups&id=" + args.context.backups[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jsonObj; |
| jsonObj = json.listbackupsresponse.backup[0]; |
| args.response.success({ |
| actionFilter: backupActionfilter, |
| data: jsonObj |
| }); |
| } |
| }); |
| } |
| } |
| }, |
| actions: { |
| remove: { |
| label: 'Delete Backup', |
| messages: { |
| confirm: function(args) { |
| return 'Are you sure you want to delete the backup?'; |
| }, |
| notification: function(args) { |
| return 'Delete Backup'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("deleteBackup&id=" + args.context.backups[0].id), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.deletebackupresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| restoreBackup: { |
| label: 'label.backup.restore', |
| messages: { |
| confirm: function(args) { |
| return 'Please confirm that you want to restore the vm backup?'; |
| }, |
| notification: function(args) { |
| return 'label.backup.restore'; |
| } |
| }, |
| action: function(args) { |
| var data = { |
| id: args.context.backups[0].id |
| }; |
| $.ajax({ |
| url: createURL("restoreBackup"), |
| data: data, |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.restorebackupresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| restoreBackupVolume: { |
| label: 'Restore and Attach Backup Volume', |
| messages: { |
| confirm: function(args) { |
| return 'Please confirm that you want to restore and attach the volume from the backup?'; |
| }, |
| notification: function(args) { |
| return 'Restore and Attach Backup Volume'; |
| } |
| }, |
| createForm: { |
| title: 'Restore and Attach Backup Volume', |
| desc: 'Please select the volume you want to restore and attach to the VM.', |
| fields: { |
| volume: { |
| label: 'label.volume', |
| validation: { |
| required: true |
| }, |
| select: function(args) { |
| var volumes = JSON.parse(args.context.backups[0].volumes); |
| var items = []; |
| $(volumes).each(function() { |
| items.push({ |
| id: this.uuid, |
| description: '(' + this.type + ') ' + this.uuid |
| }); |
| }); |
| args.response.success({ |
| data: items |
| }); |
| } |
| }, |
| virtualmachine: { |
| label: 'label.virtual.machine', |
| validation: { |
| required: true |
| }, |
| select: function(args) { |
| $.ajax({ |
| url: createURL("listVirtualMachines"), |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var vms = json.listvirtualmachinesresponse.virtualmachine; |
| var items = []; |
| $(vms).each(function() { |
| items.push({ |
| id: this.id, |
| description: this.name |
| }); |
| }); |
| args.response.success({ |
| data: items |
| }); |
| |
| } |
| }); |
| } |
| } |
| } |
| }, |
| action: function(args) { |
| console.log(args); |
| var data = { |
| backupid: args.context.backups[0].id, |
| volumeid: args.data.volume, |
| virtualmachineid: args.data.virtualmachine |
| }; |
| $.ajax({ |
| url: createURL("restoreVolumeFromBackupAndAttachToVM"), |
| data: data, |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.restorevolumefrombackupandattachtovmresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| }, |
| |
| removeBackupChain: { |
| label: 'Delete Backup Chain', |
| messages: { |
| confirm: function(args) { |
| return 'Are you sure you want to remove VM from backup offering and delete the backup chain?'; |
| }, |
| notification: function(args) { |
| return 'Delete Backup Chain'; |
| } |
| }, |
| action: function(args) { |
| $.ajax({ |
| url: createURL("removeVirtualMachineFromBackupOffering"), |
| data: { |
| virtualmachineid: args.context.backups[0].virtualmachineid, |
| forced: true |
| }, |
| dataType: "json", |
| async: true, |
| success: function(json) { |
| var jid = json.removevirtualmachinefrombackupofferingresponse.jobid; |
| args.response.success({ |
| _custom: { |
| jobId: jid |
| } |
| }); |
| } |
| }); |
| }, |
| notification: { |
| poll: pollAsyncJobResult |
| } |
| } |
| } |
| } |
| //detailview end |
| } |
| } |
| } |
| }; |
| |
| |
| var volumeActionfilter = cloudStack.actionFilter.volumeActionfilter = function(args) { |
| var jsonObj = args.context.item; |
| var allowedActions = []; |
| |
| if ((isAdmin() || g_allowUserExpungeRecoverVolume) && jsonObj.state == 'Destroy') { |
| return ["recover", "remove"]; |
| } else if (jsonObj.state == 'Destroy') { |
| return []; |
| } |
| |
| if (jsonObj.state == 'Expunging' || jsonObj.state == 'Expunged') { |
| return ["remove"]; |
| } |
| |
| if (jsonObj.state == 'Destroyed' || jsonObj.state == 'Migrating' || jsonObj.state == 'Uploading') { |
| return []; |
| } |
| if (jsonObj.state == 'UploadError') { |
| return ["remove"]; |
| } |
| |
| if (jsonObj.hypervisor != "Ovm" && jsonObj.state == "Ready") { |
| if (jsonObj.hypervisor == 'KVM') { |
| if (jsonObj.vmstate == 'Running') { |
| if (g_kvmsnapshotenabled == true) { //"kvm.snapshot.enabled" flag should be taken to account only when snapshot is being created for Running vm (CLOUDSTACK-4428) |
| allowedActions.push("takeSnapshot"); |
| allowedActions.push("recurringSnapshot"); |
| } |
| } else { |
| allowedActions.push("takeSnapshot"); |
| allowedActions.push("recurringSnapshot"); |
| } |
| } else { |
| allowedActions.push("takeSnapshot"); |
| allowedActions.push("recurringSnapshot"); |
| } |
| } |
| |
| if ((jsonObj.type == "DATADISK" || jsonObj.type == "ROOT") && (jsonObj.state == "Ready" || jsonObj.state == "Allocated")) { |
| allowedActions.push("resize"); |
| } |
| |
| if (jsonObj.state != "Allocated") { |
| if ((jsonObj.vmstate == "Stopped" || jsonObj.virtualmachineid == null) && jsonObj.state == "Ready") { |
| allowedActions.push("downloadVolume"); |
| } |
| } |
| |
| |
| |
| if (jsonObj.type == "ROOT" || jsonObj.type == "DATADISK") { |
| if (jsonObj.state == "Ready" && isAdmin() && jsonObj.virtualmachineid != null) { |
| allowedActions.push("migrateVolume"); |
| } |
| } |
| |
| if (jsonObj.state != "Creating") { |
| if (jsonObj.type == "ROOT") { |
| if (jsonObj.vmstate == "Stopped") { |
| allowedActions.push("createTemplate"); |
| } |
| } else { //jsonObj.type == "DATADISK" |
| if (jsonObj.virtualmachineid != null) { |
| if (jsonObj.vmstate == "Running" || jsonObj.vmstate == "Stopped" || jsonObj.vmstate == "Destroyed") { |
| allowedActions.push("detachDisk"); |
| } |
| } else { // Disk not attached |
| if (jsonObj.state == "Allocated" || jsonObj.state == "Uploaded") { |
| allowedActions.push("remove"); |
| } else { |
| allowedActions.push("createTemplate"); |
| allowedActions.push("destroy"); |
| } |
| if (jsonObj.state == "Ready" && isAdmin()) { |
| allowedActions.push("migrateToAnotherStorage"); |
| } |
| allowedActions.push("attachDisk"); |
| } |
| } |
| } |
| |
| return allowedActions; |
| }; |
| |
| var snapshotActionfilter = cloudStack.actionFilter.snapshotActionfilter = function(args) { |
| var jsonObj = args.context.item; |
| |
| if (jsonObj.state == 'Destroyed') { |
| return []; |
| } |
| |
| var allowedActions = []; |
| if (jsonObj.state == "BackedUp") { |
| allowedActions.push("createTemplate"); |
| allowedActions.push("createVolume"); |
| |
| if (jsonObj.revertable) { |
| allowedActions.push("revertSnapshot"); |
| } |
| } |
| allowedActions.push("remove"); |
| |
| return allowedActions; |
| }; |
| |
| var vmSnapshotActionfilter = cloudStack.actionFilter.vmSnapshotActionfilter = function(args) { |
| var jsonObj = args.context.item; |
| |
| if (jsonObj.state == 'Error') { |
| return ["remove"]; |
| } |
| |
| var allowedActions = []; |
| if (jsonObj.state == "Ready") { |
| allowedActions.push("remove"); |
| allowedActions.push("revertToVMSnapshot"); |
| |
| if (args && args.context && args.context.instances && args.context.instances[0].hypervisor && args.context.instances[0].hypervisor === "KVM") { |
| allowedActions.push("takeSnapshot"); |
| } |
| } |
| |
| return allowedActions; |
| } |
| |
| var backupActionfilter = cloudStack.actionFilter.backupActionfilter = function(args) { |
| var jsonObj = args.context.item; |
| |
| if (jsonObj.state == 'Destroyed') { |
| return []; |
| } |
| |
| var allowedActions = []; |
| allowedActions.push("remove"); |
| allowedActions.push("restoreBackup"); |
| allowedActions.push("restoreBackupVolume"); |
| allowedActions.push("removeBackupChain"); |
| |
| return allowedActions; |
| }; |
| |
| |
| |
| })(cloudStack); |