]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/Parser.js
qemu: parse vlan trunks
[pve-manager.git] / www / manager6 / Parser.js
1 // Some configuration values are complex strings -
2 // so we need parsers/generators for them.
3
4 Ext.define('PVE.Parser', { statics: {
5
6 // this class only contains static functions
7
8 parseBoolean: function(value, default_value) {
9 if (!Ext.isDefined(value))
10 return default_value;
11 value = value.toLowerCase();
12 return value === 1 || value === '1' ||
13 value === 'on' ||
14 value === 'yes' ||
15 value === 'true';
16 },
17
18 parseQemuNetwork: function(key, value) {
19 if (!(key && value)) {
20 return;
21 }
22
23 var res = {};
24
25 var errors = false;
26 Ext.Array.each(value.split(','), function(p) {
27 if (!p || p.match(/^\s*$/)) {
28 return; // continue
29 }
30
31 var match_res;
32
33 if ((match_res = p.match(/^(ne2k_pci|e1000|e1000-82540em|e1000-82544gc|e1000-82545em|vmxnet3|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i)) !== null) {
34 res.model = match_res[1].toLowerCase();
35 if (match_res[3]) {
36 res.macaddr = match_res[3];
37 }
38 } else if ((match_res = p.match(/^bridge=(\S+)$/)) !== null) {
39 res.bridge = match_res[1];
40 } else if ((match_res = p.match(/^rate=(\d+(\.\d+)?)$/)) !== null) {
41 res.rate = match_res[1];
42 } else if ((match_res = p.match(/^tag=(\d+(\.\d+)?)$/)) !== null) {
43 res.tag = match_res[1];
44 } else if ((match_res = p.match(/^firewall=(\d+)$/)) !== null) {
45 res.firewall = match_res[1];
46 } else if ((match_res = p.match(/^link_down=(\d+)$/)) !== null) {
47 res.disconnect = match_res[1];
48 } else if ((match_res = p.match(/^queues=(\d+)$/)) !== null) {
49 res.queues = match_res[1];
50 } else if ((match_res = p.match(/^trunks=(\d+(?:-\d+)?(?:;\d+(?:-\d+)?)*)$/)) !== null) {
51 res.trunks = match_res[1];
52 } else {
53 errors = true;
54 return false; // break
55 }
56 });
57
58 if (errors || !res.model) {
59 return;
60 }
61
62 return res;
63 },
64
65 printQemuNetwork: function(net) {
66
67 var netstr = net.model;
68 if (net.macaddr) {
69 netstr += "=" + net.macaddr;
70 }
71 if (net.bridge) {
72 netstr += ",bridge=" + net.bridge;
73 if (net.tag) {
74 netstr += ",tag=" + net.tag;
75 }
76 if (net.firewall) {
77 netstr += ",firewall=" + net.firewall;
78 }
79 }
80 if (net.rate) {
81 netstr += ",rate=" + net.rate;
82 }
83 if (net.queues) {
84 netstr += ",queues=" + net.queues;
85 }
86 if (net.disconnect) {
87 netstr += ",link_down=" + net.disconnect;
88 }
89 if (net.trunks) {
90 netstr += ",trunks=" + net.trunks;
91 }
92 return netstr;
93 },
94
95 parseQemuDrive: function(key, value) {
96 if (!(key && value)) {
97 return;
98 }
99
100 var res = {};
101
102 var match_res = key.match(/^([a-z]+)(\d+)$/);
103 if (!match_res) {
104 return;
105 }
106 res['interface'] = match_res[1];
107 res.index = match_res[2];
108
109 var errors = false;
110 Ext.Array.each(value.split(','), function(p) {
111 if (!p || p.match(/^\s*$/)) {
112 return; // continue
113 }
114 var match_res = p.match(/^([a-z_]+)=(\S+)$/);
115 if (!match_res) {
116 if (!p.match(/\=/)) {
117 res.file = p;
118 return; // continue
119 }
120 errors = true;
121 return false; // break
122 }
123 var k = match_res[1];
124 if (k === 'volume') {
125 k = 'file';
126 }
127
128 if (Ext.isDefined(res[k])) {
129 errors = true;
130 return false; // break
131 }
132
133 var v = match_res[2];
134
135 if (k === 'cache' && v === 'off') {
136 v = 'none';
137 }
138
139 res[k] = v;
140 });
141
142 if (errors || !res.file) {
143 return;
144 }
145
146 return res;
147 },
148
149 printQemuDrive: function(drive) {
150
151 var drivestr = drive.file;
152
153 Ext.Object.each(drive, function(key, value) {
154 if (!Ext.isDefined(value) || key === 'file' ||
155 key === 'index' || key === 'interface') {
156 return; // continue
157 }
158 drivestr += ',' + key + '=' + value;
159 });
160
161 return drivestr;
162 },
163
164 parseOpenVZNetIf: function(value) {
165 if (!value) {
166 return;
167 }
168
169 var res = {};
170
171 var errors = false;
172 Ext.Array.each(value.split(';'), function(item) {
173 if (!item || item.match(/^\s*$/)) {
174 return; // continue
175 }
176
177 var data = {};
178 Ext.Array.each(item.split(','), function(p) {
179 if (!p || p.match(/^\s*$/)) {
180 return; // continue
181 }
182 var match_res = p.match(/^(ifname|mac|bridge|host_ifname|host_mac|mac_filter)=(\S+)$/);
183 if (!match_res) {
184 errors = true;
185 return false; // break
186 }
187 if (match_res[1] === 'bridge'){
188 var bridgevlanf = match_res[2];
189 var bridge_res = bridgevlanf.match(/^(vmbr(\d+))(v(\d+))?(f)?$/);
190 if (!bridge_res) {
191 errors = true;
192 return false; // break
193 }
194 data['bridge'] = bridge_res[1];
195 data['tag'] = bridge_res[4];
196 data['firewall'] = bridge_res[5] ? 1 : 0;
197 } else {
198 data[match_res[1]] = match_res[2];
199 }
200 });
201
202 if (errors || !data.ifname) {
203 errors = true;
204 return false; // break
205 }
206
207 data.raw = item;
208
209 res[data.ifname] = data;
210 });
211
212 return errors ? undefined: res;
213 },
214
215 printOpenVZNetIf: function(netif) {
216 var netarray = [];
217
218 Ext.Object.each(netif, function(iface, data) {
219 var tmparray = [];
220 Ext.Array.each(['ifname', 'mac', 'bridge', 'host_ifname' , 'host_mac', 'mac_filter', 'tag', 'firewall'], function(key) {
221 var value = data[key];
222 if (key === 'bridge'){
223 if(data['tag']){
224 value = value + 'v' + data['tag'];
225 }
226 if (data['firewall']){
227 value = value + 'f';
228 }
229 }
230 if (value) {
231 tmparray.push(key + '=' + value);
232 }
233
234 });
235 netarray.push(tmparray.join(','));
236 });
237
238 return netarray.join(';');
239 },
240
241 parseLxcNetwork: function(value) {
242 if (!value) {
243 return;
244 }
245
246 var data = {};
247 Ext.Array.each(value.split(','), function(p) {
248 if (!p || p.match(/^\s*$/)) {
249 return; // continue
250 }
251 var match_res = p.match(/^(bridge|hwaddr|mtu|name|ip|ip6|gw|gw6|firewall|tag)=(\S+)$/);
252 if (!match_res) {
253 // todo: simply ignore errors ?
254 return; // continue
255 }
256 data[match_res[1]] = match_res[2];
257 });
258
259 return data;
260 },
261
262 printLxcNetwork: function(data) {
263 var tmparray = [];
264 Ext.Array.each(['bridge', 'hwaddr', 'mtu', 'name', 'ip',
265 'gw', 'ip6', 'gw6', 'firewall', 'tag'], function(key) {
266 var value = data[key];
267 if (value) {
268 tmparray.push(key + '=' + value);
269 }
270 });
271
272 return tmparray.join(',');
273 },
274
275 parseLxcMountPoint: function(value) {
276 if (!value) {
277 return;
278 }
279
280 var res = {};
281
282 var errors = false;
283 Ext.Array.each(value.split(','), function(p) {
284 if (!p || p.match(/^\s*$/)) {
285 return; // continue
286 }
287 var match_res = p.match(/^([a-z_]+)=(\S+)$/);
288 if (!match_res) {
289 if (!p.match(/\=/)) {
290 res.file = p;
291 return; // continue
292 }
293 errors = true;
294 return false; // break
295 }
296 var k = match_res[1];
297 if (k === 'volume') {
298 k = 'file';
299 }
300
301 if (Ext.isDefined(res[k])) {
302 errors = true;
303 return false; // break
304 }
305
306 var v = match_res[2];
307
308 res[k] = v;
309 });
310
311 if (errors || !res.file) {
312 return;
313 }
314
315 var m = res.file.match(/^([a-z][a-z0-9\-\_\.]*[a-z0-9]):/i);
316 if (m) {
317 res.storage = m[1];
318 res.type = 'volume';
319 } else if (res.file.match(/^\/dev\//)) {
320 res.type = 'device';
321 } else {
322 res.type = 'bind';
323 }
324
325 return res;
326 },
327
328 printLxcMountPoint: function(mp) {
329 var drivestr = mp.file;
330
331 Ext.Object.each(mp, function(key, value) {
332 if (!Ext.isDefined(value) || key === 'file' ||
333 key === 'type' || key === 'storage') {
334 return; // continue
335 }
336 drivestr += ',' + key + '=' + value;
337 });
338
339 return drivestr;
340 },
341
342 parseStartup: function(value) {
343 if (value === undefined) {
344 return;
345 }
346
347 var res = {};
348
349 var errors = false;
350 Ext.Array.each(value.split(','), function(p) {
351 if (!p || p.match(/^\s*$/)) {
352 return; // continue
353 }
354
355 var match_res;
356
357 if ((match_res = p.match(/^(order)?=(\d+)$/)) !== null) {
358 res.order = match_res[2];
359 } else if ((match_res = p.match(/^up=(\d+)$/)) !== null) {
360 res.up = match_res[1];
361 } else if ((match_res = p.match(/^down=(\d+)$/)) !== null) {
362 res.down = match_res[1];
363 } else {
364 errors = true;
365 return false; // break
366 }
367 });
368
369 if (errors) {
370 return;
371 }
372
373 return res;
374 },
375
376 printStartup: function(startup) {
377 var arr = [];
378 if (startup.order !== undefined && startup.order !== '') {
379 arr.push('order=' + startup.order);
380 }
381 if (startup.up !== undefined && startup.up !== '') {
382 arr.push('up=' + startup.up);
383 }
384 if (startup.down !== undefined && startup.down !== '') {
385 arr.push('down=' + startup.down);
386 }
387
388 return arr.join(',');
389 },
390
391 parseQemuSmbios1: function(value) {
392 var res = {};
393
394 Ext.Array.each(value.split(','), function(p) {
395 var kva = p.split(/=/, 2);
396 res[kva[0]] = kva[1];
397 });
398
399 return res;
400 },
401
402 printQemuSmbios1: function(data) {
403
404 var datastr = '';
405
406 Ext.Object.each(data, function(key, value) {
407 if (value === '') return;
408 datastr += (datastr !== '' ? ',' : '') + key + '=' + value;
409 });
410
411 return datastr;
412 },
413
414 parseTfaConfig: function(value) {
415 var res = {};
416
417 Ext.Array.each(value.split(','), function(p) {
418 var kva = p.split(/=/, 2);
419 res[kva[0]] = kva[1];
420 });
421
422 return res;
423 },
424
425 parseQemuCpu: function(value) {
426 if (!value) {
427 return {};
428 }
429
430 var res = {};
431
432 var errors = false;
433 Ext.Array.each(value.split(','), function(p) {
434 if (!p || p.match(/^\s*$/)) {
435 return; // continue
436 }
437
438 if (!p.match(/=/)) {
439 if (Ext.isDefined(res['cpu'])) {
440 errors = true;
441 return false; // break
442 }
443 res.cputype = p;
444 return; // continue
445 }
446
447 var match_res = p.match(/^([a-z_]+)=(\S+)$/);
448 if (!match_res) {
449 errors = true;
450 return false; // break
451 }
452
453 var k = match_res[1];
454 if (Ext.isDefined(res[k])) {
455 errors = true;
456 return false; // break
457 }
458
459 res[k] = match_res[2];
460 });
461
462 if (errors || !res.cputype) {
463 return;
464 }
465
466 return res;
467 },
468
469 printQemuCpu: function(cpu) {
470 var cpustr = cpu.cputype;
471 var optstr = '';
472
473 Ext.Object.each(cpu, function(key, value) {
474 if (!Ext.isDefined(value) || key === 'cputype') {
475 return; // continue
476 }
477 optstr += ',' + key + '=' + value;
478 });
479
480 if (!cpustr) {
481 if (optstr)
482 return 'kvm64' + optstr;
483 return;
484 }
485
486 return cpustr + optstr;
487 },
488 }});