let isCloudInitKey = v => v && v.toString().match(/vm-.*-cloudinit/);
+ const nodeInfo = PVE.data.ResourceStore.getNodes().find(node => node.node === nodename);
+ let processorEditor = {
+ xtype: 'pveQemuProcessorEdit',
+ cgroupMode: nodeInfo['cgroup-mode'],
+ };
+
let rows = {
memory: {
header: gettext('Memory'),
header: gettext('Processors'),
never_delete: true,
editor: caps.vms['VM.Config.CPU'] || caps.vms['VM.Config.HWType']
- ? 'PVE.qemu.ProcessorEdit' : undefined,
+ ? processorEditor : undefined,
tdCls: 'pve-itype-icon-cpu',
group: 3,
defaultValue: '1',
group: 25,
order: i,
iconCls: 'usb',
- editor: caps.nodes['Sys.Console'] ? 'PVE.qemu.USBEdit' : undefined,
- never_delete: !caps.nodes['Sys.Console'],
+ editor: caps.nodes['Sys.Console'] || caps.mapping['Mapping.Use'] ? 'PVE.qemu.USBEdit' : undefined,
+ never_delete: !caps.nodes['Sys.Console'] && !caps.mapping['Mapping.Use'],
header: gettext('USB Device') + ' (' + confid + ')',
};
}
group: 30,
order: i,
tdCls: 'pve-itype-icon-pci',
- never_delete: !caps.nodes['Sys.Console'],
- editor: caps.nodes['Sys.Console'] ? 'PVE.qemu.PCIEdit' : undefined,
+ never_delete: !caps.nodes['Sys.Console'] && !caps.mapping['Mapping.Use'],
+ editor: caps.nodes['Sys.Console'] || caps.mapping['Mapping.Use'] ? 'PVE.qemu.PCIEdit' : undefined,
header: gettext('PCI Device') + ' (' + confid + ')',
};
}
return;
}
- Ext.create('PVE.window.HDReassign', {
+ Ext.create('PVE.window.GuestDiskReassign', {
autoShow: true,
disk: rec.data.key,
nodename: nodename,
let counts = {};
let isAtLimit = (type) => counts[type] >= PVE.Utils.hardware_counts[type];
+ let isAtUsbLimit = () => {
+ let ostype = me.getObjectValue('ostype');
+ let machine = me.getObjectValue('machine');
+ return counts.usb >= PVE.Utils.get_max_usb_count(ostype, machine);
+ };
let set_button_status = function() {
let selection_model = me.getSelectionModel();
// heuristic only for disabling some stuff, the backend has the final word.
const noSysConsolePerm = !caps.nodes['Sys.Console'];
+ const noHWPerm = !caps.nodes['Sys.Console'] && !caps.mapping['Mapping.Use'];
const noVMConfigHWTypePerm = !caps.vms['VM.Config.HWType'];
const noVMConfigNetPerm = !caps.vms['VM.Config.Network'];
const noVMConfigDiskPerm = !caps.vms['VM.Config.Disk'];
+ const noVMConfigCDROMPerm = !caps.vms['VM.Config.CDROM'];
+ const noVMConfigCloudinitPerm = !caps.vms['VM.Config.Cloudinit'];
- me.down('#addUsb').setDisabled(noSysConsolePerm || isAtLimit('usb'));
- me.down('#addPci').setDisabled(noSysConsolePerm || isAtLimit('hostpci'));
+ me.down('#addUsb').setDisabled(noHWPerm || isAtUsbLimit());
+ me.down('#addPci').setDisabled(noHWPerm || isAtLimit('hostpci'));
me.down('#addAudio').setDisabled(noVMConfigHWTypePerm || isAtLimit('audio'));
me.down('#addSerial').setDisabled(noVMConfigHWTypePerm || isAtLimit('serial'));
me.down('#addNet').setDisabled(noVMConfigNetPerm || isAtLimit('net'));
me.down('#addRng').setDisabled(noSysConsolePerm || isAtLimit('rng'));
efidisk_menuitem.setDisabled(noVMConfigDiskPerm || isAtLimit('efidisk'));
me.down('#addTpmState').setDisabled(noSysConsolePerm || isAtLimit('tpmstate'));
- me.down('#addCloudinitDrive').setDisabled(noSysConsolePerm || hasCloudInit);
+ me.down('#addCloudinitDrive').setDisabled(noVMConfigCDROMPerm || noVMConfigCloudinitPerm || hasCloudInit);
if (!rec) {
remove_btn.disable();
const pending = deleted || me.hasPendingChanges(key);
const isCloudInit = isCloudInitKey(value);
- const isCDRom = value && !!value.toString().match(/media=cdrom/) && !isCloudInit;
+ const isCDRom = value && !!value.toString().match(/media=cdrom/);
const isUnusedDisk = key.match(/^unused\d+/);
- const isUsedDisk = !isUnusedDisk && row.isOnStorageBus && !isCDRom && !isCloudInit;
- const isDisk = isCloudInit || isUnusedDisk || isUsedDisk;
+ const isUsedDisk = !isUnusedDisk && row.isOnStorageBus && !isCDRom;
+ const isDisk = isUnusedDisk || isUsedDisk;
const isEfi = key === 'efidisk0';
const tpmMoveable = key === 'tpmstate0' && !me.pveSelNode.data.running;
- remove_btn.setDisabled(
- deleted || row.never_delete || (isCDRom && !cdromCap) || (isDisk && !diskCap));
+ let cannotDelete = deleted || row.never_delete;
+ cannotDelete ||= isCDRom && !cdromCap;
+ cannotDelete ||= isDisk && !diskCap;
+ cannotDelete ||= isCloudInit && noVMConfigCloudinitPerm;
+ remove_btn.setDisabled(cannotDelete);
+
remove_btn.setText(isUsedDisk && !isCloudInit ? remove_btn.altText : remove_btn.defaultText);
remove_btn.RESTMethod = isUnusedDisk ? 'POST':'PUT';
isCloudInit ||
!(isDisk || isEfi || tpmMoveable),
);
- move_menuitem.setDisabled(isUnusedDisk);
reassign_menuitem.setDisabled(pending || (isEfi || tpmMoveable));
resize_menuitem.setDisabled(pending || !isUsedDisk);
text: gettext('USB Device'),
itemId: 'addUsb',
iconCls: 'fa fa-fw fa-usb black',
- disabled: !caps.nodes['Sys.Console'],
+ disabled: !caps.nodes['Sys.Console'] && !caps.mapping['Mapping.Use'],
handler: editorFactory('USBEdit'),
},
{
text: gettext('PCI Device'),
itemId: 'addPci',
iconCls: 'pve-itype-icon-pci',
- disabled: !caps.nodes['Sys.Console'],
+ disabled: !caps.nodes['Sys.Console'] && !caps.mapping['Mapping.Use'],
handler: editorFactory('PCIEdit'),
},
{
text: gettext('CloudInit Drive'),
itemId: 'addCloudinitDrive',
iconCls: 'fa fa-fw fa-cloud black',
- disabled: !caps.nodes['Sys.Console'],
+ disabled: !caps.vms['VM.Config.CDROM'] || !caps.vms['VM.Config.Cloudinit'],
handler: editorFactory('CIDriveEdit'),
},
{