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