]> git.proxmox.com Git - pve-manager.git/blob - www/manager/dc/HAConfig.js
start adding HA Config
[pve-manager.git] / www / manager / dc / HAConfig.js
1 Ext.define('PVE.dc.vmHAServiceEdit', {
2 extend: 'PVE.window.Edit',
3
4 initComponent : function() {
5 var me = this;
6
7 me.create = me.vmid ? false : true;
8
9 if (me.vmid) {
10 me.create = false;
11 me.url = "/cluster/ha/groups/pvevm:" + me.vmid;
12 me.method = 'PUT';
13 } else {
14 me.create = true;
15 me.url = "/cluster/ha/groups";
16 me.method = 'POST';
17 }
18
19 Ext.apply(me, {
20 title: gettext('HA managed VM/CT'),
21 width: 350,
22 items: [
23 {
24 xtype: me.create ? 'pveVMIDSelector' : 'displayfield',
25 name: 'vmid',
26 validateExists: true,
27 value: me.vmid || '',
28 fieldLabel: "VM ID"
29 },
30 {
31 xtype: 'pvecheckbox',
32 name: 'autostart',
33 checked: true,
34 fieldLabel: 'autostart'
35 }
36 ]
37 });
38
39 me.callParent();
40
41 if (!me.create) {
42 me.load()
43 }
44 }
45 });
46
47 Ext.define('PVE.dc.HAConfig', {
48 extend: 'Ext.panel.Panel',
49 alias: 'widget.pveDcHAConfig',
50
51 clusterInfo: {}, // reload store data here
52
53 reload: function() {
54 var me = this;
55
56 var getClusterInfo = function(conf) {
57
58 var info = {};
59
60 if (!(conf && conf.children && conf.children[0])) {
61 return info;
62 }
63
64 var cluster = conf.children[0];
65
66 if (cluster.text !== 'cluster' || !cluster.config_version) {
67 return info;
68 }
69
70 info.version = cluster.config_version;
71
72 Ext.Array.each(cluster.children, function(item) {
73 if (item.text === 'fencedevices') {
74 // fixme: make sure each node uses at least one fence device
75 info.fenceDevices = true;
76 } else if (item.text === 'rm') {
77 info.ha = true;
78 }
79 });
80
81 return info;
82 };
83
84 PVE.Utils.API2Request({
85 url: '/cluster/ha/config',
86 waitMsgTarget: me,
87 method: 'GET',
88 failure: function(response, opts) {
89 me.clusterInfo = {};
90 me.setLoading(response.htmlStatus);
91 },
92 success: function(response, opts) {
93 me.clusterInfo = getClusterInfo(response.result.data);
94 console.dir(me.clusterInfo);
95
96 me.setDisabled(!me.clusterInfo.version);
97
98 me.addMenu.setDisabled(!me.clusterInfo.version);
99
100 // note: this modifies response.result.data
101 me.treePanel.setRootNode(response.result.data);
102 me.treePanel.expandAll();
103
104
105 if (response.result.changes) {
106 me.commitBtn.setDisabled(false);
107 me.revertBtn.setDisabled(false);
108 me.diffPanel.setVisible(true);
109 me.diffPanel.update("<pre>" + Ext.htmlEncode(response.result.changes) + "</pre>");
110 } else {
111 me.commitBtn.setDisabled(true);
112 me.revertBtn.setDisabled(true);
113 me.diffPanel.setVisible(false);
114 me.diffPanel.update('');
115 }
116 }
117 });
118 },
119
120 initComponent: function() {
121 var me = this;
122
123 me.commitBtn = new PVE.button.Button({
124 text: gettext('Commit'),
125 disabled: true,
126 confirmMsg: function () {
127 return gettext('Are you sure you want to commit your changes');
128 },
129 handler: function(btn, event) {
130 PVE.Utils.API2Request({
131 url: '/cluster/ha/changes',
132 method: 'POST',
133 waitMsgTarget: me,
134 callback: function() {
135 me.reload();
136 },
137 failure: function (response, opts) {
138 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
139 }
140 });
141 }
142 });
143
144 me.revertBtn = new PVE.button.Button({
145 text: gettext('Revert changes'),
146 disabled: true,
147 confirmMsg: function () {
148 return gettext('Are you sure you want to revert (undo) your changes');
149 },
150 handler: function(btn, event) {
151 PVE.Utils.API2Request({
152 url: '/cluster/ha/changes',
153 method: 'DELETE',
154 waitMsgTarget: me,
155 callback: function() {
156 me.reload();
157 },
158 failure: function (response, opts) {
159 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
160 }
161 });
162 }
163 });
164
165 me.addMenu = new Ext.button.Button({
166 text: gettext('Add'),
167 disabled: true,
168 menu: new Ext.menu.Menu({
169 items: [
170 {
171 text: gettext('HA managed VM/CT'),
172 handler: function() {
173 if (!me.clusterInfo.fenceDevices) {
174 Ext.Msg.alert(gettext('Error'), gettext("Please configure fencing first!"));
175 return;
176 }
177 var win = Ext.create('PVE.dc.vmHAServiceEdit', {});
178 win.show();
179 win.on('destroy', me.reload, me);
180 }
181 },
182 {
183 text: gettext('Failover Domain'),
184 handler: function() {
185 Ext.Msg.alert(gettext('Error'), "not implemented - sorry");
186 }
187 }
188 ]
189 })
190 });
191
192 me.treePanel = Ext.create('Ext.tree.Panel', {
193 rootVisible: false,
194 animate: false,
195 region: 'center',
196 border: false,
197 fields: ['text', 'id', 'vmid', 'name' ],
198 columns: [
199 {
200 xtype: 'treecolumn',
201 text: 'Tag',
202 dataIndex: 'text',
203 width: 200
204 },
205 {
206 text: 'Attributes',
207 dataIndex: 'id',
208 renderer: function(value, metaData, record) {
209 var text = '';
210 Ext.Object.each(record.raw, function(key, value) {
211 if (key === 'id' || key === 'text') {
212 return;
213 }
214 text += Ext.htmlEncode(key) + '="' +
215 Ext.htmlEncode(value) + '" ';
216 });
217 return text;
218 },
219 flex: 1
220 }
221 ]
222 });
223
224 var run_editor = function() {
225 var rec = me.treePanel.selModel.getSelection()[0];
226 if (rec && rec.data.text === 'pvevm') {
227 var win = Ext.create('PVE.dc.vmHAServiceEdit', {
228 vmid: rec.data.vmid
229 });
230 win.show();
231 win.on('destroy', me.reload, me);
232 }
233 };
234
235 me.editBtn = new Ext.button.Button({
236 text: gettext('Edit'),
237 disabled: true,
238 handler: run_editor
239 });
240
241 me.removeBtn = new Ext.button.Button({
242 text: gettext('Remove'),
243 disabled: true,
244 handler: function() {
245 var rec = me.treePanel.selModel.getSelection()[0];
246 if (rec && rec.data.text === 'pvevm') {
247 var groupid = 'pvevm:' + rec.data.vmid;
248 PVE.Utils.API2Request({
249 url: '/cluster/ha/groups/' + groupid,
250 method: 'DELETE',
251 waitMsgTarget: me,
252 callback: function() {
253 me.reload();
254 },
255 failure: function (response, opts) {
256 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
257 }
258 });
259 }
260 }
261 });
262
263
264 me.diffPanel = Ext.create('Ext.panel.Panel', {
265 border: false,
266 hidden: true,
267 region: 'south',
268 autoScroll: true,
269 itemId: 'changes',
270 tbar: [ gettext('Pending changes') ],
271 split: true,
272 bodyPadding: 5,
273 flex: 0.6
274 });
275
276 Ext.apply(me, {
277 layout: 'border',
278 tbar: [ me.addMenu, me.removeBtn, me.editBtn, me.revertBtn, me.commitBtn ],
279 items: [ me.treePanel, me.diffPanel ]
280 });
281
282 me.callParent();
283
284 me.on('show', me.reload);
285
286 me.treePanel.on("selectionchange", function(sm, selected) {
287 var rec = selected[0];
288 if (rec && rec.data.text === 'pvevm') {
289 me.editBtn.setDisabled(false);
290 me.removeBtn.setDisabled(false);
291 } else {
292 me.editBtn.setDisabled(true);
293 me.removeBtn.setDisabled(true);
294
295 }
296 });
297
298 me.treePanel.on("itemdblclick", function(v, record) {
299 run_editor()
300 });
301 }
302 });