mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-05-29 21:36:01 +00:00
208 lines
4.4 KiB
JavaScript
208 lines
4.4 KiB
JavaScript
Ext.define('PVE.ha.VMResourceInputPanel', {
|
|
extend: 'Proxmox.panel.InputPanel',
|
|
onlineHelp: 'ha_manager_resource_config',
|
|
vmid: undefined,
|
|
|
|
onGetValues: function(values) {
|
|
var me = this;
|
|
|
|
if (values.vmid) {
|
|
values.sid = values.vmid;
|
|
}
|
|
delete values.vmid;
|
|
|
|
PVE.Utils.delete_if_default(values, 'group', '', me.isCreate);
|
|
PVE.Utils.delete_if_default(values, 'max_restart', '1', me.isCreate);
|
|
PVE.Utils.delete_if_default(values, 'max_relocate', '1', me.isCreate);
|
|
|
|
return values;
|
|
},
|
|
|
|
initComponent: function() {
|
|
var me = this;
|
|
var MIN_QUORUM_VOTES = 3;
|
|
|
|
var disabledHint = Ext.createWidget({
|
|
xtype: 'displayfield', // won't get submitted by default
|
|
userCls: 'pmx-hint',
|
|
value: 'Disabling the resource will stop the guest system. ' +
|
|
'See the online help for details.',
|
|
hidden: true,
|
|
});
|
|
|
|
var fewVotesHint = Ext.createWidget({
|
|
itemId: 'fewVotesHint',
|
|
xtype: 'displayfield',
|
|
userCls: 'pmx-hint',
|
|
value: 'At least three quorum votes are recommended for reliable HA.',
|
|
hidden: true,
|
|
});
|
|
|
|
Proxmox.Utils.API2Request({
|
|
url: '/cluster/config/nodes',
|
|
method: 'GET',
|
|
failure: function(response) {
|
|
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
|
|
},
|
|
success: function(response) {
|
|
var nodes = response.result.data;
|
|
var votes = 0;
|
|
Ext.Array.forEach(nodes, function(node) {
|
|
var vote = parseInt(node.quorum_votes, 10); // parse as base 10
|
|
votes += vote || 0; // parseInt might return NaN, which is false
|
|
});
|
|
|
|
if (votes < MIN_QUORUM_VOTES) {
|
|
fewVotesHint.setVisible(true);
|
|
}
|
|
},
|
|
});
|
|
|
|
var vmidStore = me.vmid ? {} : {
|
|
model: 'PVEResources',
|
|
autoLoad: true,
|
|
sorters: 'vmid',
|
|
filters: [
|
|
{
|
|
property: 'type',
|
|
value: /lxc|qemu/,
|
|
},
|
|
{
|
|
property: 'hastate',
|
|
value: /unmanaged/,
|
|
},
|
|
],
|
|
};
|
|
|
|
// value is a string above, but a number below
|
|
me.column1 = [
|
|
{
|
|
xtype: me.vmid ? 'displayfield' : 'vmComboSelector',
|
|
submitValue: me.isCreate,
|
|
name: 'vmid',
|
|
fieldLabel: me.vmid && me.guestType === 'ct' ? 'CT' : 'VM',
|
|
value: me.vmid,
|
|
store: vmidStore,
|
|
validateExists: true,
|
|
},
|
|
{
|
|
xtype: 'proxmoxintegerfield',
|
|
name: 'max_restart',
|
|
fieldLabel: gettext('Max. Restart'),
|
|
value: 1,
|
|
minValue: 0,
|
|
maxValue: 10,
|
|
allowBlank: false,
|
|
},
|
|
{
|
|
xtype: 'proxmoxintegerfield',
|
|
name: 'max_relocate',
|
|
fieldLabel: gettext('Max. Relocate'),
|
|
value: 1,
|
|
minValue: 0,
|
|
maxValue: 10,
|
|
allowBlank: false,
|
|
},
|
|
];
|
|
|
|
me.column2 = [
|
|
{
|
|
xtype: 'pveHAGroupSelector',
|
|
name: 'group',
|
|
fieldLabel: gettext('Group'),
|
|
},
|
|
{
|
|
xtype: 'proxmoxKVComboBox',
|
|
name: 'state',
|
|
value: 'started',
|
|
fieldLabel: gettext('Request State'),
|
|
comboItems: [
|
|
['started', 'started'],
|
|
['stopped', 'stopped'],
|
|
['ignored', 'ignored'],
|
|
['disabled', 'disabled'],
|
|
],
|
|
listeners: {
|
|
'change': function(field, newValue) {
|
|
if (newValue === 'disabled') {
|
|
disabledHint.setVisible(true);
|
|
} else if (disabledHint.isVisible()) {
|
|
disabledHint.setVisible(false);
|
|
}
|
|
},
|
|
},
|
|
},
|
|
disabledHint,
|
|
];
|
|
|
|
me.columnB = [
|
|
{
|
|
xtype: 'textfield',
|
|
name: 'comment',
|
|
fieldLabel: gettext('Comment'),
|
|
},
|
|
fewVotesHint,
|
|
];
|
|
|
|
me.callParent();
|
|
},
|
|
});
|
|
|
|
Ext.define('PVE.ha.VMResourceEdit', {
|
|
extend: 'Proxmox.window.Edit',
|
|
|
|
vmid: undefined,
|
|
guestType: undefined,
|
|
isCreate: undefined,
|
|
|
|
initComponent: function() {
|
|
var me = this;
|
|
|
|
if (me.isCreate === undefined) {
|
|
me.isCreate = !me.vmid;
|
|
}
|
|
|
|
if (me.isCreate) {
|
|
me.url = '/api2/extjs/cluster/ha/resources';
|
|
me.method = 'POST';
|
|
} else {
|
|
me.url = '/api2/extjs/cluster/ha/resources/' + me.vmid;
|
|
me.method = 'PUT';
|
|
}
|
|
|
|
var ipanel = Ext.create('PVE.ha.VMResourceInputPanel', {
|
|
isCreate: me.isCreate,
|
|
vmid: me.vmid,
|
|
guestType: me.guestType,
|
|
});
|
|
|
|
Ext.apply(me, {
|
|
subject: gettext('Resource') + ': ' + gettext('Container') +
|
|
'/' + gettext('Virtual Machine'),
|
|
isAdd: true,
|
|
items: [ipanel],
|
|
});
|
|
|
|
me.callParent();
|
|
|
|
if (!me.isCreate) {
|
|
me.load({
|
|
success: function(response, options) {
|
|
var values = response.result.data;
|
|
|
|
var regex = /^(\S+):(\S+)$/;
|
|
var res = regex.exec(values.sid);
|
|
|
|
if (res[1] !== 'vm' && res[1] !== 'ct') {
|
|
throw "got unexpected resource type";
|
|
}
|
|
|
|
values.vmid = res[2];
|
|
|
|
ipanel.setValues(values);
|
|
},
|
|
});
|
|
}
|
|
},
|
|
});
|