package org.ovirt.engine.core.bll.storage.domain; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.inject.Inject; import org.ovirt.engine.core.bll.QueriesCommandBase; import org.ovirt.engine.core.bll.storage.connection.StorageHelperDirector; import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.StorageDomainStatic; 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.VDSStatus; import org.ovirt.engine.core.common.queries.StorageDomainsAndStoragePoolIdQueryParameters; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.common.vdscommands.HSMGetStorageDomainInfoVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.StorageDomainDao; import org.ovirt.engine.core.dao.StoragePoolDao; import org.ovirt.engine.core.dao.VdsDao; public class GetStorageDomainsWithAttachedStoragePoolGuidQuery<P extends StorageDomainsAndStoragePoolIdQueryParameters> extends QueriesCommandBase<P> { private Guid vdsId; @Inject private VdsDao vdsDao; @Inject private StoragePoolDao storagePoolDao; @Inject private StorageDomainDao storageDomainDao; public GetStorageDomainsWithAttachedStoragePoolGuidQuery(P parameters) { super(parameters); } @Override protected void executeQueryCommand() { List<StorageDomainStatic> storageDomainsWithAttachedStoragePoolId = new ArrayList<>(); if ((getVdsForConnectStorage() != null) && isDataCenterValidForAttachedStorageDomains()) { storageDomainsWithAttachedStoragePoolId = filterAttachedStorageDomains(); } getQueryReturnValue().setReturnValue(storageDomainsWithAttachedStoragePoolId); } private Guid getVdsForConnectStorage() { vdsId = getParameters().getVdsId(); if (vdsId == null) { // Get a Host which is at UP state to connect to the Storage Domain. List<VDS> hosts = vdsDao.getAllForStoragePoolAndStatus(getParameters().getId(), VDSStatus.Up); if (!hosts.isEmpty()) { vdsId = hosts.get(new Random().nextInt(hosts.size())).getId(); log.info("vds id '{}' was chosen to fetch the Storage domain info", vdsId); } else { log.warn("There is no available vds in UP state to fetch the Storage domain info from VDSM"); } } return vdsId; } private boolean isDataCenterValidForAttachedStorageDomains() { if (getParameters().isCheckStoragePoolStatus()) { StoragePool storagePool = storagePoolDao.get(getParameters().getId()); if ((storagePool == null) || (storagePool.getStatus() != StoragePoolStatus.Up)) { log.info("The Data Center is not in UP status."); return false; } } return true; } protected List<StorageDomainStatic> filterAttachedStorageDomains() { List<StorageDomain> connectedStorageDomainsToVds = new ArrayList<>(); for (StorageDomain storageDomain : getParameters().getStorageDomainList()) { if (!connectStorageDomain(storageDomain)) { logErrorMessage(storageDomain); } else { connectedStorageDomainsToVds.add(storageDomain); } } // Some domains may have Hosted Engine VM running while importing them. // We want to avoid disconnecting before the import in that case, otherwise they'll crash List<Guid> heStorageDomainIds = storageDomainDao.getHostedEngineStorageDomainIds(); List<StorageDomainStatic> storageDomainsWithAttachedStoragePoolId = getAttachedStorageDomains(connectedStorageDomainsToVds); for (StorageDomain storageDomain : connectedStorageDomainsToVds) { if (heStorageDomainIds.contains(storageDomain.getId())) { log.info( "Skipping disconnect Storage Domain {} from VDS '{}' because Hosted Engine VM is running on it.", storageDomain.getName(), getVdsId() ); continue; } if (!disconnectStorageDomain(storageDomain)) { log.warn("Could not disconnect Storage Domain {} from VDS '{}'. ", storageDomain.getName(), getVdsId()); } } return storageDomainsWithAttachedStoragePoolId; } public Guid getVdsId() { return vdsId; } protected List<StorageDomainStatic> getAttachedStorageDomains(List<StorageDomain> storageDomains) { VDSReturnValue vdsReturnValue = null; List<StorageDomainStatic> storageDomainsWithAttachedStoragePoolId = new ArrayList<>(); // Go over the list of Storage Domains and try to get the Storage Domain info to check if it is attached to // another Storage Pool for (StorageDomain storageDomain : storageDomains) { try { vdsReturnValue = runVdsCommand(VDSCommandType.HSMGetStorageDomainInfo, new HSMGetStorageDomainInfoVDSCommandParameters(getVdsId(), storageDomain.getId())); } catch (RuntimeException e) { logErrorMessage(storageDomain); continue; } if (!vdsReturnValue.getSucceeded()) { logErrorMessage(storageDomain); continue; } Pair<StorageDomainStatic, Guid> domainFromIrs = (Pair<StorageDomainStatic, Guid>) vdsReturnValue.getReturnValue(); if (domainFromIrs.getSecond() != null) { storageDomainsWithAttachedStoragePoolId.add(domainFromIrs.getFirst()); } } return storageDomainsWithAttachedStoragePoolId; } protected boolean connectStorageDomain(StorageDomain storageDomain) { try { return StorageHelperDirector.getInstance() .getItem(storageDomain.getStorageType()) .connectStorageToDomainByVdsId(storageDomain, getVdsId()); } catch (RuntimeException e) { log.error("Exception while connecting a storage domain", e); return false; } } protected boolean disconnectStorageDomain(StorageDomain storageDomain) { try { return StorageHelperDirector.getInstance() .getItem(storageDomain.getStorageType()) .disconnectStorageFromDomainByVdsId(storageDomain, getVdsId()); } catch (RuntimeException e) { log.error("Exception while disconnecting a storage domain", e); return false; } } protected void logErrorMessage(StorageDomain storageDomain) { if (storageDomain != null) { log.error("Could not get Storage Domain info for Storage Domain (name:'{}', id:'{}') with VDS '{}'. ", storageDomain.getName(), storageDomain.getId(), getVdsId()); } else { log.error("Could not get Storage Domain info with VDS '{}'. ", getVdsId()); } } }