X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=www%2Fmanager6%2Fwindow%2FMigrate.js;h=1c23abb3e5d296be035655f71c92d9e20718e8a1;hb=dc4056cfcb1e31f90d4f28a101897624c864ff07;hp=79edf0518d0a7a039d49fac653a3425197114316;hpb=11c17a01b7afe051b987195e4efb596186d74647;p=pve-manager.git diff --git a/www/manager6/window/Migrate.js b/www/manager6/window/Migrate.js index 79edf051..1c23abb3 100644 --- a/www/manager6/window/Migrate.js +++ b/www/manager6/window/Migrate.js @@ -14,11 +14,11 @@ Ext.define('PVE.window.Migrate', { running: false, qemu: { onlineHelp: 'qm_migration', - commonName: 'VM' + commonName: 'VM', }, lxc: { onlineHelp: 'pct_migration', - commonName: 'CT' + commonName: 'CT', }, migration: { possible: true, @@ -27,14 +27,14 @@ Ext.define('PVE.window.Migrate', { mode: undefined, allowedNodes: undefined, overwriteLocalResourceCheck: false, - hasLocalResources: false - } + hasLocalResources: false, + }, }, formulas: { setMigrationMode: function(get) { - if (get('running')){ + if (get('running')) { if (get('vmtype') === 'qemu') { return gettext('Online'); } else { @@ -58,8 +58,8 @@ Ext.define('PVE.window.Migrate', { } else { return false; } - } - } + }, + }, }, controller: { @@ -69,8 +69,8 @@ Ext.define('PVE.window.Migrate', { validityChange: function(panel, isValid) { this.getViewModel().set('migration.possible', isValid); this.checkMigratePreconditions(); - } - } + }, + }, }, init: function(view) { @@ -92,20 +92,17 @@ Ext.define('PVE.window.Migrate', { } vm.set('vmtype', view.vmtype); - view.setTitle( - Ext.String.format('{0} {1} {2}', gettext('Migrate'), vm.get(view.vmtype).commonName, view.vmid) + Ext.String.format('{0} {1} {2}', gettext('Migrate'), vm.get(view.vmtype).commonName, view.vmid), ); me.lookup('proxmoxHelpButton').setHelpConfig({ - onlineHelp: vm.get(view.vmtype).onlineHelp + onlineHelp: vm.get(view.vmtype).onlineHelp, }); - me.checkMigratePreconditions(); me.lookup('formPanel').isValid(); - }, - onTargetChange: function (nodeSelector) { - //Always display the storages of the currently seleceted migration target + onTargetChange: function(nodeSelector) { + // Always display the storages of the currently seleceted migration target this.lookup('pveDiskStorageSelector').setNodename(nodeSelector.value); this.checkMigratePreconditions(); }, @@ -117,7 +114,7 @@ Ext.define('PVE.window.Migrate', { var values = me.lookup('formPanel').getValues(); var params = { - target: values.target + target: values.target, }; if (vm.get('migration.mode')) { @@ -133,7 +130,7 @@ Ext.define('PVE.window.Migrate', { } if (vm.get('migration.overwriteLocalResourceCheck')) { - params['force'] = 1; + params.force = 1; } Proxmox.Utils.API2Request({ @@ -150,13 +147,12 @@ Ext.define('PVE.window.Migrate', { Ext.create('Proxmox.window.TaskViewer', { upid: upid, - extraTitle: extraTitle + extraTitle: extraTitle, }).show(); view.close(); - } + }, }); - }, checkMigratePreconditions: function(resetMigrationPossible) { @@ -181,11 +177,10 @@ Ext.define('PVE.window.Migrate', { me.lookup('pveNodeSelector').allowedNodes = vm.get('migration.allowedNodes'); me.lookup('formPanel').isValid(); - }, - checkQemuPreconditions: function(resetMigrationPossible) { - var me = this, + checkQemuPreconditions: async function(resetMigrationPossible) { + let me = this, vm = me.getViewModel(), migrateStats; @@ -193,113 +188,103 @@ Ext.define('PVE.window.Migrate', { vm.set('migration.mode', 'online'); } - Proxmox.Utils.API2Request({ - url: '/nodes/' + vm.get('nodename') + '/' + vm.get('vmtype') + '/' + vm.get('vmid') + '/migrate', - method: 'GET', - failure: function(response, opts) { - Ext.Msg.alert(gettext('Error'), response.htmlStatus); - }, - success: function(response, options) { - migrateStats = response.result.data; - if (migrateStats.running) { - vm.set('running', true); - } - // Get migration object from viewmodel to prevent - // to many bind callbacks - var migration = vm.get('migration'); - if (resetMigrationPossible) migration.possible = true; - migration.preconditions = []; - - if (migrateStats.allowed_nodes) { - migration.allowedNodes = migrateStats.allowed_nodes; - var target = me.lookup('pveNodeSelector').value; - if (target.length && !migrateStats.allowed_nodes.includes(target)) { - let disallowed = migrateStats.not_allowed_nodes[target]; - let missing_storages = disallowed.unavailable_storages.join(', '); + try { + if (me.fetchingNodeMigrateInfo && me.fetchingNodeMigrateInfo === vm.get('nodename')) { + return; + } + me.fetchingNodeMigrateInfo = vm.get('nodename'); + let { result } = await Proxmox.Async.api2({ + url: `/nodes/${vm.get('nodename')}/${vm.get('vmtype')}/${vm.get('vmid')}/migrate`, + method: 'GET', + }); + migrateStats = result.data; + me.fetchingNodeMigrateInfo = false; + } catch (error) { + Ext.Msg.alert(gettext('Error'), error.htmlStatus); + return; + } - migration.possible = false; - migration.preconditions.push({ - text: 'Storage (' + missing_storages + ') not available on selected target. ' + - 'Start VM to use live storage migration or select other target node', - severity: 'error' - }); - } - } + if (migrateStats.running) { + vm.set('running', true); + } + // Get migration object from viewmodel to prevent to many bind callbacks + let migration = vm.get('migration'); + if (resetMigrationPossible) { + migration.possible = true; + } + migration.preconditions = []; + + if (migrateStats.allowed_nodes) { + migration.allowedNodes = migrateStats.allowed_nodes; + let target = me.lookup('pveNodeSelector').value; + if (target.length && !migrateStats.allowed_nodes.includes(target)) { + let disallowed = migrateStats.not_allowed_nodes[target]; + let missingStorages = disallowed.unavailable_storages.join(', '); + + migration.possible = false; + migration.preconditions.push({ + text: 'Storage (' + missingStorages + ') not available on selected target. ' + + 'Start VM to use live storage migration or select other target node', + severity: 'error', + }); + } + } + + if (migrateStats.local_resources.length) { + migration.hasLocalResources = true; + if (!migration.overwriteLocalResourceCheck || vm.get('running')) { + migration.possible = false; + migration.preconditions.push({ + text: Ext.String.format('Can\'t migrate VM with local resources: {0}', + migrateStats.local_resources.join(', ')), + severity: 'error', + }); + } else { + migration.preconditions.push({ + text: Ext.String.format('Migrate VM with local resources: {0}. ' + + 'This might fail if resources aren\'t available on the target node.', + migrateStats.local_resources.join(', ')), + severity: 'warning', + }); + } + } - if (migrateStats.local_resources.length) { - migration.hasLocalResources = true; - if(!migration.overwriteLocalResourceCheck || vm.get('running')){ + if (migrateStats.local_disks.length) { + migrateStats.local_disks.forEach(function(disk) { + if (disk.cdrom && disk.cdrom === 1) { + if (!disk.volid.includes('vm-' + vm.get('vmid') + '-cloudinit')) { migration.possible = false; migration.preconditions.push({ - text: Ext.String.format('Can\'t migrate VM with local resources: {0}', - migrateStats.local_resources.join(', ')), - severity: 'error' - }); - } else { - migration.preconditions.push({ - text: Ext.String.format('Migrate VM with local resources: {0}. ' + - 'This might fail if resources aren\'t available on the target node.', - migrateStats.local_resources.join(', ')), - severity: 'warning' + text: "Can't migrate VM with local CD/DVD", + severity: 'error', }); } - } - - if (migrateStats.local_disks.length) { - - migrateStats.local_disks.forEach(function (disk) { - if (disk.cdrom && disk.cdrom === 1) { - if (disk.volid.includes('vm-'+vm.get('vmid')+'-cloudinit')) { - if (migrateStats.running) { - migration.possible = false; - migration.preconditions.push({ - text: "Can't live migrate VM with local cloudinit disk, use shared storage instead", - severity: 'error' - }); - } else { - return; - } - } else { - migration.possible = false; - migration.preconditions.push({ - text: "Can't migrate VM with local CD/DVD", - severity: 'error' - }); - } - } else { - var size_string = disk.size ? '(' + PVE.Utils.render_size(disk.size) + ')' : ''; - migration['with-local-disks'] = 1; - migration.preconditions.push({ - text: Ext.String.format('Migration with local disk might take long: {0} {1}', - disk.volid, size_string), - severity: 'warning' - }); - } + } else { + let size = disk.size ? '(' + Proxmox.Utils.render_size(disk.size) + ')' : ''; + migration['with-local-disks'] = 1; + migration.preconditions.push({ + text: Ext.String.format('Migration with local disk might take long: {0} {1}', disk.volid, size), + severity: 'warning', }); - } + }); + } - vm.set('migration', migration); - - } - }); + vm.set('migration', migration); }, checkLxcPreconditions: function(resetMigrationPossible) { - var me = this, - vm = me.getViewModel(); + let vm = this.getViewModel(); if (vm.get('running')) { vm.set('migration.mode', 'restart'); } - } - - + }, }, width: 600, modal: true, layout: { type: 'vbox', - align: 'stretch' + align: 'stretch', }, border: false, items: [ @@ -308,33 +293,31 @@ Ext.define('PVE.window.Migrate', { reference: 'formPanel', bodyPadding: 10, border: false, - layout: { - type: 'column' - }, + layout: 'hbox', items: [ { xtype: 'container', - columnWidth: 0.5, + flex: 1, items: [{ xtype: 'displayfield', name: 'source', fieldLabel: gettext('Source node'), bind: { - value: '{nodename}' - } + value: '{nodename}', + }, }, { xtype: 'displayfield', reference: 'migrationMode', fieldLabel: gettext('Mode'), bind: { - value: '{setMigrationMode}' - } - }] + value: '{setMigrationMode}', + }, + }], }, { xtype: 'container', - columnWidth: 0.5, + flex: 1, items: [{ xtype: 'pveNodeSelector', reference: 'pveNodeSelector', @@ -344,8 +327,8 @@ Ext.define('PVE.window.Migrate', { disallowedNodes: undefined, onlineValidator: true, listeners: { - change: 'onTargetChange' - } + change: 'onTargetChange', + }, }, { xtype: 'pveStorageSelector', @@ -355,10 +338,10 @@ Ext.define('PVE.window.Migrate', { storageContent: 'images', allowBlank: true, autoSelect: false, - emptyText: 'use current layout', + emptyText: gettext('Current layout'), bind: { - hidden: '{setStorageselectorHidden}' - } + hidden: '{setStorageselectorHidden}', + }, }, { xtype: 'proxmoxcheckbox', @@ -366,18 +349,21 @@ Ext.define('PVE.window.Migrate', { fieldLabel: gettext('Force'), autoEl: { tag: 'div', - 'data-qtip': 'Overwrite local resources unavailable check' + 'data-qtip': 'Overwrite local resources unavailable check', }, bind: { hidden: '{setLocalResourceCheckboxHidden}', - value: '{migration.overwriteLocalResourceCheck}' + value: '{migration.overwriteLocalResourceCheck}', }, listeners: { - change: {fn: 'checkMigratePreconditions', extraArg: true} - } - }] - } - ] + change: { + fn: 'checkMigratePreconditions', + extraArg: true, + }, + }, + }], + }, + ], }, { xtype: 'gridpanel', @@ -397,22 +383,23 @@ Ext.define('PVE.window.Migrate', { return v; } }, - width: 35 + width: 35, }, { text: 'Info', dataIndex: 'text', cellWrap: true, - flex: 1 + flex: 1, }], bind: { hidden: '{!migration.preconditions.length}', store: { - fields: ['severity','text'], - data: '{migration.preconditions}' - } - } - } + fields: ['severity', 'text'], + data: '{migration.preconditions}', + sorters: 'text', + }, + }, + }, ], buttons: [ @@ -421,7 +408,7 @@ Ext.define('PVE.window.Migrate', { reference: 'proxmoxHelpButton', onlineHelp: 'pct_migration', listenToGlobalEvent: false, - hidden: false + hidden: false, }, '->', { @@ -430,8 +417,8 @@ Ext.define('PVE.window.Migrate', { text: gettext('Migrate'), handler: 'startMigration', bind: { - disabled: '{!migration.possible}' - } - } - ] + disabled: '{!migration.possible}', + }, + }, + ], });