]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/qemu/BootOrderEdit.js
1 Ext
.define('pve-boot-order-entry', {
2 extend
: 'Ext.data.Model',
4 { name
: 'name', type
: 'string' },
5 { name
: 'enabled', type
: 'bool' },
6 { name
: 'desc', type
: 'string' },
10 Ext
.define('PVE.qemu.BootOrderPanel', {
11 extend
: 'Proxmox.panel.InputPanel',
12 alias
: 'widget.pveQemuBootOrderPanel',
14 onlineHelp
: 'qm_bootorder',
16 vmconfig
: {}, // store loaded vm config
21 xclass
: 'Ext.app.ViewController',
24 isCloudinit
: (v
) => v
.match(/media=cdrom/) && v
.match(/[:/]vm
-\d
+-cloudinit
/),
26 isDisk: function(value
) {
27 return PVE
.Utils
.bus_match
.test(value
);
30 isBootdev: function(dev
, value
) {
31 return (this.isDisk(dev
) && !this.isCloudinit(value
)) ||
32 (/^net\d+/).test(dev
) ||
33 (/^hostpci\d+/).test(dev
) ||
34 ((/^usb\d+/).test(dev
) && !(/spice/).test(value
));
37 setVMConfig: function(vmconfig
) {
39 me
.vmconfig
= vmconfig
;
43 let boot
= PVE
.Parser
.parsePropertyString(me
.vmconfig
.boot
, "legacy");
47 bootorder
= boot
.order
.split(';').map(dev
=> ({ name
: dev
, enabled
: true }));
48 } else if (!(/^\s*$/).test(me
.vmconfig
.boot
)) {
49 // legacy style, transform to new bootorder
50 let order
= boot
.legacy
|| 'cdn';
51 let bootdisk
= me
.vmconfig
.bootdisk
|| undefined;
53 // get the first 4 characters (acdn)
54 // ignore the rest (there should never be more than 4)
55 let orderList
= order
.split('').slice(0, 4);
58 for (let i
= 0; i
< orderList
.length
; i
++) {
60 if (orderList
[i
] === 'c') {
61 if (bootdisk
!== undefined && me
.vmconfig
[bootdisk
]) {
64 } else if (orderList
[i
] === 'd') {
65 Ext
.Object
.each(me
.vmconfig
, function(key
, value
) {
66 if (me
.isDisk(key
) && value
.match(/media=cdrom/) && !me
.isCloudinit(value
)) {
70 } else if (orderList
[i
] === 'n') {
71 Ext
.Object
.each(me
.vmconfig
, function(key
, value
) {
72 if ((/^net\d+/).test(key
)) {
78 // Object.each iterates in random order, sort alphabetically
80 list
.forEach(dev
=> bootorder
.push({ name
: dev
, enabled
: true }));
84 // add disabled devices as well
86 Ext
.Object
.each(me
.vmconfig
, function(key
, value
) {
87 if (me
.isBootdev(key
, value
) &&
88 !Ext
.Array
.some(bootorder
, x
=> x
.name
=== key
)) {
93 disabled
.forEach(dev
=> bootorder
.push({ name
: dev
, enabled
: false }));
96 bootorder
.forEach(entry
=> {
97 entry
.desc
= me
.vmconfig
[entry
.name
];
100 me
.store
.insert(0, bootorder
);
101 me
.store
.fireEvent("update");
104 calculateValue: function() {
106 return me
.store
.getData().items
107 .filter(x
=> x
.data
.enabled
)
108 .map(x
=> x
.data
.name
)
112 onGetValues: function() {
114 // Note: we allow an empty value, so no 'delete' option
115 let val
= { order
: me
.calculateValue() };
116 let res
= { boot
: PVE
.Parser
.printPropertyString(val
) };
135 renderer
: (value
, metaData
, record
, rowIndex
) => {
136 let dragHandle
= "<i class='pve-grid-fa fa fa-fw fa-reorder cursor-move'></i>";
137 let idx
= (rowIndex
+ 1).toString();
138 if (record
.get('enabled')) {
139 return dragHandle
+ idx
;
141 return dragHandle
+ "<span class='faded'>" + idx
+ "</span>";
146 xtype
: 'checkcolumn',
147 header
: gettext('Enabled'),
148 dataIndex
: 'enabled',
152 header
: gettext('Device'),
155 renderer
: (value
, metaData
, record
, rowIndex
) => {
156 let desc
= record
.get('desc');
158 let icon
= '', iconCls
;
159 if (value
.match(/^net\d+$/)) {
160 iconCls
= 'exchange';
161 } else if (desc
.match(/media=cdrom/)) {
162 metaData
.tdCls
= 'pve-itype-icon-cdrom';
166 if (iconCls
!== undefined) {
167 metaData
.tdCls
+= 'pve-itype-fa';
168 icon
= `<i class="pve-grid-fa fa fa-fw fa-${iconCls}"></i>`;
175 header
: gettext('Description'),
182 ptype
: 'gridviewdragdrop',
183 dragText
: gettext('Drag and drop to reorder'),
188 // doesn't fire automatically on reorder
189 this.getStore().fireEvent("update");
195 html
: gettext('Drag and drop to reorder'),
198 xtype
: 'displayfield',
199 reference
: 'emptyWarning',
201 value
: gettext('Warning: No devices selected, the VM will probably not boot!'),
204 // for dirty marking and 'reset' function
208 setValue: function(val
) {
210 let panel
= me
.up('pveQemuBootOrderPanel');
212 // on form reset, go back to original state
213 if (!panel
.inUpdate
) {
214 panel
.setVMConfig(panel
.vmconfig
);
217 // not a subclass, so no callParent; just do it manually
218 me
.setRawValue(me
.valueToRaw(val
));
219 return me
.mixins
.field
.setValue
.call(me
, val
);
224 initComponent: function() {
229 let controller
= me
.getController();
231 let grid
= controller
.lookup('grid');
232 let marker
= controller
.lookup('marker');
233 let emptyWarning
= controller
.lookup('emptyWarning');
235 marker
.originalValue
= undefined;
237 me
.store
= Ext
.create('Ext.data.Store', {
238 model
: 'pve-boot-order-entry',
241 this.commitChanges();
242 let val
= me
.calculateValue();
243 if (marker
.originalValue
=== undefined) {
244 marker
.originalValue
= val
;
247 marker
.setValue(val
);
250 emptyWarning
.setHidden(val
!== '');
251 grid
.getView().refresh();
255 grid
.setStore(me
.store
);
259 Ext
.define('PVE.qemu.BootOrderEdit', {
260 extend
: 'Proxmox.window.Edit',
263 xtype
: 'pveQemuBootOrderPanel',
264 itemId
: 'inputpanel',
267 subject
: gettext('Boot Order'),
270 initComponent: function() {
274 success: function(response
, options
) {
275 me
.down('#inputpanel').setVMConfig(response
.result
.data
);