]> git.proxmox.com Git - pve-manager.git/blobdiff - www/manager6/window/GuestImport.js
ui: guest import: fix isWindows check
[pve-manager.git] / www / manager6 / window / GuestImport.js
index aac0c94a2f25617ac1ac779441edc925ad7d46fe..81e9074eb9a1996b3f9ea62f8a4130d0ee67a0f3 100644 (file)
@@ -92,44 +92,69 @@ Ext.define('PVE.window.GuestImport', {
            summaryGrid.getStore().setData(Object.entries(values).map(([key, value]) => ({ key, value })));
        },
 
+       calculateAdditionalCDIdx: function() {
+           let me = this;
+
+           let maxIde = me.getMaxControllerId('ide');
+           let maxSata = me.getMaxControllerId('sata');
+           // only ide0 and ide2 can be used reliably for isos (e.g. for q35)
+           if (maxIde < 0) {
+               return 'ide0';
+           }
+           if (maxIde < 2) {
+               return 'ide2';
+           }
+           if (maxSata < PVE.Utils.diskControllerMaxIDs.sata - 1) {
+               return `sata${maxSata+1}`;
+           }
+
+           return '';
+       },
+
        // assume assigned sata disks indices are continuous, so without holes
-       getMaxSata: function() {
+       getMaxControllerId: function(controller) {
            let me = this;
            let view = me.getView();
-           if (view.maxSata !== undefined) {
-               return view.maxSata;
+           if (!controller) {
+               return -1;
+           }
+
+           let max = view[`max${controller}`];
+           if (max !== undefined) {
+               return max;
            }
 
-           view.maxSata = -1;
+           max = -1;
            for (const key of Object.keys(me.getView().vmConfig)) {
-               if (!key.toLowerCase().startsWith('sata')) {
+               if (!key.toLowerCase().startsWith(controller)) {
                    continue;
                }
-               let idx = parseInt(key.slice(4), 10);
-               if (idx > view.maxSata) {
-                   view.maxSata = idx;
+               let idx = parseInt(key.slice(controller.length), 10);
+               if (idx > max) {
+                   max = idx;
                }
            }
            me.lookup('diskGrid').getStore().each(rec => {
-               if (!rec.data.id.toLowerCase().startsWith('sata')) {
+               if (!rec.data.id.toLowerCase().startsWith(controller)) {
                    return;
                }
-               let idx = parseInt(rec.data.id.slice(4), 10);
-               if (idx > view.maxSata) {
-                   view.maxSata = idx;
+               let idx = parseInt(rec.data.id.slice(controller.length), 10);
+               if (idx > max) {
+                   max = idx;
                }
            });
            me.lookup('cdGrid').getStore().each(rec => {
-               if (!rec.data.id.toLowerCase().startsWith('sata')) {
+               if (!rec.data.id.toLowerCase().startsWith(controller) || rec.data.hidden) {
                    return;
                }
-               let idx = parseInt(rec.data.id.slice(4), 10);
-               if (idx > view.maxSata) {
-                   view.maxSata = idx;
+               let idx = parseInt(rec.data.id.slice(controller.length), 10);
+               if (idx > max) {
+                   max = idx;
                }
            });
 
-           return view.maxSata;
+           view[`max${controller}`] = max;
+           return max;
        },
 
        mapDisk: function(value, metaData) {
@@ -142,8 +167,12 @@ Ext.define('PVE.window.GuestImport', {
                return value;
            }
            let offset = parseInt(value.slice(4), 10);
-           let newIdx = offset + me.getMaxSata() + 1;
-           if (newIdx > PVE.Utils.diskControllerMaxIDs.sata) {
+           let newIdx = offset + me.getMaxControllerId('sata') + 1;
+           if (me.getViewModel().get('isWindows') && me.getView().additionalCdIdx?.startsWith('sata')) {
+               // additionalCdIdx takes the highest sata port
+               newIdx++;
+           }
+           if (newIdx >= PVE.Utils.diskControllerMaxIDs.sata) {
                let prefix = '';
                if (metaData !== undefined) {
                    // we're in the renderer so put a warning here
@@ -155,14 +184,45 @@ Ext.define('PVE.window.GuestImport', {
            return `sata${newIdx}`;
        },
 
-       refreshDiskGrid: function() {
+       refreshGrids: function() {
            this.lookup('diskGrid').reconfigure();
+           this.lookup('cdGrid').reconfigure();
+       },
+
+       onOSTypeChange: function(_cb, value) {
+           let me = this;
+           if (!value) {
+               return;
+           }
+           let store = me.lookup('cdGrid').getStore();
+           let collection = store.getData().getSource() ?? store.getData();
+           let rec = collection.find('autogenerated', true);
+
+           let isWindows = (value ?? '').startsWith('w');
+           if (rec) {
+               rec.set('hidden', !isWindows);
+               rec.commit();
+           }
+           let prepareVirtio = me.lookup('mapSata').getValue();
+           me.lookup('scsihw').setValue(prepareVirtio && isWindows ? 'virtio-scsi-single' : me.getView().vmConfig.scsihw);
+
+           me.refreshGrids();
+       },
+
+       onPrepareVirtioChange: function(_cb, value) {
+           let me = this;
+
+           let scsihw = me.lookup('scsihw');
+           scsihw.suspendEvents();
+           scsihw.setValue(value ? 'virtio-scsi-single' : me.getView().vmConfig.scsihw);
+           scsihw.resumeEvents();
+
+           me.refreshGrids();
        },
 
-       toggleIsoSelector: function(_cb, value) {
+       onScsiHwChange: function(_field, value) {
            let me = this;
-           me.lookup('isoSelector').setDisabled(!value);
-           me.lookup('isoSelector').setHidden(!value);
+           me.getView().vmConfig.scsihw = value;
        },
 
        control: {
@@ -187,13 +247,13 @@ Ext.define('PVE.window.GuestImport', {
                activate: 'calculateConfig',
            },
            'proxmoxcheckbox[reference=mapSata]': {
-               change: 'refreshDiskGrid',
+               change: 'onPrepareVirtioChange',
            },
            'combobox[name=ostype]': {
-               change: 'refreshDiskGrid',
+               change: 'onOSTypeChange',
            },
-           'proxmoxcheckbox[reference=enableSecondCD]': {
-               change: 'toggleIsoSelector',
+           'pveScsiHwSelector': {
+               change: 'onScsiHwChange',
            },
        },
     },
@@ -203,7 +263,8 @@ Ext.define('PVE.window.GuestImport', {
            coreCount: 1,
            socketCount: 1,
            liveImport: false,
-           os: '',
+           os: 'l26',
+           maxCdDrives: false,
            warnings: [],
        },
 
@@ -214,7 +275,7 @@ Ext.define('PVE.window.GuestImport', {
                + get('warnings').map(w => `<li>${w}</li>`).join('') + '</ul>',
            liveImportNote: get => !get('liveImport') ? ''
                : gettext('Note: If anything goes wrong during the live-import, new data written by the VM may be lost.'),
-           isWindows: get => (get('os') ?? '').startsWith('win'),
+           isWindows: get => (get('os') ?? '').startsWith('w'),
        },
     },
 
@@ -323,27 +384,6 @@ Ext.define('PVE.window.GuestImport', {
                            config['live-restore'] = 1;
                        }
 
-                       if (grid.lookup('enableSecondCD')) {
-                           let idsToTry = ['ide0', 'ide2'];
-                           for (let i = 0; i <=PVE.Utils.diskControllerMaxIDs.sata; i++) {
-                               idsToTry.push(`sata{$i}`);
-                           }
-                           let found = false;
-                           for (const id of idsToTry) {
-                               if (!config[id]) {
-                                   config[id] = PVE.Parser.printQemuDrive({
-                                       media: 'cdrom',
-                                       file: grid.lookup('isoSelector').getValue(),
-                                   });
-                                   found = true;
-                                   break;
-                               }
-                           }
-                           if (!found) {
-                               console.warn('could not insert cd drive for virtio');
-                           }
-                       }
-
                        // remove __default__ values
                        for (const [key, value] of Object.entries(config)) {
                            if (value === '__default__') {
@@ -369,7 +409,7 @@ Ext.define('PVE.window.GuestImport', {
                            reference: 'socketsField',
                            value: 1,
                            minValue: 1,
-                           maxValue: 4,
+                           maxValue: 128,
                            allowBlank: true,
                            bind: {
                                value: '{socketCount}',
@@ -382,7 +422,7 @@ Ext.define('PVE.window.GuestImport', {
                            reference: 'coresField',
                            value: 1,
                            minValue: 1,
-                           maxValue: 128,
+                           maxValue: 1024,
                            allowBlank: true,
                            bind: {
                                value: '{coreCount}',
@@ -390,16 +430,14 @@ Ext.define('PVE.window.GuestImport', {
                        },
                        {
                            xtype: 'pveMemoryField',
-                           fieldLabel: gettext('Memory'),
+                           fieldLabel: gettext('Memory') + ' (MiB)',
                            name: 'memory',
                            reference: 'memoryField',
                            value: 512,
                            allowBlank: true,
                        },
-                       {
-                           //spacer
-                           xtype: 'displayfield',
-                       },
+                       { xtype: 'displayfield' }, // spacer
+                       { xtype: 'displayfield' }, // spacer
                        {
                            xtype: 'pveDiskStorageSelector',
                            reference: 'defaultStorage',
@@ -425,7 +463,7 @@ Ext.define('PVE.window.GuestImport', {
                            name: 'cpu',
                            reference: 'cputype',
                            value: 'x86-64-v2-AES',
-                           fieldLabel: gettext('Type'),
+                           fieldLabel: gettext('CPU Type'),
                        },
                        {
                            xtype: 'displayfield',
@@ -465,6 +503,7 @@ Ext.define('PVE.window.GuestImport', {
                                data: PVE.Utils.kvm_ostypes.Linux,
                            },
                        },
+                       { xtype: 'displayfield' }, // spacer
                        {
                            xtype: 'PVE.form.BridgeSelector',
                            reference: 'defaultBridge',
@@ -513,59 +552,8 @@ Ext.define('PVE.window.GuestImport', {
 
                    // the first inputpanel handles all values, so prevent value leakage here
                    onGetValues: () => ({}),
-                   column1: [
-                       {
-                           xtype: 'pveScsiHwSelector',
-                           reference: 'scsihw',
-                           name: 'scsihw',
-                           submitValue: false,
-                           fieldLabel: gettext('SCSI Controller'),
-                       },
-                       {
-                           xtype: 'proxmoxcheckbox',
-                           reference: 'enableSecondCD',
-                           isFormField: false,
-                           hidden: true,
-                           checked: false,
-                           boxLabel: gettext('Add additional drive for VirtIO drivers'),
-                           bind: {
-                               hidden: '{!isWindows}',
-                               disabled: '{!isWindows}',
-                           },
-                       },
-                   ],
 
-                   column2: [
-                       {
-                           xtype: 'proxmoxcheckbox',
-                           fieldLabel: gettext('Map SCSI to SATA'),
-                           labelWidth: 120,
-                           reference: 'mapSata',
-                           isFormField: false,
-                           hidden: true,
-                           disabled: true,
-                           bind: {
-                               hidden: '{!isWindows}',
-                               disabled: '{!isWindows}',
-                           },
-                           autoEl: {
-                               tag: 'div',
-                               'data-qtip': gettext('Useful for a quicker switch to VirtIO-SCSI attached disks'),
-                           },
-                       },
-                       {
-                           xtype: 'pveIsoSelector',
-                           reference: 'isoSelector',
-                           submitValue: false,
-                           labelWidth: 120,
-                           labelAlign: 'left',
-                           insideWizard: true,
-                           hidden: true,
-                           disabled: true,
-                       },
-                   ],
-
-                   columnB: [
+                   columnT: [
                        {
                            xtype: 'displayfield',
                            fieldLabel: gettext('Disks'),
@@ -648,13 +636,41 @@ Ext.define('PVE.window.GuestImport', {
                                },
                            ],
                        },
+                   ],
+
+                   column1: [
+                       {
+                           xtype: 'proxmoxcheckbox',
+                           fieldLabel: gettext('Prepare for VirtIO-SCSI'),
+                           labelWidth: 200,
+                           reference: 'mapSata',
+                           isFormField: false,
+                           disabled: true,
+                           bind: {
+                               disabled: '{!isWindows}',
+                           },
+                           autoEl: {
+                               tag: 'div',
+                               'data-qtip': gettext('Maps SCSI disks to SATA and changes the SCSI Controller. Useful for a quicker switch to VirtIO-SCSI attached disks'),
+                           },
+                       },
+                   ],
+
+                   column2: [
+                       {
+                           xtype: 'pveScsiHwSelector',
+                           reference: 'scsihw',
+                           name: 'scsihw',
+                           submitValue: false,
+                           fieldLabel: gettext('SCSI Controller'),
+                       },
+                   ],
+
+                   columnB: [
                        {
                            xtype: 'displayfield',
                            fieldLabel: gettext('CD/DVD Drives'),
                            labelWidth: 200,
-                           style: {
-                               paddingTop: '10px',
-                           },
                        },
                        {
                            xtype: 'grid',
@@ -666,6 +682,11 @@ Ext.define('PVE.window.GuestImport', {
                                sorters: [
                                    'id',
                                ],
+                               filters: [
+                                   function(rec) {
+                                       return !rec.data.hidden;
+                                   },
+                               ],
                            },
                            columns: [
                                {
@@ -835,7 +856,6 @@ Ext.define('PVE.window.GuestImport', {
 
        me.lookup('defaultStorage').setNodename(me.nodename);
        me.lookup('defaultBridge').setNodename(me.nodename);
-       me.lookup('isoSelector').setNodename(me.nodename);
 
        let renderWarning = w => {
            const warningsCatalogue = {
@@ -888,14 +908,29 @@ Ext.define('PVE.window.GuestImport', {
                    }
                    cdroms.push({
                        enable: true,
+                       hidden: false,
                        id,
                    });
                    delete me.vmConfig[id];
                }
+
                me.lookup('diskGrid').getStore().setData(disks);
                me.lookup('netGrid').getStore().setData(nets);
                me.lookup('cdGrid').getStore().setData(cdroms);
 
+               let additionalCdIdx = me.getController().calculateAdditionalCDIdx();
+               if (additionalCdIdx === '') {
+                   me.getViewModel().set('maxCdDrives', true);
+               } else if (cdroms.length === 0) {
+                   me.additionalCdIdx = additionalCdIdx;
+                   me.lookup('cdGrid').getStore().add({
+                       enable: true,
+                       hidden: !(me.vmConfig.ostype ?? '').startsWith('w'),
+                       id: additionalCdIdx,
+                       autogenerated: true,
+                   });
+               }
+
                me.getViewModel().set('warnings', data.warnings.map(w => renderWarning(w)));
 
                let osinfo = PVE.Utils.get_kvm_osinfo(me.vmConfig.ostype ?? '');