server: Fix hardcoded max data volumes when VM has been created but not started before (#3494)

When VM is created but not started on any host, attaching a volume on it causes the maximum number of allowed volumes to be 6 (hardcoded).
This commit is contained in:
Nicolas Vazquez 2019-07-22 09:03:00 -03:00 committed by Rohit Yadav
parent e1fa270593
commit 38f97c65b8
4 changed files with 29 additions and 1 deletions

View File

@ -35,4 +35,6 @@ public interface HypervisorCapabilitiesDao extends GenericDao<HypervisorCapabili
Integer getMaxHostsPerCluster(HypervisorType hypervisorType, String hypervisorVersion);
Boolean isVmSnapshotEnabled(HypervisorType hypervisorType, String hypervisorVersion);
List<HypervisorType> getHypervisorsWithDefaultEntries();
}

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.hypervisor.dao;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
@ -106,4 +107,16 @@ public class HypervisorCapabilitiesDaoImpl extends GenericDaoBase<HypervisorCapa
HypervisorCapabilitiesVO result = getCapabilities(hypervisorType, hypervisorVersion);
return result.getVmSnapshotEnabled();
}
@Override
public List<HypervisorType> getHypervisorsWithDefaultEntries() {
SearchCriteria<HypervisorCapabilitiesVO> sc = HypervisorTypeAndVersionSearch.create();
sc.setParameters("hypervisorVersion", DEFAULT_VERSION);
List<HypervisorCapabilitiesVO> hypervisorCapabilitiesVOS = listBy(sc);
List<HypervisorType> hvs = new ArrayList<>();
for (HypervisorCapabilitiesVO capabilitiesVO : hypervisorCapabilitiesVOS) {
hvs.add(capabilitiesVO.getHypervisorType());
}
return hvs;
}
}

View File

@ -266,6 +266,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
private List<StoragePoolAllocator> _storagePoolAllocators;
private List<HypervisorType> supportingDefaultHV;
VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
static final ConfigKey<Long> VmJobCheckInterval = new ConfigKey<Long>("Advanced", Long.class, "vm.job.check.interval", "3000", "Interval in milliseconds to check if the job is complete", false);
@ -2857,7 +2859,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
}
}
verifyManagedStorage(volumeToAttachStoragePool.getId(), hostId);
if (volumeToAttachStoragePool != null) {
verifyManagedStorage(volumeToAttachStoragePool.getId(), hostId);
}
// volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before
DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null;
@ -3003,6 +3007,11 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
if (host != null) {
_hostDao.loadDetails(host);
maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(host.getHypervisorType(), host.getDetail("product_version"));
} else {
HypervisorType hypervisorType = vm.getHypervisorType();
if (hypervisorType != null && CollectionUtils.isNotEmpty(supportingDefaultHV) && supportingDefaultHV.contains(hypervisorType)) {
maxDataVolumesSupported = _hypervisorCapabilitiesDao.getMaxDataVolumesLimit(hypervisorType, "default");
}
}
if (maxDataVolumesSupported == null || maxDataVolumesSupported.intValue() <= 0) {
maxDataVolumesSupported = 6; // 6 data disks by default if nothing
@ -3050,6 +3059,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
public boolean configure(String name, Map<String, Object> params) {
String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.toString());
_maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000);
supportingDefaultHV = _hypervisorCapabilitiesDao.getHypervisorsWithDefaultEntries();
return true;
}

View File

@ -33,6 +33,7 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
@ -149,6 +150,8 @@ public class VolumeApiServiceImplTest {
private HostDao _hostDao;
@Mock
private StoragePoolTagsDao storagePoolTagsDao;
@Mock
private HypervisorCapabilitiesDao hypervisorCapabilitiesDao;
private DetachVolumeCmd detachCmd = new DetachVolumeCmd();
private Class<?> _detachCmdClass = detachCmd.getClass();