package org.ovirt.engine.ui.uicommonweb.models.vms.hostdev; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VmHostDevicesParameters; import org.ovirt.engine.core.common.action.VmManagementParametersBase; import org.ovirt.engine.core.common.businessentities.HostDeviceView; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.queries.IdQueryParameters; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.uicommonweb.UICommand; import org.ovirt.engine.ui.uicommonweb.help.HelpTag; import org.ovirt.engine.ui.uicommonweb.models.ConfirmationModel; import org.ovirt.engine.ui.uicommonweb.models.EntityModel; import org.ovirt.engine.ui.uicompat.IFrontendActionAsyncCallback; import org.ovirt.engine.ui.uicompat.UIConstants; import com.google.inject.Inject; public class VmHostDeviceListModel extends HostDeviceListModelBase<VM> { private UICommand addCommand; private UICommand removeCommand; private UICommand repinHostCommand; private final UIConstants constants; @Inject public VmHostDeviceListModel(UIConstants constants) { this.constants = constants; setTitle(constants.hostDevicesTitle()); setHelpTag(HelpTag.vm_host_devices); setHashName("host_devices"); //$NON-NLS-1$ setAddCommand(new UICommand("New", this)); //$NON-NLS-1$ getAddCommand().setIsExecutionAllowed(true); setRemoveCommand(new UICommand("Remove", this)); //$NON-NLS-1$ setRepinHostCommand(new UICommand("RepinHost", this)); //$NON-NLS-1$ getRepinHostCommand().setIsExecutionAllowed(true); getCommands().add(UICommand.createDefaultOkUiCommand("OnRepin", this)); //$NON-NLS-1$ getCommands().add(UICommand.createCancelUiCommand("Cancel", this)); //$NON-NLS-1$ updateActionAvailability(); } private void updateActionAvailability() { getRemoveCommand().setIsExecutionAllowed(!getSelectedPrimaryDeviceNames().isEmpty()); } @Override protected String getListName() { return "VmHostDeviceListModel"; //$NON-NLS-1$ } @Override public void executeCommand(UICommand command) { super.executeCommand(command); if (command == getAddCommand()) { addDevices(); } else if (command == getRemoveCommand()) { removeDevices(); } else if (command == getRepinHostCommand()) { repinHost(); } else if ("OnSave".equals(command.getName())) { //$NON-NLS-1$ onSave(); } else if ("OnRemove".equals(command.getName())) { //$NON-NLS-1$ onRemove(); } else if ("OnRepin".equals(command.getName())) { //$NON-NLS-1$ onRepin(); } else if ("Cancel".equals(command.getName())) { //$NON-NLS-1$ cancel(); } } @Override protected void syncSearch() { if (getEntity() != null) { syncSearch(VdcQueryType.GetExtendedVmHostDevicesByVmId, new IdQueryParameters(getEntity().getId())); } } @Override protected void selectedItemsChanged() { super.selectedItemsChanged(); updateActionAvailability(); } private void addDevices() { if (getWindow() != null) { return; } AddVmHostDevicesModel window = new AddVmHostDevicesModel(); window.init(getEntity()); window.getCommands().add(UICommand.createDefaultOkUiCommand("OnSave", this)); //$NON-NLS-1$ window.getCommands().add(UICommand.createCancelUiCommand("Cancel", this)); //$NON-NLS-1$ setWindow(window); } private void removeDevices() { if (getWindow() != null) { return; } ConfirmationModel window = new ConfirmationModel(); setConfirmWindow(window); window.setTitle(constants.removeHostDevices()); window.setHelpTag(HelpTag.remove_host_device); window.setHashName("remove_host_device"); //$NON-NLS-1$ window.setItems(getSelectedPrimaryDeviceNames()); window.getCommands().add(UICommand.createDefaultOkUiCommand("OnRemove", this)); //$NON-NLS-1$ window.getCommands().add(UICommand.createCancelUiCommand("Cancel", this)); //$NON-NLS-1$ } private void repinHost() { if (getWindow() != null) { return; } RepinHostModel window = new RepinHostModel(); window.init(getEntity()); window.getCommands().add(UICommand.createDefaultOkUiCommand("OnRepin", this)); //$NON-NLS-1$ window.getCommands().add(UICommand.createCancelUiCommand("Cancel", this)); //$NON-NLS-1$ setWindow(window); } private void onSave() { final AddVmHostDevicesModel model = (AddVmHostDevicesModel) getWindow(); if (!model.validate()) { return; } model.startProgress(); if (getEntity().getDedicatedVmForVdsList().isEmpty() || !getEntity().getDedicatedVmForVdsList().contains(model.getPinnedHost().getSelectedItem().getId())) { pinVmToHost(model.getPinnedHost().getSelectedItem().getId(), result -> { if (result.getReturnValue().getSucceeded()) { doAttachDevices(model.getSelectedHostDevices().getItems()); } }); } else { doAttachDevices(model.getSelectedHostDevices().getItems()); } } private void doAttachDevices(Collection<EntityModel<HostDeviceView>> items) { List<String> deviceNamesToAttach = new ArrayList<>(); for (EntityModel<HostDeviceView> model : items) { deviceNamesToAttach.add(model.getEntity().getDeviceName()); } Frontend.getInstance().runAction(VdcActionType.AddVmHostDevices, new VmHostDevicesParameters(getEntity().getId(), deviceNamesToAttach), result -> { syncSearch(); getWindow().stopProgress(); setWindow(null); }); } private void pinVmToHost(Guid hostId, IFrontendActionAsyncCallback callback) { getEntity().setDedicatedVmForVdsList(hostId); Frontend.getInstance().runAction(VdcActionType.UpdateVm, new VmManagementParametersBase(getEntity().getStaticData()), callback); } private void onRemove() { final ConfirmationModel model = (ConfirmationModel) getConfirmWindow(); if (model.getProgress() != null) { return; } model.startProgress(); ArrayList<String> deviceNames = getSelectedPrimaryDeviceNames(); Frontend.getInstance().runAction(VdcActionType.RemoveVmHostDevices, new VmHostDevicesParameters(getEntity().getId(), deviceNames), result -> { model.stopProgress(); setConfirmWindow(null); }); } /** * Returns list of primary (non-placeholder) device names from the current selection. * Returns empty list when none or only placeholder devices are selected. */ private ArrayList<String> getSelectedPrimaryDeviceNames() { ArrayList<String> deviceNames = new ArrayList<>(); if (getSelectedItems() != null) { for (HostDeviceView vmHostDevice : getSelectedItems()) { // only non-placeholder devices should be taken into account if (!vmHostDevice.isIommuPlaceholder()) { deviceNames.add(vmHostDevice.getDeviceName()); } } } return deviceNames; } private void onRepin() { final RepinHostModel model = (RepinHostModel) getWindow(); model.startProgress(); pinVmToHost(model.getPinnedHost().getSelectedItem().getId(), result -> { model.stopProgress(); setWindow(null); }); } private void cancel() { setWindow(null); setConfirmWindow(null); } public UICommand getAddCommand() { return addCommand; } private void setAddCommand(UICommand addCommand) { this.addCommand = addCommand; } public UICommand getRemoveCommand() { return removeCommand; } private void setRemoveCommand(UICommand removeCommand) { this.removeCommand = removeCommand; } public UICommand getRepinHostCommand() { return repinHostCommand; } private void setRepinHostCommand(UICommand repinHostCommand) { this.repinHostCommand = repinHostCommand; } }