package org.ovirt.engine.ui.uicommonweb.models.vms; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.TreeSet; import org.ovirt.engine.core.common.action.RunVmOnceParams; import org.ovirt.engine.core.common.businessentities.BusinessEntitiesDefinitions; import org.ovirt.engine.core.common.businessentities.DisplayType; import org.ovirt.engine.core.common.businessentities.GraphicsDevice; import org.ovirt.engine.core.common.businessentities.GraphicsType; import org.ovirt.engine.core.common.businessentities.InitializationType; import org.ovirt.engine.core.common.businessentities.ServerCpu; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VmInit; import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface; import org.ovirt.engine.core.common.businessentities.storage.Disk; import org.ovirt.engine.core.common.queries.ConfigurationValues; import org.ovirt.engine.core.common.queries.IdQueryParameters; import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.uicommonweb.ICommandTarget; import org.ovirt.engine.ui.uicommonweb.Linq; import org.ovirt.engine.ui.uicommonweb.UICommand; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicommonweb.help.HelpTag; import org.ovirt.engine.ui.uicommonweb.models.EntityModel; import org.ovirt.engine.ui.uicommonweb.models.HasEntity; import org.ovirt.engine.ui.uicommonweb.models.ListModel; import org.ovirt.engine.ui.uicommonweb.models.Model; import org.ovirt.engine.ui.uicommonweb.models.vms.key_value.KeyValueModel; import org.ovirt.engine.ui.uicommonweb.validation.I18NExtraNameOrNoneValidation; import org.ovirt.engine.ui.uicommonweb.validation.IValidation; import org.ovirt.engine.ui.uicommonweb.validation.LengthValidation; import org.ovirt.engine.ui.uicommonweb.validation.MatchFieldsValidator; import org.ovirt.engine.ui.uicommonweb.validation.NoTrimmingWhitespacesValidation; import org.ovirt.engine.ui.uicommonweb.validation.NotEmptyValidation; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.Event; import org.ovirt.engine.ui.uicompat.EventArgs; import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs; import org.ovirt.engine.ui.uicompat.UIConstants; import org.ovirt.engine.ui.uicompat.external.StringUtils; public abstract class RunOnceModel extends Model { // Boot Options tab public static final String RUN_ONCE_COMMAND = "OnRunOnce"; //$NON-NLS-1$ /** The VM that is about to run */ protected final VM vm; /** Listener for events that are triggered by this model */ protected ICommandTarget commandTarget; protected final UICommand runOnceCommand; protected final UICommand cancelCommand; private EntityModel<Boolean> privateAttachFloppy; public EntityModel<Boolean> getAttachFloppy() { return privateAttachFloppy; } private void setAttachFloppy(EntityModel<Boolean> value) { privateAttachFloppy = value; } private ListModel<String> privateFloppyImage; public ListModel<String> getFloppyImage() { return privateFloppyImage; } private void setFloppyImage(ListModel<String> value) { privateFloppyImage = value; } private EntityModel<Boolean> privateAttachIso; public EntityModel<Boolean> getAttachIso() { return privateAttachIso; } private void setAttachIso(EntityModel<Boolean> value) { privateAttachIso = value; } private ListModel<String> privateIsoImage; public ListModel<String> getIsoImage() { return privateIsoImage; } private void setIsoImage(ListModel<String> value) { privateIsoImage = value; } private ListModel<String> kernelImage; public ListModel<String> getKernelImage() { return kernelImage; } public void setKernelImage(ListModel<String> kernelImage) { this.kernelImage = kernelImage; } private ListModel<String> initrdImage; public ListModel<String> getInitrdImage() { return initrdImage; } public void setInitrdImage(ListModel<String> initrdImage) { this.initrdImage = initrdImage; } private ListModel<EntityModel<DisplayType>> privateDisplayProtocol; public ListModel<EntityModel<DisplayType>> getDisplayProtocol() { return privateDisplayProtocol; } private void setDisplayProtocol(ListModel<EntityModel<DisplayType>> value) { privateDisplayProtocol = value; } // Linux Boot Options tab private EntityModel<String> privateKernelParameters; public EntityModel<String> getKernelParameters() { return privateKernelParameters; } private void setKernel_parameters(EntityModel<String> value) { privateKernelParameters = value; } // Initial Boot tab - Sysprep private ListModel<String> privateSysPrepDomainName; public ListModel<String> getSysPrepDomainName() { return privateSysPrepDomainName; } private void setSysPrepDomainName(ListModel<String> value) { privateSysPrepDomainName = value; } private EntityModel<String> privateSysPrepSelectedDomainName; public EntityModel<String> getSysPrepSelectedDomainName() { return privateSysPrepSelectedDomainName; } private void setSysPrepSelectedDomainName(EntityModel<String> value) { privateSysPrepSelectedDomainName = value; } private EntityModel<String> privateSysPrepUserName; public EntityModel<String> getSysPrepUserName() { return privateSysPrepUserName; } private void setSysPrepUserName(EntityModel<String> value) { privateSysPrepUserName = value; } private EntityModel<String> sysPrepPassword; public EntityModel<String> getSysPrepPassword() { return sysPrepPassword; } private void setSysPrepPassword(EntityModel<String> value) { sysPrepPassword = value; } private EntityModel<String> sysPrepPasswordVerification; public EntityModel<String> getSysPrepPasswordVerification() { return sysPrepPasswordVerification; } private void setSysPrepPasswordVerification(EntityModel<String> value) { sysPrepPasswordVerification = value; } private EntityModel<Boolean> privateUseAlternateCredentials; public EntityModel<Boolean> getUseAlternateCredentials() { return privateUseAlternateCredentials; } private void setUseAlternateCredentials(EntityModel<Boolean> value) { privateUseAlternateCredentials = value; } private EntityModel<Boolean> privateIsSysprepEnabled; public EntityModel<Boolean> getIsSysprepEnabled() { return privateIsSysprepEnabled; } private void setIsSysprepEnabled(EntityModel<Boolean> value) { privateIsSysprepEnabled = value; } private EntityModel<Boolean> privateIsSysprepPossible; public EntityModel<Boolean> getIsSysprepPossible() { return privateIsSysprepPossible; } private void setIsSysprepPossible(EntityModel<Boolean> value) { privateIsSysprepPossible = value; } // Initialization private EntityModel<Boolean> privateIsVmFirstRun; public EntityModel<Boolean> getIsVmFirstRun() { return privateIsVmFirstRun; } private void setIsVmFirstRun(EntityModel<Boolean> value) { privateIsVmFirstRun = value; } private EntityModel<Boolean> privateIsLinuxOptionsAvailable; public EntityModel<Boolean> getIsLinuxOptionsAvailable() { return privateIsLinuxOptionsAvailable; } private void setIsLinuxOptionsAvailable(EntityModel<Boolean> value) { privateIsLinuxOptionsAvailable = value; } // Initial Boot tab - Cloud-Init private EntityModel<Boolean> privateIsCloudInitEnabled; public EntityModel<Boolean> getIsCloudInitEnabled() { return privateIsCloudInitEnabled; } private void setIsCloudInitEnabled(EntityModel<Boolean> value) { privateIsCloudInitEnabled = value; } public VmInitModel vmInitModel; public VmInitModel getVmInitModel() { return vmInitModel; } public void setVmInitModel(VmInitModel value) { vmInitModel = value; } private EntityModel<Boolean> privateIsCloudInitPossible; public EntityModel<Boolean> getIsCloudInitPossible() { return privateIsCloudInitPossible; } private void setIsCloudInitPossible(EntityModel<Boolean> value) { privateIsCloudInitPossible = value; } // Custom Properties tab private KeyValueModel customPropertySheet; public KeyValueModel getCustomPropertySheet() { return customPropertySheet; } public void setCustomPropertySheet(KeyValueModel customPropertySheet) { this.customPropertySheet = customPropertySheet; } private EntityModel<Boolean> bootMenuEnabled; public EntityModel<Boolean> getBootMenuEnabled() { return bootMenuEnabled; } public void setBootMenuEnabled(EntityModel<Boolean> bootMenuEnabled) { this.bootMenuEnabled = bootMenuEnabled; } private EntityModel<Boolean> privateRunAndPause; public EntityModel<Boolean> getRunAndPause() { return privateRunAndPause; } public void setRunAndPause(EntityModel<Boolean> value) { privateRunAndPause = value; } private EntityModel<Boolean> privateRunAsStateless; public EntityModel<Boolean> getRunAsStateless() { return privateRunAsStateless; } public void setRunAsStateless(EntityModel<Boolean> value) { privateRunAsStateless = value; } private EntityModel<Boolean> privateRunOnceHeadlessModeIsSelected; public EntityModel<Boolean> getRunOnceHeadlessModeIsSelected() { return privateRunOnceHeadlessModeIsSelected; } public void setRunOnceHeadlessModeIsSelected(EntityModel<Boolean> value) { privateRunOnceHeadlessModeIsSelected = value; } private EntityModel<Boolean> privateDisplayConsole_Vnc_IsSelected; public EntityModel<Boolean> getDisplayConsole_Vnc_IsSelected() { return privateDisplayConsole_Vnc_IsSelected; } public void setDisplayConsole_Vnc_IsSelected(EntityModel<Boolean> value) { privateDisplayConsole_Vnc_IsSelected = value; } private ListModel<String> vncKeyboardLayout; public ListModel<String> getVncKeyboardLayout() { return vncKeyboardLayout; } public void setVncKeyboardLayout(ListModel<String> vncKeyboardLayout) { this.vncKeyboardLayout = vncKeyboardLayout; } // Display Protocol tab private EntityModel<Boolean> privateDisplayConsole_Spice_IsSelected; public EntityModel<Boolean> getDisplayConsole_Spice_IsSelected() { return privateDisplayConsole_Spice_IsSelected; } public void setDisplayConsole_Spice_IsSelected(EntityModel<Boolean> value) { privateDisplayConsole_Spice_IsSelected = value; } private EntityModel<Boolean> spiceFileTransferEnabled; public EntityModel<Boolean> getSpiceFileTransferEnabled() { return spiceFileTransferEnabled; } public void setSpiceFileTransferEnabled(EntityModel<Boolean> spiceFileTransferEnabled) { this.spiceFileTransferEnabled = spiceFileTransferEnabled; } private EntityModel<Boolean> spiceCopyPasteEnabled; public EntityModel<Boolean> getSpiceCopyPasteEnabled() { return spiceCopyPasteEnabled; } public void setSpiceCopyPasteEnabled(EntityModel<Boolean> spiceCopyPasteEnabled) { this.spiceCopyPasteEnabled = spiceCopyPasteEnabled; } // Misc private boolean privateIsLinuxOS; public boolean getIsLinuxOS() { return privateIsLinuxOS; } public void setIsLinuxOS(boolean value) { privateIsLinuxOS = value; } private boolean privateIsWindowsOS; public boolean getIsWindowsOS() { return privateIsWindowsOS; } public void setIsWindowsOS(boolean value) { privateIsWindowsOS = value; } private BootSequenceModel bootSequence; public BootSequenceModel getBootSequence() { return bootSequence; } public void setBootSequence(BootSequenceModel value) { if (bootSequence != value) { bootSequence = value; onPropertyChanged(new PropertyChangedEventArgs("BootSequence")); //$NON-NLS-1$ } } private boolean isHostTabVisible = false; public boolean getIsHostTabVisible() { return isHostTabVisible; } public void setIsHostTabVisible(boolean value) { if (isHostTabVisible != value) { isHostTabVisible = value; onPropertyChanged(new PropertyChangedEventArgs("IsHostTabVisible")); //$NON-NLS-1$ } } private boolean isCustomPropertiesSheetVisible = false; public boolean getIsCustomPropertiesSheetVisible() { return isCustomPropertiesSheetVisible; } public void setIsCustomPropertiesSheetVisible(boolean value) { if (isCustomPropertiesSheetVisible != value) { isCustomPropertiesSheetVisible = value; onPropertyChanged(new PropertyChangedEventArgs("IsCustomPropertiesSheetVisible")); //$NON-NLS-1$ } } // System tab private ListModel<String> emulatedMachine; public ListModel<String> getEmulatedMachine() { return emulatedMachine; } private void setEmulatedMachine(ListModel<String> emulatedMachine) { this.emulatedMachine = emulatedMachine; } private ListModel<String> customCpu; public ListModel<String> getCustomCpu() { return customCpu; } private void setCustomCpu(ListModel<String> customCpu) { this.customCpu = customCpu; } // Host tab private ListModel<VDS> defaultHost; public ListModel<VDS> getDefaultHost() { return defaultHost; } private void setDefaultHost(ListModel<VDS> value) { this.defaultHost = value; } private EntityModel<Boolean> isAutoAssign; public EntityModel<Boolean> getIsAutoAssign() { return isAutoAssign; } public void setIsAutoAssign(EntityModel<Boolean> value) { this.isAutoAssign = value; } // The "sysprep" option was moved from a standalone check box to a // pseudo floppy disk image. In order not to change the back-end // interface, the Reinitialize variable was changed to a read-only // property and its value is based on the selected floppy image. // A similar comparison is done for cloud-init iso images, so the // variable was changed from a boolean to an Enum. public InitializationType getInitializationType() { if (getAttachFloppy().getEntity() != null && getAttachFloppy().getEntity() && "[sysprep]".equals(getFloppyImage().getSelectedItem())) { //$NON-NLS-1$ return InitializationType.Sysprep; } else if (getIsCloudInitEnabled().getEntity() != null && getIsCloudInitEnabled().getEntity()) { return InitializationType.CloudInit; } else { return InitializationType.None; } } public String getFloppyImagePath() { if (getAttachFloppy().getEntity()) { return getInitializationType() == InitializationType.Sysprep ? "" : getFloppyImage().getSelectedItem(); //$NON-NLS-1$ } else { return ""; //$NON-NLS-1$ } } public String getIsoImagePath() { if (getAttachIso().getEntity()) { return getIsoImage().getSelectedItem(); } else { return ""; //$NON-NLS-1$ } } public void setIsoImagePath(String isoPath) { if ("".equals(isoPath)) { //$NON-NLS-1$ getAttachIso().setEntity(false); } else { getAttachIso().setEntity(true); getIsoImage().setSelectedItem(isoPath); } } public RunOnceModel(VM vm, ICommandTarget commandTarget) { this.vm = vm; this.commandTarget = commandTarget; // Boot Options tab setAttachFloppy(new EntityModel<Boolean>()); getAttachFloppy().getEntityChangedEvent().addListener(this); setFloppyImage(new ListModel<String>()); getFloppyImage().getSelectedItemChangedEvent().addListener(this); setAttachIso(new EntityModel<Boolean>()); getAttachIso().getEntityChangedEvent().addListener(this); setIsoImage(new ListModel<String>()); getIsoImage().getSelectedItemChangedEvent().addListener(this); setDisplayProtocol(new ListModel<EntityModel<DisplayType>>()); setBootSequence(new BootSequenceModel()); // Linux Boot Options tab setKernel_parameters(new EntityModel<String>()); setKernelImage(new ListModel<String>()); setInitrdImage(new ListModel<String>()); // Initial Boot tab - Sysprep setIsCloudInitEnabled(new EntityModel<>(false)); setSysPrepDomainName(new ListModel<String>()); setSysPrepSelectedDomainName(new EntityModel<String>()); setSysPrepUserName(new EntityModel<String>().setIsChangeable(false)); setSysPrepPassword(new EntityModel<String>().setIsChangeable(false)); setSysPrepPasswordVerification(new EntityModel<String>().setIsChangeable(false)); setIsSysprepEnabled(new EntityModel<>(false)); setIsSysprepPossible(new EntityModel<Boolean>()); setIsVmFirstRun(new EntityModel<>(false)); getIsVmFirstRun().getEntityChangedEvent().addListener(this); setUseAlternateCredentials(new EntityModel<>(false)); getUseAlternateCredentials().getEntityChangedEvent().addListener(this); // Initial Boot tab - Cloud-Init setIsCloudInitPossible(new EntityModel<Boolean>()); setVmInitModel(new VmInitModel()); // Custom Properties tab setCustomPropertySheet(new KeyValueModel()); setBootMenuEnabled(new EntityModel<>(false)); getBootMenuEnabled().setIsAvailable(true); setRunAndPause(new EntityModel<>(false)); setRunAsStateless(new EntityModel<>(false)); // Display Protocol tab setRunOnceHeadlessModeIsSelected(new EntityModel<Boolean>()); getRunOnceHeadlessModeIsSelected().getEntityChangedEvent().addListener(this); setDisplayConsole_Spice_IsSelected(new EntityModel<Boolean>()); getDisplayConsole_Spice_IsSelected().getEntityChangedEvent().addListener(this); setDisplayConsole_Vnc_IsSelected(new EntityModel<Boolean>()); getDisplayConsole_Vnc_IsSelected().getEntityChangedEvent().addListener(this); setVncKeyboardLayout(new ListModel<String>()); getVncKeyboardLayout().getSelectedItemChangedEvent().addListener(this); initVncKeyboardLayout(); getVncKeyboardLayout().setSelectedItem(vm.getDefaultVncKeyboardLayout()); setSpiceFileTransferEnabled(new EntityModel<Boolean>()); getSpiceFileTransferEnabled().setEntity(vm.isSpiceFileTransferEnabled()); getSpiceFileTransferEnabled().setIsChangeable(true); getSpiceFileTransferEnabled().setIsAvailable(true); setSpiceCopyPasteEnabled(new EntityModel<Boolean>()); getSpiceCopyPasteEnabled().setEntity(vm.isSpiceCopyPasteEnabled()); getSpiceCopyPasteEnabled().setIsChangeable(true); getSpiceCopyPasteEnabled().setIsAvailable(true); // System tab setEmulatedMachine(new ListModel<String>()); getEmulatedMachine().setSelectedItem(vm.getCustomEmulatedMachine()); setCustomCpu(new ListModel<String>()); getCustomCpu().setSelectedItem(vm.getCustomCpuName()); // Host tab setDefaultHost(new ListModel<VDS>()); getDefaultHost().getSelectedItemChangedEvent().addListener(this); setIsAutoAssign(new EntityModel<Boolean>()); getIsAutoAssign().getEntityChangedEvent().addListener(this); // availability/visibility setIsLinuxOptionsAvailable(new EntityModel<>(false)); setIsHostTabVisible(true); setIsCustomPropertiesSheetVisible(true); setIsLinuxOS(false); setIsWindowsOS(false); runOnceCommand = UICommand.createDefaultOkUiCommand(RunOnceModel.RUN_ONCE_COMMAND, this); cancelCommand = UICommand.createCancelUiCommand(Model.CANCEL_COMMAND, this); getCommands().addAll(Arrays.asList(runOnceCommand, cancelCommand)); } public void init() { setTitle(ConstantsManager.getInstance().getConstants().runVirtualMachinesTitle()); setHelpTag(HelpTag.run_once_virtual_machine); setHashName("run_once_virtual_machine"); //$NON-NLS-1$ setIsoImagePath(vm.getIsoPath()); // needs to be called before iso list is updated getAttachFloppy().setEntity(false); getBootMenuEnabled().setEntity(true); getRunAsStateless().setEntity(vm.isStateless()); getRunAndPause().setEntity(vm.isRunAndPause()); // passing Kernel parameters getKernelParameters().setEntity(vm.getKernelParams()); setIsLinuxOS(AsyncDataProvider.getInstance().isLinuxOsType(vm.getVmOsId())); getIsLinuxOptionsAvailable().setEntity(getIsLinuxOS()); setIsWindowsOS(AsyncDataProvider.getInstance().isWindowsOsType(vm.getVmOsId())); getIsVmFirstRun().setEntity(!vm.isInitialized()); initVmInitEnabled(vm.getVmInit(), vm.isInitialized()); getVmInitModel().init(vm.getStaticData()); toggleAutoSetVmHostname(); updateDomainList(); updateSystemTabLists(); updateIsoList(); updateUnknownTypeImagesList(); updateFloppyImages(); updateInitialRunFields(); // Boot sequence. setIsBootFromNetworkAllowedForVm(); setIsBootFromHardDiskAllowedForVm(); // Display protocols. if (vm.getDefaultDisplayType() != DisplayType.none) { updateDisplayProtocols(); } else { getRunOnceHeadlessModeIsSelected().setEntity(true); } EntityModel<DisplayType> vncProtocol = new EntityModel<>(DisplayType.vga) .setTitle(ConstantsManager.getInstance().getConstants().vncTitle()); EntityModel<DisplayType> qxlProtocol = new EntityModel<>(DisplayType.qxl) .setTitle(ConstantsManager.getInstance().getConstants().spiceTitle()); boolean hasSpiceSupport = AsyncDataProvider.getInstance().hasSpiceSupport(vm.getOs(), vm.getCompatibilityVersion()); if (hasSpiceSupport) { getDisplayProtocol().setItems(Arrays.asList(vncProtocol, qxlProtocol)); } else { getDisplayProtocol().setItems(Arrays.asList(vncProtocol)); getDisplayConsole_Spice_IsSelected().setIsAvailable(false); } getDisplayProtocol().setSelectedItem(vm.getDefaultDisplayType() == DisplayType.vga ? vncProtocol : qxlProtocol); getSpiceFileTransferEnabled().setEntity(vm.isSpiceFileTransferEnabled()); getSpiceCopyPasteEnabled().setEntity(vm.isSpiceCopyPasteEnabled()); AsyncDataProvider.isFloppySupported(new AsyncQuery<>(isFloppySupported -> { if (!isFloppySupported) { getAttachFloppy().setIsAvailable(false); getFloppyImage().setIsAvailable(false); } }), vm.getOs(), vm.getCompatibilityVersion()); } private void initVmInitEnabled(VmInit vmInit, boolean isInitialized) { if (vmInit == null) { getIsCloudInitEnabled().setEntity(false); getIsSysprepEnabled().setEntity(false); getAttachFloppy().setEntity(false); } else if (!isInitialized) { if (getIsWindowsOS()) { getIsSysprepEnabled().setEntity(true); getAttachFloppy().setEntity(true); } else { getIsCloudInitEnabled().setEntity(true); } } } protected RunVmOnceParams createRunVmOnceParams() { RunVmOnceParams params = new RunVmOnceParams(); params.setVmId(vm.getId()); params.setBootSequence(getBootSequence().getSequence()); params.setDiskPath(getIsoImagePath()); params.setFloppyPath(getFloppyImagePath()); params.setBootMenuEnabled(getBootMenuEnabled().getEntity()); params.setRunAndPause(getRunAndPause().getEntity()); params.setRunAsStateless(getRunAsStateless().getEntity()); params.setInitializationType(getInitializationType()); params.setCustomProperties(getCustomPropertySheet().serialize()); // kernel params String selectedKernelImage = getKernelImage().getSelectedItem(); if (!StringUtils.isEmpty(selectedKernelImage)) { params.setKernelUrl(selectedKernelImage); } if (getKernelParameters().getEntity() != null) { params.setKernelParams(getKernelParameters().getEntity()); } String selectedInitrdImage = getInitrdImage().getSelectedItem(); if (!StringUtils.isEmpty(selectedInitrdImage)) { params.setInitrdUrl(selectedInitrdImage); } // Sysprep params if (getSysPrepUserName().getEntity() != null) { params.setSysPrepUserName(getSysPrepUserName().getEntity()); } if (getSysPrepPassword().getEntity() != null) { params.setSysPrepPassword(getSysPrepPassword().getEntity()); } if (getIsCloudInitEnabled() != null && getIsCloudInitEnabled().getEntity() || getIsSysprepEnabled() != null && getIsSysprepEnabled().getEntity()) { params.setVmInit(getVmInitModel().buildCloudInitParameters(this)); } if (getRunOnceHeadlessModeIsSelected().getEntity()) { params.getRunOnceGraphics().clear(); params.setRunOnceDisplayType(DisplayType.none); } else { params.getRunOnceGraphics().add(Boolean.TRUE.equals(getDisplayConsole_Vnc_IsSelected().getEntity()) ? GraphicsType.VNC : GraphicsType.SPICE); if (vm.getDefaultDisplayType() == DisplayType.none) { params.setRunOnceDisplayType(params.getRunOnceGraphics().contains(GraphicsType.SPICE) ? DisplayType.qxl : DisplayType.cirrus); } } params.setVncKeyboardLayout(getVncKeyboardLayout().getSelectedItem()); String selectedDomain = getSysPrepSelectedDomainName().getEntity(); if (!StringHelper.isNullOrEmpty(selectedDomain)) { params.setSysPrepDomainName(selectedDomain); } String selectedEmulatedMachine = getEmulatedMachine().getSelectedItem(); if (!StringHelper.isNullOrEmpty(selectedEmulatedMachine)) { params.setCustomEmulatedMachine(selectedEmulatedMachine); } String selectedCustomCpu = getCustomCpu().getSelectedItem(); if (!StringHelper.isNullOrEmpty(selectedCustomCpu)) { params.setCustomCpuName(selectedCustomCpu); } params.setSpiceFileTransferEnabled(getSpiceFileTransferEnabled().getEntity()); params.setSpiceCopyPasteEnabled(getSpiceCopyPasteEnabled().getEntity()); return params; } protected void updateFloppyImages() { AsyncDataProvider.getInstance().getFloppyImageList(new AsyncQuery<>( images -> { VM selectedVM = vm; if (AsyncDataProvider.getInstance().isWindowsOsType(selectedVM.getVmOsId())) { // Add a pseudo floppy disk image used for Windows' sysprep. if (!selectedVM.isInitialized() && vm.getVmInit() != null) { images.add(0, "[sysprep]"); //$NON-NLS-1$ getAttachFloppy().setEntity(true); } else { images.add("[sysprep]"); //$NON-NLS-1$ } } getFloppyImage().setItems(images); if (getFloppyImage().getIsChangable() && getFloppyImage().getSelectedItem() == null) { getFloppyImage().setSelectedItem(Linq.firstOrNull(images)); } }), vm.getStoragePoolId()); } private void setIsBootFromHardDiskAllowedForVm() { Frontend.getInstance().runQuery(VdcQueryType.GetAllDisksByVmId, new IdQueryParameters(vm.getId()), new AsyncQuery<VdcQueryReturnValue>(returnValue -> { ArrayList<Disk> vmDisks = returnValue.getReturnValue(); if (vmDisks.isEmpty()) { getRunAsStateless().setIsChangeable(false); getRunAsStateless() .setChangeProhibitionReason(ConstantsManager.getInstance() .getMessages() .disklessVmCannotRunAsStateless()); getRunAsStateless().setEntity(false); } if (!isDisksContainBootableDisk(vmDisks)) { BootSequenceModel bootSequenceModel = getBootSequence(); bootSequenceModel.getHardDiskOption().setIsChangeable(false); bootSequenceModel.getHardDiskOption() .setChangeProhibitionReason(ConstantsManager.getInstance() .getMessages() .bootableDiskIsRequiredToBootFromDisk()); } })); } private boolean isDisksContainBootableDisk(List<Disk> disks) { for (Disk disk : disks) { if (disk.getDiskVmElementForVm(vm.getId()).isBoot()) { return true; } } return false; } private void setIsBootFromNetworkAllowedForVm() { Frontend.getInstance().runQuery(VdcQueryType.GetVmInterfacesByVmId, new IdQueryParameters(vm.getId()), new AsyncQuery<VdcQueryReturnValue>(returnValue -> { Collection<VmNetworkInterface> nics = returnValue.getReturnValue(); boolean hasPluggedNics = nics.stream().anyMatch(VmNetworkInterface::isPlugged); if (!hasPluggedNics) { BootSequenceModel bootSequenceModel = getBootSequence(); bootSequenceModel.getNetworkOption().setIsChangeable(false); bootSequenceModel.getNetworkOption() .setChangeProhibitionReason(ConstantsManager.getInstance() .getMessages() .interfaceIsRequiredToBootFromNetwork()); } })); } private void updateDisplayProtocols() { Frontend.getInstance().runQuery(VdcQueryType.GetGraphicsDevices, new IdQueryParameters(vm.getId()), new AsyncQuery<VdcQueryReturnValue>(returnValue -> { boolean selectVnc = false; List<GraphicsDevice> graphicsDevices = returnValue.getReturnValue(); if (graphicsDevices.size() == 1 && graphicsDevices.get(0).getGraphicsType() == GraphicsType.VNC) { selectVnc = true; } getDisplayConsole_Vnc_IsSelected().setEntity(selectVnc); getDisplayConsole_Spice_IsSelected().setEntity(!selectVnc); })); } public void updateIsoList() { updateIsoList(false); } public void updateUnknownTypeImagesList() { updateUnknownTypeImagesList(false); } public void updateUnknownTypeImagesList(boolean forceRefresh) { AsyncDataProvider.getInstance().getUnknownImageList(new AsyncQuery<>(images -> { getKernelImage().setItems(images); getInitrdImage().setItems(images); getKernelImage().setSelectedItem(null); getInitrdImage().setSelectedItem(null); }), vm.getStoragePoolId(), forceRefresh); } public void updateIsoList(boolean forceRefresh) { AsyncDataProvider.getInstance().getIrsImageList(new AsyncQuery<>( images -> { final String lastSelectedIso = getIsoImage().getSelectedItem(); getIsoImage().setItems(images); if (getIsoImage().getIsChangable()) { // try to preselect last image if (lastSelectedIso != null && images.contains(lastSelectedIso)) { getIsoImage().setSelectedItem(lastSelectedIso); } else { getIsoImage().setSelectedItem(Linq.firstOrNull(images)); } } }), vm.getStoragePoolId(), forceRefresh); } private void updateDomainList() { // Update Domain list AsyncDataProvider.getInstance().getAuthzExtensionsNames(new AsyncQuery<>(domains -> { String oldDomain = getSysPrepDomainName().getSelectedItem(); if (oldDomain != null && !oldDomain.equals("") && !domains.contains(oldDomain)) { //$NON-NLS-1$ domains.add(0, oldDomain); } getSysPrepDomainName().setItems(domains); String selectedDomain = (oldDomain != null) ? oldDomain : Linq.firstOrNull(domains); if (!StringHelper.isNullOrEmpty(selectedDomain)) { getSysPrepDomainName().setSelectedItem(selectedDomain); } })); } private void updateSystemTabLists() { Guid clusterId = vm.getClusterId(); if (clusterId != null) { // update emulated machine list AsyncDataProvider.getInstance().getEmulatedMachinesByClusterID(new AsyncQuery<>( emulatedSet -> { if (emulatedSet != null) { String oldVal = getEmulatedMachine().getSelectedItem(); getEmulatedMachine().setItems(new TreeSet<>(emulatedSet)); getEmulatedMachine().setSelectedItem(oldVal);// even if converted - needed as fallback convertEmulatedMachineField(); } }), clusterId); AsyncDataProvider.getInstance().getClusterById(new AsyncQuery<>( cluster -> { if (cluster != null) { // update cpu names list if (cluster.getCpuName() != null) { AsyncDataProvider.getInstance().getSupportedCpuList(new AsyncQuery<>( returnValue -> { if (returnValue != null) { List<String> cpuList = new ArrayList<>(); for (ServerCpu cpu : returnValue) { cpuList.add(cpu.getVdsVerbData()); } String oldVal = getCustomCpu().getSelectedItem(); getCustomCpu().setItems(cpuList); // replace 'cluster cpu' with the explicit run-time value if (StringHelper.isNullOrEmpty(oldVal) && !cpuList.isEmpty()) { getCustomCpu().setSelectedItem(cpuList.get( cpuList.size() - 1)); } else { getCustomCpu().setSelectedItem(oldVal); } } }), cluster.getCpuName()); } } }), clusterId); } } // replace 'cluster emulated machine' with the explicit run-time value private void convertEmulatedMachineField() { if (StringHelper.isNullOrEmpty(getEmulatedMachine().getSelectedItem())) { Guid clusterId = vm.getClusterId(); if (clusterId != null) { AsyncDataProvider.getInstance().getClusterById(new AsyncQuery<>( cluster -> { if (cluster != null) { if (cluster.getEmulatedMachine() != null) { getEmulatedMachine().setSelectedItem(cluster.getEmulatedMachine()); } } }), clusterId); } } } public void sysPrepListBoxChanged() { getSysPrepSelectedDomainName().setEntity(getSysPrepDomainName().getSelectedItem()); } @Override public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) { super.eventRaised(ev, sender, args); if (ev.matchesDefinition(ListModel.selectedItemChangedEventDefinition)) { if (sender == getIsoImage()) { IsoImage_SelectedItemChanged(); } else if (sender == getFloppyImage()) { floppyImage_SelectedItemChanged(); } } else if (ev.matchesDefinition(HasEntity.entityChangedEventDefinition)) { if (sender == getAttachFloppy()) { attachFloppy_EntityChanged(); } else if (sender == getAttachIso()) { attachIso_EntityChanged(); } else if (sender == getIsVmFirstRun()) { isVmFirstRun_EntityChanged(); } else if (sender == getUseAlternateCredentials()) { useAlternateCredentials_EntityChanged(); } else if (sender == getDisplayConsole_Vnc_IsSelected() && ((EntityModel<Boolean>) sender).getEntity()) { getRunOnceHeadlessModeIsSelected().setEntity(false); getDisplayConsole_Spice_IsSelected().setEntity(false); getVncKeyboardLayout().setIsChangeable(true); getSpiceFileTransferEnabled().setIsChangeable(false); getSpiceCopyPasteEnabled().setIsChangeable(false); } else if (sender == getDisplayConsole_Spice_IsSelected() && ((EntityModel<Boolean>) sender).getEntity()) { getRunOnceHeadlessModeIsSelected().setEntity(false); getDisplayConsole_Vnc_IsSelected().setEntity(false); getVncKeyboardLayout().setIsChangeable(false); getSpiceFileTransferEnabled().setIsChangeable(true); getSpiceCopyPasteEnabled().setIsChangeable(true); } else if (sender == getRunOnceHeadlessModeIsSelected() && ((EntityModel<Boolean>) sender).getEntity()) { getDisplayConsole_Vnc_IsSelected().setEntity(false); getDisplayConsole_Spice_IsSelected().setEntity(false); getVncKeyboardLayout().setIsChangeable(false); getSpiceFileTransferEnabled().setIsChangeable(false); getSpiceCopyPasteEnabled().setIsChangeable(false); } else if (sender == getIsAutoAssign()) { isAutoAssign_EntityChanged(sender, args); } } } private void attachIso_EntityChanged() { getIsoImage().setIsChangeable(getAttachIso().getEntity()); getBootSequence().getCdromOption().setIsChangeable(getAttachIso().getEntity()); updateInitialRunFields(); } private void attachFloppy_EntityChanged() { getFloppyImage().setIsChangeable(getAttachFloppy().getEntity()); updateInitialRunFields(); } private void useAlternateCredentials_EntityChanged() { boolean useAlternateCredentials = getUseAlternateCredentials().getEntity(); getSysPrepUserName().setIsChangeable(getUseAlternateCredentials().getEntity()); getSysPrepPassword().setIsChangeable(getUseAlternateCredentials().getEntity()); getSysPrepPasswordVerification().setIsChangeable(getUseAlternateCredentials().getEntity()); getSysPrepUserName().setEntity(useAlternateCredentials ? "" : null); //$NON-NLS-1$ getSysPrepPassword().setEntity(useAlternateCredentials ? "" : null); //$NON-NLS-1$ getSysPrepPasswordVerification().setEntity(useAlternateCredentials ? "" : null); //$NON-NLS-1$ } private void isVmFirstRun_EntityChanged() { updateInitialRunFields(); } private void floppyImage_SelectedItemChanged() { updateInitialRunFields(); } private void IsoImage_SelectedItemChanged() { updateInitialRunFields(); } private void isAutoAssign_EntityChanged(Object sender, EventArgs args) { if (!getIsAutoAssign().getEntity()) { getDefaultHost().setIsChangeable(true); } } // Sysprep/cloud-init sections displayed only with proper OS type (Windows // or Linux, respectively) and when proper floppy or CD is attached. // Currently vm.isFirstRun() status is not considered. public void updateInitialRunFields() { getIsSysprepPossible().setEntity(getIsWindowsOS()); getIsSysprepEnabled().setEntity(getInitializationType() == InitializationType.Sysprep); // also other can be cloud inited getIsCloudInitPossible().setEntity(!getIsWindowsOS()); getIsCloudInitEnabled().setEntity(getInitializationType() == InitializationType.CloudInit); getIsCloudInitEnabled().setIsAvailable(!getIsWindowsOS()); if (getIsSysprepPossible().getEntity() && getIsSysprepEnabled().getEntity()) { getVmInitModel().updateSysprepDomain(getVmInitModel().getSysprepDomain().getSelectedItem()); } } public boolean validate() { getIsoImage().setIsValid(true); if (getAttachIso().getEntity()) { getIsoImage().validateSelectedItem(new IValidation[] { new NotEmptyValidation() }); } getFloppyImage().setIsValid(true); if (getAttachFloppy().getEntity()) { getFloppyImage().validateSelectedItem(new IValidation[] { new NotEmptyValidation() }); } boolean customPropertyValidation = getCustomPropertySheet().validate(); if (getIsLinuxOS()) { getKernelImage().validateSelectedItem(new IValidation[] { new NoTrimmingWhitespacesValidation() }); getInitrdImage().validateSelectedItem(new IValidation[] { new NoTrimmingWhitespacesValidation() }); getKernelParameters().validateEntity(new IValidation[] { new NoTrimmingWhitespacesValidation() }); // initrd path and kernel params require kernel path to be filled if (StringHelper.isNullOrEmpty(getKernelImage().getSelectedItem())) { final UIConstants constants = ConstantsManager.getInstance().getConstants(); if (!StringHelper.isNullOrEmpty(getInitrdImage().getSelectedItem())) { getInitrdImage().getInvalidityReasons().add(constants.initrdPathInvalid()); getInitrdImage().setIsValid(false); getKernelImage().getInvalidityReasons().add(constants.initrdPathInvalid()); getKernelImage().setIsValid(false); } if (!StringHelper.isNullOrEmpty(getKernelParameters().getEntity())) { getKernelParameters().getInvalidityReasons().add(constants.kernelParamsInvalid()); getKernelParameters().setIsValid(false); getKernelImage().getInvalidityReasons().add(constants.kernelParamsInvalid()); getKernelImage().setIsValid(false); } } } if (getIsAutoAssign().getEntity() != null && !getIsAutoAssign().getEntity()) { getDefaultHost().validateSelectedItem(new IValidation[] { new NotEmptyValidation() }); } else { getDefaultHost().setIsValid(true); } getSysPrepPassword().setIsValid(true); getSysPrepPasswordVerification().setIsValid(true); if (getIsWindowsOS() && getIsSysprepEnabled().getEntity()) { getSysPrepPassword().validateEntity(new IValidation[] { new NotEmptyValidation(), new MatchFieldsValidator(getSysPrepPassword().getEntity(), getSysPrepPasswordVerification().getEntity()) }); } boolean cloudInitIsValid = getVmInitModel().validate(); getEmulatedMachine().validateSelectedItem(new IValidation[] { new I18NExtraNameOrNoneValidation(), new LengthValidation(BusinessEntitiesDefinitions.VM_EMULATED_MACHINE_SIZE) }); getCustomCpu().validateSelectedItem(new IValidation[] { new I18NExtraNameOrNoneValidation(), new LengthValidation(BusinessEntitiesDefinitions.VM_CPU_NAME_SIZE) }); return getIsoImage().getIsValid() && getFloppyImage().getIsValid() && getKernelImage().getIsValid() && getInitrdImage().getIsValid() && getKernelParameters().getIsValid() && getDefaultHost().getIsValid() && customPropertyValidation && cloudInitIsValid && getSysPrepPassword().getIsValid() && getEmulatedMachine().getIsValid() && getCustomCpu().getIsValid(); } @Override public void executeCommand(UICommand command) { super.executeCommand(command); if (command == runOnceCommand) { if (validate()) { onRunOnce(); } } else if (command == cancelCommand) { commandTarget.executeCommand(command); } } protected abstract void onRunOnce(); private void initVncKeyboardLayout() { List<String> layouts = (List<String>) AsyncDataProvider.getInstance().getConfigValuePreConverted(ConfigurationValues.VncKeyboardLayoutValidValues); List<String> vncKeyboardLayoutItems = new ArrayList<>(); vncKeyboardLayoutItems.add(null); vncKeyboardLayoutItems.addAll(layouts); getVncKeyboardLayout().setItems(vncKeyboardLayoutItems); getVncKeyboardLayout().setIsChangeable(false); } public void autoSetVmHostname() { getVmInitModel().autoSetHostname(vm.getName()); } private void toggleAutoSetVmHostname() { if (vm.getVmInit() != null && vm.getName() != null && !vm.getName().equals(vm.getVmInit().getHostname())) { getVmInitModel().disableAutoSetHostname(); } } }