]>
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',
23 init: function(view
) {
26 let grid
= me
.lookup('grid');
27 let marker
= me
.lookup('marker');
28 let emptyWarning
= me
.lookup('emptyWarning');
30 marker
.originalValue
= undefined;
32 view
.store
= Ext
.create('Ext.data.Store', {
33 model
: 'pve-boot-order-entry',
37 let val
= view
.calculateValue();
38 if (marker
.originalValue
=== undefined) {
39 marker
.originalValue
= val
;
43 view
.inUpdate
= false;
45 emptyWarning
.setHidden(val
!== '');
46 grid
.getView().refresh();
50 grid
.setStore(view
.store
);
54 isCloudinit
: (v
) => v
.match(/media=cdrom/) && v
.match(/[:/]vm
-\d
+-cloudinit
/),
56 isDisk: function(value
) {
57 return PVE
.Utils
.bus_match
.test(value
);
60 isBootdev: function(dev
, value
) {
61 return (this.isDisk(dev
) && !this.isCloudinit(value
)) ||
62 (/^net\d+/).test(dev
) ||
63 (/^hostpci\d+/).test(dev
) ||
64 ((/^usb\d+/).test(dev
) && !(/spice/).test(value
));
67 setVMConfig: function(vmconfig
) {
69 me
.vmconfig
= vmconfig
;
73 let boot
= PVE
.Parser
.parsePropertyString(me
.vmconfig
.boot
, "legacy");
77 bootorder
= boot
.order
.split(';').map(dev
=> ({ name
: dev
, enabled
: true }));
78 } else if (!(/^\s*$/).test(me
.vmconfig
.boot
)) {
79 // legacy style, transform to new bootorder
80 let order
= boot
.legacy
|| 'cdn';
81 let bootdisk
= me
.vmconfig
.bootdisk
|| undefined;
83 // get the first 4 characters (acdn)
84 // ignore the rest (there should never be more than 4)
85 let orderList
= order
.split('').slice(0, 4);
88 for (let i
= 0; i
< orderList
.length
; i
++) {
90 if (orderList
[i
] === 'c') {
91 if (bootdisk
!== undefined && me
.vmconfig
[bootdisk
]) {
94 } else if (orderList
[i
] === 'd') {
95 Ext
.Object
.each(me
.vmconfig
, function(key
, value
) {
96 if (me
.isDisk(key
) && value
.match(/media=cdrom/) && !me
.isCloudinit(value
)) {
100 } else if (orderList
[i
] === 'n') {
101 Ext
.Object
.each(me
.vmconfig
, function(key
, value
) {
102 if ((/^net\d+/).test(key
)) {
108 // Object.each iterates in random order, sort alphabetically
110 list
.forEach(dev
=> bootorder
.push({ name
: dev
, enabled
: true }));
114 // add disabled devices as well
116 Ext
.Object
.each(me
.vmconfig
, function(key
, value
) {
117 if (me
.isBootdev(key
, value
) &&
118 !Ext
.Array
.some(bootorder
, x
=> x
.name
=== key
)) {
123 disabled
.forEach(dev
=> bootorder
.push({ name
: dev
, enabled
: false }));
126 bootorder
.forEach(entry
=> {
127 entry
.desc
= me
.vmconfig
[entry
.name
];
130 me
.store
.insert(0, bootorder
);
131 me
.store
.fireEvent("update");
134 calculateValue: function() {
136 return me
.store
.getData().items
137 .filter(x
=> x
.data
.enabled
)
138 .map(x
=> x
.data
.name
)
142 onGetValues: function() {
144 // Note: we allow an empty value, so no 'delete' option
145 let val
= { order
: me
.calculateValue() };
146 let res
= { boot
: PVE
.Parser
.printPropertyString(val
) };
165 renderer
: (value
, metaData
, record
, rowIndex
) => {
166 let dragHandle
= "<i class='pve-grid-fa fa fa-fw fa-reorder cursor-move'></i>";
167 let idx
= (rowIndex
+ 1).toString();
168 if (record
.get('enabled')) {
169 return dragHandle
+ idx
;
171 return dragHandle
+ "<span class='faded'>" + idx
+ "</span>";
176 xtype
: 'checkcolumn',
177 header
: gettext('Enabled'),
178 dataIndex
: 'enabled',
182 header
: gettext('Device'),
185 renderer
: (value
, metaData
, record
, rowIndex
) => {
186 let desc
= record
.get('desc');
188 let icon
= '', iconCls
;
189 if (value
.match(/^net\d+$/)) {
190 iconCls
= 'exchange';
191 } else if (desc
.match(/media=cdrom/)) {
192 metaData
.tdCls
= 'pve-itype-icon-cdrom';
196 if (iconCls
!== undefined) {
197 metaData
.tdCls
+= 'pve-itype-fa';
198 icon
= `<i class="pve-grid-fa fa fa-fw fa-${iconCls}"></i>`;
205 header
: gettext('Description'),
212 ptype
: 'gridviewdragdrop',
213 dragText
: gettext('Drag and drop to reorder'),
218 // doesn't fire automatically on reorder
219 this.getStore().fireEvent("update");
225 html
: gettext('Drag and drop to reorder'),
228 xtype
: 'displayfield',
229 reference
: 'emptyWarning',
231 value
: gettext('Warning: No devices selected, the VM will probably not boot!'),
234 // for dirty marking and 'reset' function
238 setValue: function(val
) {
240 let panel
= me
.up('pveQemuBootOrderPanel');
242 // on form reset, go back to original state
243 if (!panel
.inUpdate
) {
244 panel
.setVMConfig(panel
.vmconfig
);
247 // not a subclass, so no callParent; just do it manually
248 me
.setRawValue(me
.valueToRaw(val
));
249 return me
.mixins
.field
.setValue
.call(me
, val
);
255 Ext
.define('PVE.qemu.BootOrderEdit', {
256 extend
: 'Proxmox.window.Edit',
259 xtype
: 'pveQemuBootOrderPanel',
260 itemId
: 'inputpanel',
263 subject
: gettext('Boot Order'),
266 initComponent: function() {
270 success
: ({ result
}) => me
.down('#inputpanel').setVMConfig(result
.data
),