Roy Golan has uploaded a new change for review. Change subject: core: Import the hosted engine VM if its no manged ......................................................................
core: Import the hosted engine VM if its no manged Let the monitoring import the HE VM if its not in the setup already PRECONDITIONS - The hosted engine Storage Domain (name Hosted_Engine) should be imported into the setup and be up - The engine VM should already be in the db. The Vm is an external Vm at fist and assumed to be added by the monitoring of the host IMPORT the import rely on the "full list" response from vdsm to get all data that is out there. the disks are assumed to be on the target storage domain. NEW OriginType.MANAGED_HOSTED_ENGINE was added to mark that VM is managed from now on and to signal the monitoring on when its not imported and should be Change-Id: I0ff2c440785cb91e3beef0530eda77324cc954d0 Bug-Url: https://bugzilla.redhat.com/ Signed-off-by: Roy Golan <rgo...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsEventListener.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/IVdsEventListener.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/OriginType.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java 8 files changed, 187 insertions(+), 2 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/95/42295/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsEventListener.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsEventListener.java index 353c81c..d7e5be3 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsEventListener.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsEventListener.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.concurrent.Callable; +import javax.ejb.EJB; import javax.enterprise.event.Observes; import javax.enterprise.inject.Instance; import javax.inject.Inject; @@ -18,6 +19,7 @@ import org.ovirt.engine.core.bll.context.EngineContext; import org.ovirt.engine.core.bll.host.AvailableUpdatesFinder; import org.ovirt.engine.core.bll.hostdev.HostDeviceManager; +import org.ovirt.engine.core.bll.interfaces.BackendInternal; import org.ovirt.engine.core.bll.job.ExecutionHandler; import org.ovirt.engine.core.bll.scheduling.SchedulingManager; import org.ovirt.engine.core.bll.storage.StoragePoolStatusHandler; @@ -27,10 +29,12 @@ import org.ovirt.engine.core.common.action.ConnectHostToStoragePoolServersParameters; import org.ovirt.engine.core.common.action.FenceVdsActionParameters; import org.ovirt.engine.core.common.action.HostStoragePoolParametersBase; +import org.ovirt.engine.core.common.action.ImportVmParameters; import org.ovirt.engine.core.common.action.MaintenanceNumberOfVdssParameters; import org.ovirt.engine.core.common.action.MigrateVmToServerParameters; import org.ovirt.engine.core.common.action.ProcessDownVmParameters; import org.ovirt.engine.core.common.action.ReconstructMasterParameters; +import org.ovirt.engine.core.common.action.RemoveVmParameters; import org.ovirt.engine.core.common.action.SetNonOperationalVdsParameters; import org.ovirt.engine.core.common.action.SetStoragePoolStatusParameters; import org.ovirt.engine.core.common.action.StorageDomainParametersBase; @@ -42,22 +46,32 @@ import org.ovirt.engine.core.common.businessentities.IVdsAsyncCommand; import org.ovirt.engine.core.common.businessentities.IVdsEventListener; import org.ovirt.engine.core.common.businessentities.NonOperationalReason; +import org.ovirt.engine.core.common.businessentities.OriginType; +import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.StorageDomainStatic; +import org.ovirt.engine.core.common.businessentities.StorageDomainStatus; import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VmDynamic; import org.ovirt.engine.core.common.businessentities.VmStatic; import org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterStatus; import org.ovirt.engine.core.common.businessentities.qos.CpuQos; +import org.ovirt.engine.core.common.businessentities.storage.DiskImage; +import org.ovirt.engine.core.common.config.Config; +import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.errors.VdcBllErrors; import org.ovirt.engine.core.common.errors.VdcBllMessages; import org.ovirt.engine.core.common.eventqueue.Event; import org.ovirt.engine.core.common.eventqueue.EventQueue; import org.ovirt.engine.core.common.eventqueue.EventResult; import org.ovirt.engine.core.common.eventqueue.EventType; +import org.ovirt.engine.core.common.interfaces.SearchType; import org.ovirt.engine.core.common.locks.LockingGroup; +import org.ovirt.engine.core.common.queries.SearchParameters; +import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.common.vdscommands.DisconnectStoragePoolVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.UpdateVmPolicyVDSParams; @@ -67,6 +81,8 @@ import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase; +import org.ovirt.engine.core.dao.VdsGroupDAO; +import org.ovirt.engine.core.dao.profiles.DiskProfileDao; import org.ovirt.engine.core.di.Injector; import org.ovirt.engine.core.utils.linq.Function; import org.ovirt.engine.core.utils.linq.LinqUtils; @@ -90,6 +106,12 @@ private AvailableUpdatesFinder availableUpdatesFinder; @Inject AutoStartVmsRunner autoStartVmsRunner; + @EJB + BackendInternal backend; + @Inject + VdsGroupDAO vdsGroupDAO; + @Inject + DiskProfileDao diskProfileDao; private static final Logger log = LoggerFactory.getLogger(VdsEventListener.class); @@ -510,4 +532,52 @@ public boolean isUpdateAvailable(VDS host) { return availableUpdatesFinder.isUpdateAvailable(host); } + + @Override + public void importHostedEngineVm(final VM vm, final Guid vdsGroupId) { + ThreadPoolUtil.execute(new Runnable() { + public void run() { + // get the special sd of hosted engine + StorageDomain sd = (StorageDomain) ((ArrayList) backend.runInternalQuery( + VdcQueryType.Search, + new SearchParameters( + "Storage: name=" + Config.<String>getValue(ConfigValues.HostedEngineStorageDomainName), + SearchType.StorageDomain + ) + ).getReturnValue()).get(0); + // no point in trying this without the SD + if (sd != null && sd.getStatus() == StorageDomainStatus.Active) { + // first remove the vm(status up valid in this case, for removal) and then import it + boolean removedUnmanagedHEVM = backend.runInternalAction( + VdcActionType.RemoveVm, + new RemoveVmParameters(vm.getId(), true)).getSucceeded(); + if (removedUnmanagedHEVM) { + // now import the VM with its disks + ImportVmParameters parameters = new ImportVmParameters( + vm, + sd.getId(), + sd.getId(), + sd.getStoragePoolId(), + vdsGroupId); + // assumption is that there's only 1 profile for hosted engine domain. its an unmanged domain. + Guid sdProfileId = diskProfileDao.getAllForStorageDomain(sd.getId()).get(0).getId(); + for (DiskImage image : vm.getImages()) { + image.setDiskProfileId(sdProfileId); + image.setStorageIds(new ArrayList(Arrays.asList(sd.getId()))); + image.setVmSnapshotId(Guid.newGuid()); + } + // disks are there already(the vm is running) + parameters.setImagesExistOnTargetStorageDomain(true); + // distinguish from "regular" he vm. + vm.setOrigin(OriginType.MANAGED_HOSTED_ENGINE); + // architecture is a missing attribute from vdsm structure. relying on the cluster is perfectly reliable. + vm.setClusterArch(vdsGroupDAO.get(vdsGroupId).getArchitecture()); + backend.runInternalAction( + VdcActionType.ImportVm, + parameters); + } + } + } + }); + } } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java index a34c82b..6861e0e 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VmHandler.java @@ -156,6 +156,8 @@ COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.CancelMigrateVm); COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.SetVmTicket); COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.VmLogon); + COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.UpdateVm); + COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.RemoveVm); } public static boolean isUpdateValid(VmStatic source, VmStatic destination, VMStatus status) { diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/IVdsEventListener.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/IVdsEventListener.java index d67573b..2c41b4d 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/IVdsEventListener.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/IVdsEventListener.java @@ -81,4 +81,6 @@ void refreshHostIfAnyVmHasHostDevices(List<Guid> vmIds, Guid hostId); boolean isUpdateAvailable(VDS host); + + void importHostedEngineVm(VM vm, Guid vdsGroupId); } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/OriginType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/OriginType.java index 782edaf..a585cb6 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/OriginType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/OriginType.java @@ -11,7 +11,9 @@ // VMs that externally run on the host (not created by the engine) EXTERNAL(4), // VMs that were created by the hosted engine setup - HOSTED_ENGINE(5); + HOSTED_ENGINE(5), + // managed means we allow limited provisioning on this VM by the engine + MANAGED_HOSTED_ENGINE(6); private int intValue; private static Map<Integer, OriginType> mappings; diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java index deb1b8d..c76ea24 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VM.java @@ -1781,7 +1781,7 @@ } public boolean isHostedEngine() { - return OriginType.HOSTED_ENGINE.equals(getOrigin()); + return OriginType.HOSTED_ENGINE == getOrigin() || OriginType.MANAGED_HOSTED_ENGINE == getOrigin(); } public boolean isExternalVm() { diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java index feded40..5905b91 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmAnalyzer.java @@ -3,6 +3,7 @@ import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.common.AuditLogType; +import org.ovirt.engine.core.common.businessentities.OriginType; import org.ovirt.engine.core.common.businessentities.UnchangeableByVdsm; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.VM; @@ -74,6 +75,7 @@ private boolean stable; private boolean autoVmToRun; private boolean externalVm; + private boolean hostedEngineUnmanaged; //dependencies private final VmsMonitoring vmsMonitoring; // aggregate all data using it. @@ -120,6 +122,7 @@ updateLunDisks(); updateVmJobs(); analyzeExternalVms(); + analyzeHostedEngineVm(); if (vmDynamicToSave != null) { vmsMonitoring.addVmDynamicToList(vmDynamicToSave); } @@ -136,6 +139,14 @@ if (getDbFacade().getVmStaticDao().get(vdsmVm.getVmDynamic().getId()) == null) { externalVm = true; } + } + } + + private void analyzeHostedEngineVm() { + if (dbVm != null + && vdsmVm != null + && dbVm.getOrigin() == OriginType.HOSTED_ENGINE) { + hostedEngineUnmanaged = true; } } @@ -1016,4 +1027,8 @@ public VdsManager getVdsManager() { return vmsMonitoring.getVdsManager(); } + + public boolean isHostedEngineUnmanaged() { + return hostedEngineUnmanaged; + } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java index de6209c..1aecd85d 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/VmsMonitoring.java @@ -29,6 +29,7 @@ import org.ovirt.engine.core.common.businessentities.VmStatistics; import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface; import org.ovirt.engine.core.common.businessentities.network.VmNetworkStatistics; +import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.businessentities.storage.DiskImageDynamic; import org.ovirt.engine.core.common.businessentities.storage.LUNs; import org.ovirt.engine.core.common.utils.Pair; @@ -42,6 +43,7 @@ import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; import org.ovirt.engine.core.utils.transaction.TransactionMethod; import org.ovirt.engine.core.utils.transaction.TransactionSupport; +import org.ovirt.engine.core.vdsbroker.vdsbroker.VdsBrokerObjectsBuilder; import org.ovirt.engine.core.vdsbroker.vdsbroker.VdsProperties; import org.ovirt.engine.core.vdsbroker.vdsbroker.entities.VmInternalData; import org.slf4j.Logger; @@ -235,6 +237,19 @@ ResourceManager.getInstance().RemoveAsyncRunningVm(vmUpdater.getDbVm().getId()); } + if (vmUpdater.isHostedEngineUnmanaged()) { + Map vmStruct = getVmInfo(Collections.singletonList(vmUpdater.getVdsmVm() + .getVmDynamic() + .getId() + .toString()))[0]; + VM vm = VdsBrokerObjectsBuilder.buildVmsDataFromExternalProvider(vmStruct); + vm.setImages(VdsBrokerObjectsBuilder.BuildDiskImagesFromDevices(vmStruct)); + vm.setInterfaces(VdsBrokerObjectsBuilder.BuildVmNetworkInterfacesFromDevices(vmStruct)); + for (DiskImage diskImage : vm.getImages()) { + vm.getDiskMap().put(Guid.newGuid(), diskImage); + } + getVdsEventListener().importHostedEngineVm(vm, getVdsManager().getVdsGroupId()); + } } getVdsEventListener().updateSlaPolicies(succeededToRunVms, vdsManager.getVdsId()); diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java index 39052bb..f953297 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsBrokerObjectsBuilder.java @@ -68,8 +68,11 @@ import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.businessentities.storage.DiskImageDynamic; +import org.ovirt.engine.core.common.businessentities.storage.DiskInterface; import org.ovirt.engine.core.common.businessentities.storage.LUNs; import org.ovirt.engine.core.common.businessentities.storage.StorageType; +import org.ovirt.engine.core.common.businessentities.storage.VolumeFormat; +import org.ovirt.engine.core.common.businessentities.storage.VolumeType; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.utils.EnumUtils; @@ -127,6 +130,82 @@ return vm; } + /** + * Convert the devices map and make a list of {@linkplain DiskImage} + * Mainly used to import the Hosted Engine Vm disks. + * + * @param vmStruct + * @return A List of Disk Images {@linkplain DiskImage} + */ + public static ArrayList<DiskImage> BuildDiskImagesFromDevices(Map<String, Object> vmStruct) { + ArrayList<DiskImage> diskImages = new ArrayList<>(); + Object[] devices = (Object[]) vmStruct.get("devices"); + if (devices != null) { + for (Object device : devices) { + Map <String, Object> deviceMap = (Map<String, Object>) device; + if (VdsProperties.Disk.equals(deviceMap.get(VdsProperties.Device))) { + DiskImage image = new DiskImage(); + image.setDiskAlias((String) deviceMap.get(VdsProperties.Alias)); + image.setSize(Long.parseLong((String) deviceMap.get("apparentsize"))); + image.setActualSize(Long.parseLong((String) deviceMap.get("truesize"))); + image.setId(Guid.newGuid()); + image.setvolumeFormat(VolumeFormat.valueOf(((String) deviceMap.get(VdsProperties.Format)).toUpperCase())); + image.setShareable(false); + image.setId(Guid.createGuidFromString((String) deviceMap.get(VdsProperties.DeviceId))); + image.setImageId(Guid.createGuidFromString((String) deviceMap.get(VdsProperties.VolumeId))); + // TODO not sure how to extract that info + image.setVolumeType(VolumeType.Preallocated); + switch ((String) deviceMap.get("iface")) { + case "virtio": + image.setDiskInterface(DiskInterface.VirtIO); + case "iscsi": + image.setDiskInterface(DiskInterface.VirtIO_SCSI); + case "ide": + image.setDiskInterface(DiskInterface.IDE); + } + diskImages.add(image); + } + } + } + return diskImages; + } + /** + * Convert the devices map and make a list of {@linkplain VmNetworkInterface} + * Mainly used to import the Hosted Engine Vm disks. + * + * @param vmStruct + * @return A List of VM network interfaces {@linkplain VmNetworkInterface} + */ + public static ArrayList<VmNetworkInterface> BuildVmNetworkInterfacesFromDevices(Map<String, Object> vmStruct) { + ArrayList<VmNetworkInterface> nics = new ArrayList<>(); + Object[] devices = (Object[]) vmStruct.get("devices"); + if (devices != null) { + for (Object device : devices) { + Map<String, Object> deviceMap = (Map<String, Object>) device; + if (VdsProperties.INTERFACE.equals(deviceMap.get(VdsProperties.Type))) { + VmNetworkInterface nic = new VmNetworkInterface(); + nic.setMacAddress((String) deviceMap.get(VdsProperties.MAC_ADDR)); + nic.setName((String) deviceMap.get(VdsProperties.Name)); + // FIXME we can't deduce the network profile by the network name. its many to many. + nic.setNetworkName((String) deviceMap.get(VdsProperties.NETWORK)); + nic.setType(VmInterfaceType.valueOf((String) deviceMap.get(VdsProperties.NIC_TYPE)).getValue()); + if (deviceMap.containsKey(VdsProperties.Model)) { + String model = (String) deviceMap.get(VdsProperties.Model); + for (VmInterfaceType type : VmInterfaceType.values()) { + if (model.equals(type.getInternalName())) { + nic.setType(type.getValue()); + break; + } + } + } + nics.add(nic); + } + + } + } + return nics; + } + private static VmStatic buildVmStaticDataFromExternalProvider(Map<String, Object> xmlRpcStruct) { if (!xmlRpcStruct.containsKey(VdsProperties.vm_guid) || !xmlRpcStruct.containsKey(VdsProperties.vm_name) || !xmlRpcStruct.containsKey(VdsProperties.mem_size_mb) -- To view, visit https://gerrit.ovirt.org/42295 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0ff2c440785cb91e3beef0530eda77324cc954d0 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Roy Golan <rgo...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches