]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/window/PCIMapEdit.js
ui: pci map edit: reintroduce warnings checks
[pve-manager.git] / www / manager6 / window / PCIMapEdit.js
CommitLineData
2ffe0f32
DC
1Ext.define('PVE.window.PCIMapEditWindow', {
2 extend: 'Proxmox.window.Edit',
3
4 mixins: ['Proxmox.Mixin.CBind'],
5
6 width: 800,
7
8 subject: gettext('PCI mapping'),
9
10 onlineHelp: 'resource_mapping',
11
12 method: 'POST',
13
14 cbindData: function(initialConfig) {
15 let me = this;
bd712824
DC
16 me.isCreate = !me.name || !me.nodename;
17 me.method = me.name ? 'PUT' : 'POST';
2ffe0f32
DC
18 return {
19 name: me.name,
20 nodename: me.nodename,
21 };
22 },
23
24 submitUrl: function(_url, data) {
25 let me = this;
bd712824 26 let name = me.method === 'PUT' ? me.name : '';
2ffe0f32
DC
27 return `/cluster/mapping/pci/${name}`;
28 },
29
30 controller: {
31 xclass: 'Ext.app.ViewController',
32
33 onGetValues: function(values) {
34 let me = this;
35 let view = me.getView();
36 if (view.method === "POST") {
37 delete me.digest;
38 }
39
40 if (values.iommugroup === -1) {
41 delete values.iommugroup;
42 }
43
44 let nodename = values.node ?? view.nodename;
45 delete values.node;
46 if (me.originalMap) {
47 let otherMaps = PVE.Parser
48 .filterPropertyStringList(me.originalMap, (e) => e.node !== nodename);
49 if (otherMaps.length) {
50 values.map = values.map.concat(otherMaps);
51 }
52 }
53
54 return values;
55 },
56
57 onSetValues: function(values) {
58 let me = this;
59 let view = me.getView();
60 me.originalMap = [...values.map];
61 values.map = PVE.Parser.filterPropertyStringList(values.map, (e) => e.node === view.nodename);
62 return values;
63 },
64
65 checkIommu: function(store, records, success) {
66 let me = this;
67 if (!success || !records.length) {
68 return;
69 }
70 me.lookup('iommu_warning').setVisible(
71 records.every((val) => val.data.iommugroup === -1),
72 );
e633ac0f
DC
73
74 let value = me.lookup('pciselector').getValue();
75 me.checkIsolated(value);
76 },
77
78 checkIsolated: function(value) {
79 let me = this;
80
81 let store = me.lookup('pciselector').getStore();
82
83 let isIsolated = function(entry) {
84 let isolated = true;
85 let parsed = PVE.Parser.parsePropertyString(entry);
86 parsed.iommugroup = parseInt(parsed.iommugroup, 10);
87 if (!parsed.iommugroup) {
88 return isolated;
89 }
90 store.each(({ data }) => {
91 let isSubDevice = data.id.startsWith(parsed.path);
92 if (data.iommugroup === parsed.iommugroup && data.id !== parsed.path && !isSubDevice) {
93 isolated = false;
94 return false;
95 }
96 return true;
97 });
98 return isolated;
99 };
100
101 let showWarning = false;
102 if (Ext.isArray(value)) {
103 for (const entry of value) {
104 if (!isIsolated(entry)) {
105 showWarning = true;
106 break;
107 }
108 }
109 } else {
110 showWarning = isIsolated(value);
111 }
112 me.lookup('group_warning').setVisible(showWarning);
2ffe0f32
DC
113 },
114
115 mdevChange: function(mdevField, value) {
116 this.lookup('pciselector').setMdev(value);
117 },
118
119 nodeChange: function(_field, value) {
120 this.lookup('pciselector').setNodename(value);
121 },
122
123 pciChange: function(_field, value) {
124 let me = this;
125 me.lookup('multiple_warning').setVisible(Ext.isArray(value) && value.length > 1);
e633ac0f 126 me.checkIsolated(value);
2ffe0f32
DC
127 },
128
129 control: {
130 'field[name=mdev]': {
131 change: 'mdevChange',
132 },
133 'pveNodeSelector': {
134 change: 'nodeChange',
135 },
136 'pveMultiPCISelector': {
137 change: 'pciChange',
138 },
139 },
140 },
141
142 items: [
143 {
144 xtype: 'inputpanel',
145 onGetValues: function(values) {
146 return this.up('window').getController().onGetValues(values);
147 },
148
149 onSetValues: function(values) {
150 return this.up('window').getController().onSetValues(values);
151 },
152
153 columnT: [
154 {
155 xtype: 'displayfield',
156 reference: 'iommu_warning',
157 hidden: true,
158 columnWidth: 1,
159 padding: '0 0 10 0',
160 value: 'No IOMMU detected, please activate it.' +
161 'See Documentation for further information.',
162 userCls: 'pmx-hint',
163 },
164 {
165 xtype: 'displayfield',
166 reference: 'multiple_warning',
167 hidden: true,
168 columnWidth: 1,
169 padding: '0 0 10 0',
170 value: 'When multiple devices are selected, the first free one will be chosen' +
171 ' on guest start.',
172 userCls: 'pmx-hint',
173 },
174 {
175 xtype: 'displayfield',
176 reference: 'group_warning',
177 hidden: true,
178 columnWidth: 1,
179 padding: '0 0 10 0',
180 itemId: 'iommuwarning',
181 value: 'The selected Device is not in a seperate IOMMU group, make sure this is intended.',
182 userCls: 'pmx-hint',
183 },
184 ],
185
186 column1: [
187 {
188 xtype: 'pmxDisplayEditField',
189 fieldLabel: gettext('Name'),
190 labelWidth: 120,
191 cbind: {
192 editable: '{!name}',
193 value: '{name}',
194 submitValue: '{isCreate}',
195 },
196 name: 'id',
197 allowBlank: false,
198 },
2ffe0f32
DC
199 {
200 xtype: 'pmxDisplayEditField',
bd712824 201 fieldLabel: gettext('Mapping on Node'),
2ffe0f32
DC
202 labelWidth: 120,
203 name: 'node',
204 editConfig: {
205 xtype: 'pveNodeSelector',
206 },
207 cbind: {
208 editable: '{!nodename}',
209 value: '{nodename}',
210 },
211 allowBlank: false,
212 },
213 ],
214
bd712824
DC
215 column2: [
216 {
217 // as spacer
218 xtype: 'displayfield',
219 },
220 {
221 xtype: 'proxmoxcheckbox',
222 fieldLabel: gettext('Mediated Devices'),
223 labelWidth: 120,
224 reference: 'mdev',
225 name: 'mdev',
226 cbind: {
227 deleteEmpty: '{!isCreate}',
228 },
229 },
230 ],
231
2ffe0f32
DC
232 columnB: [
233 {
234 xtype: 'pveMultiPCISelector',
235 fieldLabel: gettext('Device'),
236 labelWidth: 120,
237 height: 300,
238 reference: 'pciselector',
239 name: 'map',
240 cbind: {
241 nodename: '{nodename}',
242 },
243 allowBlank: false,
244 onLoadCallBack: 'checkIommu',
245 margin: '0 0 10 0',
246 },
247 {
248 xtype: 'proxmoxtextfield',
249 fieldLabel: gettext('Comment'),
250 labelWidth: 120,
251 submitValue: true,
252 name: 'description',
253 cbind: {
254 deleteEmpty: '{!isCreate}',
255 },
256 },
257 ],
258 },
259 ],
260});