]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/window/GuestImport.js
1 Ext
.define('PVE.window.GuestImport', {
2 extend
: 'Proxmox.window.Edit', // fixme: Proxmox.window.Edit?
3 alias
: 'widget.pveGuestImportWindow',
5 title
: gettext('Import Guest'),
7 submitUrl: function() {
9 return `/nodes/${me.nodename}/qemu`;
14 submitText
: gettext('Import'),
18 loadUrl: function(_url
, { storage
, nodename
, volumeName
}) {
19 let args
= Ext
.Object
.toQueryString({ volume
: volumeName
});
20 return `/nodes/${nodename}/storage/${storage}/import-metadata?${args}`;
24 xclass
: 'Ext.app.ViewController',
26 setNodename: function(_column
, widget
) {
28 let view
= me
.getView();
29 widget
.setNodename(view
.nodename
);
32 storageChange: function(storageSelector
, value
) {
35 let grid
= me
.lookup('diskGrid');
36 let rec
= storageSelector
.getWidgetRecord();
37 let validFormats
= storageSelector
.store
.getById(value
).data
.format
;
38 grid
.query('pveDiskFormatSelector').some((selector
) => {
39 if (selector
.getWidgetRecord().data
.id
!== rec
.data
.id
) {
43 if (validFormats
?.[0]?.qcow2
) {
44 selector
.setDisabled(false);
45 selector
.setValue('qcow2');
47 selector
.setValue('raw');
48 selector
.setDisabled(true);
55 onOSBaseChange: function(_field
, value
) {
57 let ostype
= me
.lookup('ostype');
58 let store
= ostype
.getStore();
59 store
.setData(PVE
.Utils
.kvm_ostypes
[value
]);
60 let old_val
= ostype
.getValue();
61 if (old_val
&& store
.find('val', old_val
) !== -1) {
62 ostype
.setValue(old_val
);
64 ostype
.setValue(store
.getAt(0));
70 // update records from widgetcolumns
71 change: function(widget
, value
) {
72 let rec
= widget
.getWidgetRecord();
73 rec
.set(widget
.name
, value
);
77 'pveStorageSelector': {
78 change
: 'storageChange',
80 'field[name=osbase]': {
81 change
: 'onOSBaseChange',
94 totalCoreCount
: get => get('socketCount') * get('coreCount'),
95 hideWarnings
: get => get('warnings').length
=== 0,
96 warningsText
: get => '<ul style="margin: 0; padding-left: 20px;">'
97 + get('warnings').map(w
=> `<li>${w}</li>`).join('') + '</ul>',
104 onGetValues: function(values
) {
106 let grid
= me
.up('pveGuestImportWindow');
108 let config
= Ext
.apply(grid
.vmConfig
, values
);
111 config
.scsi0
= config
.scsi0
.replace('local:0,', 'local:0,format=qcow2,');
114 grid
.lookup('diskGrid').getStore().each((rec
) => {
115 if (!rec
.data
.enable
) {
118 let id
= rec
.data
.id
;
119 delete rec
.data
.enable
;
121 rec
.data
.file
+= ':0'; // for our special api format
122 if (id
=== 'efidisk0') {
123 delete rec
.data
['import-from'];
125 config
[id
] = PVE
.Parser
.printQemuDrive(rec
.data
);
128 grid
.lookup('netGrid').getStore().each((rec
) => {
129 if (!rec
.data
.enable
) {
132 let id
= rec
.data
.id
;
133 delete rec
.data
.enable
;
135 config
[id
] = PVE
.Parser
.printQemuNetwork(rec
.data
);
138 if (grid
.lookup('liveimport').getValue()) {
139 config
['live-restore'] = 1;
147 xtype
: 'pveGuestIDSelector',
151 loadNextFreeID
: true,
154 xtype
: 'proxmoxintegerfield',
155 fieldLabel
: gettext('Sockets'),
157 reference
: 'socketsField',
163 value
: '{socketCount}',
167 xtype
: 'proxmoxintegerfield',
168 fieldLabel
: gettext('Cores'),
170 reference
: 'coresField',
176 value
: '{coreCount}',
180 xtype
: 'pveMemoryField',
181 fieldLabel
: gettext('Memory'),
183 reference
: 'memoryField',
192 fieldLabel
: gettext('Name'),
195 reference
: 'nameField',
199 xtype
: 'CPUModelSelector',
201 reference
: 'cputype',
202 value
: 'x86-64-v2-AES',
203 fieldLabel
: gettext('Type'),
206 xtype
: 'displayfield',
207 fieldLabel
: gettext('Total cores'),
211 value
: '{totalCoreCount}',
218 fieldLabel
: gettext('OS Type'),
222 store
: Object
.keys(PVE
.Utils
.kvm_ostypes
),
228 fieldLabel
: gettext('Version'),
234 displayField
: 'desc',
236 fields
: ['desc', 'val'],
237 data
: PVE
.Utils
.kvm_ostypes
.Linux
,
243 xtype
: 'displayfield',
244 fieldLabel
: gettext('Disks'),
249 reference
: 'diskGrid',
254 xtype
: 'checkcolumn',
255 header
: gettext('Use'),
259 checkchange: function(_column
, _rowIndex
, _checked
, record
) {
265 text
: gettext('Disk'),
269 text
: gettext('Source'),
270 dataIndex
: 'import-from',
272 renderer: function(value
) {
273 return value
.replace(/^.*\//, '');
277 text
: gettext('Storage'),
279 xtype
: 'widgetcolumn',
282 xtype
: 'pveStorageSelector',
285 storageContent
: 'images',
287 onWidgetAttach
: 'setNodename',
290 text
: gettext('Format'),
292 xtype
: 'widgetcolumn',
295 xtype
: 'pveDiskFormatSelector',
298 matchFieldWidth
: false,
304 xtype
: 'displayfield',
305 fieldLabel
: gettext('Network Interfaces'),
311 reference
: 'netGrid',
315 xtype
: 'checkcolumn',
316 header
: gettext('Use'),
320 checkchange: function(_column
, _rowIndex
, _checked
, record
) {
330 text
: gettext('MAC address'),
332 dataIndex
: 'macaddr',
335 text
: gettext('Model'),
340 text
: gettext('Bridge'),
342 xtype
: 'widgetcolumn',
344 xtype
: 'PVE.form.BridgeSelector',
349 onWidgetAttach
: 'setNodename',
354 xtype
: 'displayfield',
355 fieldLabel
: gettext('Warnings'),
359 hidden
: '{hideWarnings}',
363 xtype
: 'displayfield',
364 reference
: 'warningText',
368 hidden
: '{hideWarnings}',
369 value
: '{warningsText}',
376 initComponent: function() {
379 if (!me
.volumeName
) {
380 throw "no volumeName given";
384 throw "no storage given";
388 throw "no nodename given";
393 me
.query('toolbar')?.[0]?.insert(0, {
394 xtype
: 'proxmoxcheckbox',
395 reference
: 'liveimport',
396 boxLabelAlign
: 'before',
397 boxLabel
: gettext('Live Import'),
400 me
.setTitle(Ext
.String
.format(gettext('Import Guest - {0}'), `${me.storage}:${me.volumeName}`));
402 let renderWarning
= w
=> {
403 const warningsCatalogue
= {
404 'cdrom-image-ignored': gettext("CD-ROM images cannot get imported, please reconfigure the '{0}' drive after the import"),
405 'nvme-unsupported': gettext("NVMe disks are currently not supported, '{0}' will get attaced as SCSI"),
406 'ovmf-with-lsi-unsupported': gettext("OVMF is built without LSI drivers, scsi hardware was set to '{1}'"),
407 'serial-port-socket-only': gettext("Serial socket '{0}' will be mapped to a socket"),
409 let message
= warningsCatalogue
[w
.type
];
410 if (!w
.type
|| !message
) {
411 return w
.message
?? w
.type
?? gettext('Unknown warning');
413 return Ext
.String
.format(message
, w
.key
?? 'unknown', w
.value
?? 'unknown');
417 success: function(response
) {
418 let data
= response
.result
.data
;
419 me
.vmConfig
= data
['create-args'];
422 for (const [id
, value
] of Object
.entries(data
.disks
?? {})) {
426 'import-from': id
=== 'efidisk0' ? Ext
.htmlEncode('<none>') : value
,
432 for (const [id
, parsed
] of Object
.entries(data
.net
?? {})) {
434 parsed
.enable
= true;
437 me
.lookup('diskGrid').getStore().setData(disks
);
438 me
.lookup('netGrid').getStore().setData(nets
);
440 me
.getViewModel().set('warnings', data
.warnings
.map(w
=> renderWarning(w
)));
442 let osinfo
= PVE
.Utils
.get_kvm_osinfo(me
.vmConfig
.ostype
?? '');