]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/qemu/CloudInit.js
correct node free calculation
[pve-manager.git] / www / manager6 / qemu / CloudInit.js
CommitLineData
4c507192
DC
1Ext.define('PVE.qemu.CloudInit', {
2 extend: 'Proxmox.grid.PendingObjectGrid',
3 xtype: 'pveCiPanel',
4
5 tbar: [
6 {
7 xtype: 'proxmoxButton',
8 disabled: true,
9 dangerous: true,
10 confirmMsg: function(rec) {
11 var me = this.up('grid');
12 var warn = gettext('Are you sure you want to remove entry {0}');
13
14 var entry = rec.data.key;
15 var msg = Ext.String.format(warn, "'"
16 + me.renderKey(entry, {}, rec) + "'");
17
18 return msg;
19 },
20 enableFn: function(record) {
21 var me = this.up('grid');
22 var caps = Ext.state.Manager.get('GuiCap');
23 if (me.rows[record.data.key].never_delete ||
24 !caps.vms['VM.Config.Network']) {
25 return false;
26 }
2ed6dceb
DC
27
28 if (record.data.key === 'cipassword' && !record.data.value) {
29 return false;
30 }
4c507192
DC
31 return true;
32 },
33 handler: function() {
34 var me = this.up('grid');
2ed6dceb
DC
35 var records = me.getSelection();
36 if (!records || !records.length) {
37 return;
38 }
39
40 var id = records[0].data.key;
41 var match = id.match(/^net(\d+)$/);
42 if (match) {
43 id = 'ipconfig' + match[1];
44 }
45
46 var params = {};
47 params['delete'] = id;
48 Proxmox.Utils.API2Request({
49 url: me.baseurl + '/config',
50 waitMsgTarget: me,
51 method: 'PUT',
52 params: params,
53 failure: function(response, opts) {
54 Ext.Msg.alert('Error', response.htmlStatus);
55 },
56 callback: function() {
57 me.reload();
58 }
59 });
4c507192
DC
60 },
61 text: gettext('Remove')
62 },
63 {
64 xtype: 'proxmoxButton',
65 disabled: true,
66 handler: function() {
67 var me = this.up('grid');
68 me.run_editor();
69 },
70 text: gettext('Edit')
71 },
72 '-',
73 {
74 xtype: 'button',
75 itemId: 'savebtn',
76 text: gettext('Regenerate Image'),
77 handler: function() {
78 var me = this.up('grid');
79 var eject_params = {};
80 var insert_params = {};
81 var disk = PVE.Parser.parseQemuDrive(me.ciDriveId, me.ciDrive);
82 var storage = '';
83 var stormatch = disk.file.match(/^([^\:]+)\:/);
84 if (stormatch) {
85 storage = stormatch[1];
86 }
87 eject_params[me.ciDriveId] = 'none,media=cdrom';
88 insert_params[me.ciDriveId] = storage + ':cloudinit';
89
90 var failure = function(response, opts) {
91 Ext.Msg.alert('Error', response.htmlStatus);
92 };
93
94 Proxmox.Utils.API2Request({
95 url: me.baseurl + '/config',
96 waitMsgTarget: me,
97 method: 'PUT',
98 params: eject_params,
99 failure: failure,
100 callback: function() {
101 Proxmox.Utils.API2Request({
102 url: me.baseurl + '/config',
103 waitMsgTarget: me,
104 method: 'PUT',
105 params: insert_params,
106 failure: failure,
107 callback: function() {
108 me.reload();
109 }
110 });
111 }
112 });
113 }
114 }
115 ],
116
117 border: false,
118
119 set_button_status: function(rstore, records, success) {
120 if (!success || records.length < 1) {
121 return;
122 }
123 var me = this;
124 var found;
125 records.forEach(function(record) {
126 if (found) {
127 return;
128 }
129 var id = record.data.key;
130 var value = record.data.value;
131 var ciregex = new RegExp("vm-" + me.pveSelNode.data.vmid + "-cloudinit");
132 if (id.match(/^(ide|scsi|sata)\d+$/) && ciregex.test(value)) {
133 found = id;
134 me.ciDriveId = found;
135 me.ciDrive = value;
136 }
137 });
138
139 me.down('#savebtn').setDisabled(!found);
140 me.setDisabled(!found);
141 if (!found) {
142 me.getView().mask(gettext('No CloudInit Drive found'), ['pve-static-mask']);
143 } else {
144 me.getView().unmask();
145 }
146 },
147
148 renderKey: function(key, metaData, rec, rowIndex, colIndex, store) {
149 var me = this;
150 var rows = me.rows;
151 var rowdef = rows[key] || {};
152
153 var icon = "";
154 if (rowdef.iconCls) {
155 icon = '<i class="' + rowdef.iconCls + '"></i> ';
156 }
157 return icon + (rowdef.header || key);
158 },
159
160 listeners: {
161 activate: function () {
162 var me = this;
163 me.rstore.startUpdate();
164 },
165 itemdblclick: function() {
166 var me = this;
167 me.run_editor();
168 }
169 },
170
171 initComponent: function() {
172 var me = this;
173
174 var nodename = me.pveSelNode.data.node;
175 if (!nodename) {
176 throw "no node name specified";
177 }
178
179 var vmid = me.pveSelNode.data.vmid;
180 if (!vmid) {
181 throw "no VM ID specified";
182 }
183 var caps = Ext.state.Manager.get('GuiCap');
184 me.baseurl = '/api2/extjs/nodes/' + nodename + '/qemu/' + vmid;
185 me.url = me.baseurl + '/pending';
186 me.editorConfig.url = me.baseurl + '/config';
187 me.editorConfig.pveSelNode = me.pveSelNode;
188
189 /*jslint confusion: true*/
190 /* editor is string and object */
191 me.rows = {
192 ciuser: {
193 header: gettext('User'),
194 iconCls: 'fa fa-user',
195 never_delete: true,
196 defaultValue: '',
197 editor: caps.vms['VM.Config.Options'] ? {
198 xtype: 'proxmoxWindowEdit',
199 subject: gettext('User'),
200 items: [
201 {
202 xtype: 'proxmoxtextfield',
203 deleteEmpty: true,
204 emptyText: Proxmox.Utils.defaultText,
205 fieldLabel: gettext('User'),
206 name: 'ciuser'
207 }
208 ]
209 } : undefined,
210 renderer: function(value) {
211 return value || Proxmox.Utils.defaultText;
212 }
213 },
214 cipassword: {
215 header: gettext('Password'),
216 iconCls: 'fa fa-unlock',
4c507192
DC
217 defaultValue: '',
218 editor: caps.vms['VM.Config.Options'] ? {
219 xtype: 'proxmoxWindowEdit',
220 subject: gettext('Password'),
221 items: [
222 {
223 xtype: 'proxmoxtextfield',
224 inputType: 'password',
225 deleteEmpty: true,
226 emptyText: Proxmox.Utils.noneText,
227 fieldLabel: gettext('Password'),
228 name: 'cipassword'
229 }
230 ]
231 } : undefined,
232 renderer: function(value) {
233 return value || Proxmox.Utils.noneText;
234 }
235 },
236 searchdomain: {
237 header: gettext('DNS domain'),
238 iconCls: 'fa fa-globe',
239 editor: caps.vms['VM.Config.Network'] ? 'PVE.lxc.DNSEdit' : undefined,
240 never_delete: true,
241 defaultValue: gettext('use host settings')
242 },
243 nameserver: {
244 header: gettext('DNS servers'),
245 iconCls: 'fa fa-globe',
246 editor: caps.vms['VM.Config.Network'] ? 'PVE.lxc.DNSEdit' : undefined,
247 never_delete: true,
248 defaultValue: gettext('use host settings')
249 },
250 sshkeys: {
251 header: gettext('SSH public key'),
252 iconCls: 'fa fa-key',
253 editor: caps.vms['VM.Config.Network'] ? 'PVE.qemu.SSHKeyEdit' : undefined,
254 never_delete: true,
255 renderer: function(value) {
256 value = decodeURIComponent(value);
257 var keys = value.split('\n');
258 var text = [];
259 keys.forEach(function(key) {
260 if (key.length) {
261 // First erase all quoted strings (eg. command="foo"
262 var v = key.replace(/"(?:\\.|[^"\\])*"/g, '');
263 // Now try to detect the comment:
264 var res = v.match(/^\s*(\S+\s+)?(?:ssh-(?:dss|rsa|ed25519)|ecdsa-sha2-nistp\d+)\s+\S+\s+(.*?)\s*$/, '');
265 if (res) {
266 key = Ext.String.htmlEncode(res[2]);
267 if (res[1]) {
268 key += ' <span style="color:gray">(' + gettext('with options') + ')</span>';
269 }
270 text.push(key);
271 return;
272 }
273 // Most likely invalid at this point, so just stick to
274 // the old value.
275 text.push(Ext.String.htmlEncode(key));
276 }
277 });
278 if (text.length) {
279 return text.join('<br>');
280 } else {
281 return Proxmox.Utils.noneText;
282 }
283 },
284 defaultValue: ''
285 }
286 };
287 var i;
288 var ipconfig_renderer = function(value, md, record, ri, ci, store, pending) {
289 var id = record.data.key;
290 var match = id.match(/^net(\d+)$/);
291 var val = '';
292 if (match) {
293 val = me.getObjectValue('ipconfig'+match[1], '', pending);
294 }
295 return val;
296 };
297 for (i = 0; i < 32; i++) {
298 // we want to show an entry for every network device
299 // even if it is empty
300 me.rows['net' + i.toString()] = {
301 multiKey: ['ipconfig' + i.toString(), 'net' + i.toString()],
302 header: gettext('IP Config') + ' (net' + i.toString() +')',
303 editor: caps.vms['VM.Config.Network'] ? 'PVE.qemu.IPConfigEdit' : undefined,
304 iconCls: 'fa fa-exchange',
305 renderer: ipconfig_renderer
306 };
307 me.rows['ipconfig' + i.toString()] = {
308 visible: false
309 };
310 }
311 /*jslint confusion: false*/
312
313 PVE.Utils.forEachBus(['ide', 'scsi', 'sata'], function(type, id) {
314 me.rows[type+id] = {
315 visible: false
316 };
317 });
318 me.callParent();
319 me.mon(me.rstore, 'load', me.set_button_status, me);
320 }
321});