]>
Commit | Line | Data |
---|---|---|
9b81768f DM |
1 | Ext.define('PVE.ha.VMResourceInputPanel', { |
2 | extend: 'PVE.panel.InputPanel', | |
95cf0210 | 3 | onlineHelp: 'ha_manager_resource_config', |
9b81768f DM |
4 | vmid: undefined, |
5 | ||
6 | onGetValues: function(values) { | |
7 | var me = this; | |
8 | ||
d5e771ce | 9 | if (me.isCreate) { |
9b81768f DM |
10 | values.sid = values.vmid; |
11 | } | |
12 | ||
9b81768f DM |
13 | |
14 | delete values.vmid; | |
15 | ||
d5e771ce EK |
16 | PVE.Utils.delete_if_default(values, 'group', '', me.isCreate); |
17 | PVE.Utils.delete_if_default(values, 'max_restart', '1', me.isCreate); | |
18 | PVE.Utils.delete_if_default(values, 'max_relocate', '1', me.isCreate); | |
b2f9a9e4 | 19 | |
9b81768f DM |
20 | return values; |
21 | }, | |
22 | ||
23 | initComponent : function() { | |
24 | var me = this; | |
0a4651f0 | 25 | var MIN_QUORUM_VOTES = 3; |
9b81768f | 26 | |
390b8555 EK |
27 | var disabledHint = Ext.createWidget({ |
28 | xtype: 'displayfield', //submitValue is false, so we don't get submitted | |
29 | userCls: 'pve-hint', | |
49e19905 DC |
30 | value: 'Disabling the resource will stop the guest system. ' + |
31 | 'See the online help for details.', | |
390b8555 EK |
32 | hidden: true |
33 | }); | |
34 | ||
0a4651f0 EK |
35 | var fewVotesHint = Ext.createWidget({ |
36 | itemId: 'fewVotesHint', | |
37 | xtype: 'displayfield', | |
38 | userCls: 'pve-hint', | |
39 | updateValue: function(votes) { | |
40 | var me = this; | |
49e19905 DC |
41 | me.setValue('You need at least three quorum votes for a reliable HA cluster. ' + |
42 | 'See the online help for details. Current votes: ' + votes); | |
0a4651f0 EK |
43 | }, |
44 | hidden: true | |
45 | }); | |
46 | ||
47 | PVE.Utils.API2Request({ | |
48 | url: '/cluster/config/nodes', | |
49 | method: 'GET', | |
50 | failure: function(response) { | |
51 | Ext.Msg.alert(gettext('Error'), response.htmlStatus); | |
52 | }, | |
53 | success: function(response) { | |
54 | var nodes = response.result.data; | |
55 | var votes = 0; | |
56 | Ext.Array.forEach(nodes, function(node) { | |
57 | var vote = parseInt(node.quorum_votes, 10); // parse as base 10 | |
58 | votes += vote || 0; // parseInt might return NaN, which is false | |
59 | }); | |
60 | ||
61 | if (votes < MIN_QUORUM_VOTES) { | |
62 | fewVotesHint.updateValue(votes); | |
63 | fewVotesHint.setVisible(true); | |
64 | } | |
65 | } | |
66 | }); | |
67 | ||
a49cdcee DC |
68 | // value is a string above, but a number below |
69 | /*jslint confusion: true */ | |
9b81768f DM |
70 | me.column1 = [ |
71 | { | |
ed416f20 | 72 | xtype: me.vmid ? 'displayfield' : 'pveGuestIDSelector', |
9b81768f | 73 | name: 'vmid', |
ed416f20 | 74 | fieldLabel: (me.vmid && me.guestType === 'ct') ? 'CT' : 'VM', |
9b81768f | 75 | value: me.vmid, |
ed416f20 | 76 | loadNextGuestID: false, |
9b81768f | 77 | validateExists: true |
b2f9a9e4 TL |
78 | }, |
79 | { | |
8a7e5598 | 80 | xtype: 'pveIntegerField', |
b2f9a9e4 TL |
81 | name: 'max_restart', |
82 | fieldLabel: gettext('Max. Restart'), | |
83 | value: 1, | |
84 | minValue: 0, | |
85 | maxValue: 10, | |
86 | allowBlank: false | |
87 | }, | |
88 | { | |
8a7e5598 | 89 | xtype: 'pveIntegerField', |
b2f9a9e4 TL |
90 | name: 'max_relocate', |
91 | fieldLabel: gettext('Max. Relocate'), | |
92 | value: 1, | |
93 | minValue: 0, | |
94 | maxValue: 10, | |
95 | allowBlank: false | |
9b81768f DM |
96 | } |
97 | ]; | |
a49cdcee | 98 | /*jslint confusion: false */ |
9b81768f DM |
99 | |
100 | me.column2 = [ | |
101 | { | |
102 | xtype: 'pveHAGroupSelector', | |
103 | name: 'group', | |
9b81768f DM |
104 | fieldLabel: gettext('Group') |
105 | }, | |
106 | { | |
ecd45352 TL |
107 | xtype: 'pveKVComboBox', |
108 | name: 'state', | |
109 | value: 'started', | |
110 | fieldLabel: gettext('Request State'), | |
111 | comboItems: [ | |
e49da95b DC |
112 | ['started', 'started'], |
113 | ['stopped', 'stopped'], | |
840cd466 | 114 | ['ignored', 'ignored'], |
e49da95b | 115 | ['disabled', 'disabled'] |
ecd45352 | 116 | ], |
390b8555 EK |
117 | listeners: { |
118 | 'change': function(field, newValue) { | |
ecd45352 | 119 | if (newValue === 'disabled') { |
390b8555 EK |
120 | disabledHint.setVisible(true); |
121 | } | |
122 | else { | |
123 | if (disabledHint.isVisible()) { | |
124 | disabledHint.setVisible(false); | |
125 | } | |
126 | } | |
127 | } | |
128 | } | |
129 | }, | |
130 | disabledHint | |
9b81768f DM |
131 | ]; |
132 | ||
133 | me.columnB = [ | |
134 | { | |
135 | xtype: 'textfield', | |
136 | name: 'comment', | |
137 | fieldLabel: gettext('Comment') | |
0a4651f0 EK |
138 | }, |
139 | fewVotesHint | |
9b81768f DM |
140 | ]; |
141 | ||
142 | me.callParent(); | |
143 | } | |
144 | }); | |
145 | ||
146 | Ext.define('PVE.ha.VMResourceEdit', { | |
147 | extend: 'PVE.window.Edit', | |
148 | ||
149 | vmid: undefined, | |
ed416f20 | 150 | guestType: undefined, |
9b81768f DM |
151 | |
152 | initComponent : function() { | |
153 | var me = this; | |
154 | ||
d5e771ce | 155 | me.isCreate = !me.vmid; |
9b81768f | 156 | |
d5e771ce | 157 | if (me.isCreate) { |
9b81768f DM |
158 | me.url = '/api2/extjs/cluster/ha/resources'; |
159 | me.method = 'POST'; | |
160 | } else { | |
161 | me.url = '/api2/extjs/cluster/ha/resources/' + me.vmid; | |
162 | me.method = 'PUT'; | |
163 | } | |
164 | ||
165 | var ipanel = Ext.create('PVE.ha.VMResourceInputPanel', { | |
d5e771ce | 166 | isCreate: me.isCreate, |
ed416f20 EK |
167 | vmid: me.vmid, |
168 | guestType: me.guestType | |
9b81768f DM |
169 | }); |
170 | ||
171 | Ext.apply(me, { | |
8f8ec25d EK |
172 | subject: gettext('Resource') + ': ' + gettext('Container') + |
173 | '/' + gettext('Virtual Machine'), | |
9b81768f DM |
174 | isAdd: true, |
175 | items: [ ipanel ] | |
176 | }); | |
177 | ||
178 | me.callParent(); | |
179 | ||
d5e771ce | 180 | if (!me.isCreate) { |
9b81768f DM |
181 | me.load({ |
182 | success: function(response, options) { | |
183 | var values = response.result.data; | |
184 | ||
9b81768f DM |
185 | var regex = /^(\S+):(\S+)$/; |
186 | var res = regex.exec(values.sid); | |
187 | ||
a764c5f7 DC |
188 | if (res[1] !== 'vm' && res[1] !== 'ct') { |
189 | throw "got unexpected resource type"; | |
190 | } | |
9b81768f DM |
191 | |
192 | values.vmid = res[2]; | |
193 | ||
194 | ipanel.setValues(values); | |
195 | } | |
196 | }); | |
197 | } | |
198 | } | |
199 | }); |