]>
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 setIsos: function(ignoredVolumes
) {
34 let isos
= Object
.entries(ignoredVolumes
).map(([id
, value
]) => `${id}: ${value.replace(/^.*\//, '')}`);
38 let warning
= gettext('The following cd images were detected, but will not be carried over:');
39 warning
+= '<br>' + isos
.join('<br>');
40 let warnings
= me
.getViewModel().get('warnings');
41 warnings
.push(warning
);
42 me
.getViewModel().set('warnings', warnings
);
45 storageChange: function(storageSelector
, value
) {
48 let grid
= me
.lookup('diskGrid');
49 let rec
= storageSelector
.getWidgetRecord();
50 let validFormats
= storageSelector
.store
.getById(value
).data
.format
;
51 grid
.query('pveDiskFormatSelector').some((selector
) => {
52 if (selector
.getWidgetRecord().data
.id
!== rec
.data
.id
) {
56 if (validFormats
?.[0]?.qcow2
) {
57 selector
.setDisabled(false);
58 selector
.setValue('qcow2');
60 selector
.setValue('raw');
61 selector
.setDisabled(true);
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',
91 totalCoreCount
: get => get('socketCount') * get('coreCount'),
92 hideWarnings
: get => get('warnings').length
=== 0,
93 warningsText
: get => get('warnings').join('<br><br>'),
100 onGetValues: function(values
) {
102 let grid
= me
.up('pveGuestImportWindow');
104 let config
= Ext
.apply(grid
.vmConfig
, values
);
107 config
.scsi0
= config
.scsi0
.replace('local:0,', 'local:0,format=qcow2,');
110 grid
.lookup('diskGrid').getStore().each((rec
) => {
111 if (!rec
.data
.enable
) {
114 let id
= rec
.data
.id
;
115 delete rec
.data
.enable
;
117 rec
.data
.file
+= ':0'; // for our special api format
118 if (id
=== 'efidisk0') {
119 delete rec
.data
['import-from'];
121 config
[id
] = PVE
.Parser
.printQemuDrive(rec
.data
);
124 grid
.lookup('netGrid').getStore().each((rec
) => {
125 if (!rec
.data
.enable
) {
128 let id
= rec
.data
.id
;
129 delete rec
.data
.enable
;
131 config
[id
] = PVE
.Parser
.printQemuNetwork(rec
.data
);
134 if (grid
.lookup('liveimport').getValue()) {
135 config
['live-restore'] = 1;
143 xtype
: 'pveGuestIDSelector',
147 loadNextFreeID
: true,
150 xtype
: 'proxmoxintegerfield',
151 fieldLabel
: gettext('Sockets'),
153 reference
: 'socketsField',
159 value
: '{socketCount}',
163 xtype
: 'proxmoxintegerfield',
164 fieldLabel
: gettext('Cores'),
166 reference
: 'coresField',
172 value
: '{coreCount}',
176 xtype
: 'pveMemoryField',
177 fieldLabel
: gettext('Memory'),
179 reference
: 'memoryField',
188 fieldLabel
: gettext('Name'),
191 reference
: 'nameField',
195 xtype
: 'CPUModelSelector',
197 reference
: 'cputype',
198 value
: 'x86-64-v2-AES',
199 fieldLabel
: gettext('Type'),
202 xtype
: 'displayfield',
203 fieldLabel
: gettext('Total cores'),
207 value
: '{totalCoreCount}',
213 xtype
: 'displayfield',
214 fieldLabel
: gettext('Disks'),
219 reference
: 'diskGrid',
224 xtype
: 'checkcolumn',
225 header
: gettext('Use'),
229 checkchange: function(_column
, _rowIndex
, _checked
, record
) {
235 text
: gettext('Disk'),
239 text
: gettext('Source'),
240 dataIndex
: 'import-from',
242 renderer: function(value
) {
243 return value
.replace(/^.*\//, '');
247 text
: gettext('Storage'),
249 xtype
: 'widgetcolumn',
252 xtype
: 'pveStorageSelector',
255 storageContent
: 'images',
257 onWidgetAttach
: 'setNodename',
260 text
: gettext('Format'),
262 xtype
: 'widgetcolumn',
265 xtype
: 'pveDiskFormatSelector',
268 matchFieldWidth
: false,
274 xtype
: 'displayfield',
275 fieldLabel
: gettext('Network Interfaces'),
281 reference
: 'netGrid',
285 xtype
: 'checkcolumn',
286 header
: gettext('Use'),
290 checkchange: function(_column
, _rowIndex
, _checked
, record
) {
300 text
: gettext('MAC address'),
302 dataIndex
: 'macaddr',
305 text
: gettext('Model'),
310 text
: gettext('Bridge'),
312 xtype
: 'widgetcolumn',
314 xtype
: 'PVE.form.BridgeSelector',
319 onWidgetAttach
: 'setNodename',
324 xtype
: 'displayfield',
325 fieldLabel
: gettext('Warnings'),
329 hidden
: '{hideWarnings}',
333 xtype
: 'displayfield',
334 reference
: 'warningText',
338 hidden
: '{hideWarnings}',
339 value
: '{warningsText}',
346 initComponent: function() {
349 if (!me
.volumeName
) {
350 throw "no volumeName given";
354 throw "no storage given";
358 throw "no nodename given";
363 me
.query('toolbar')?.[0]?.insert(0, {
364 xtype
: 'proxmoxcheckbox',
365 reference
: 'liveimport',
366 boxLabelAlign
: 'before',
367 boxLabel
: gettext('Live Import'),
370 me
.setTitle(Ext
.String
.format(gettext('Import Guest - {0}'), `${me.storage}:${me.volumeName}`));
373 success: function(response
) {
374 let data
= response
.result
.data
;
375 me
.vmConfig
= data
['create-args'];
378 for (const [id
, value
] of Object
.entries(data
.disks
?? {})) {
382 'import-from': id
=== 'efidisk0' ? Ext
.htmlEncode('<none>') : value
,
388 for (const [id
, parsed
] of Object
.entries(data
.net
?? {})) {
390 parsed
.enable
= true;
393 me
.lookup('diskGrid').getStore().setData(disks
);
394 me
.lookup('netGrid').getStore().setData(nets
);
396 me
.getViewModel().set('warnings', data
.warnings
.map(warning
=> warning
.message
));
397 me
.getController().setIsos(data
['ignored-volumes']);
399 me
.setValues(me
.vmConfig
);