use of com.cloud.legacymodel.storage.DiskOffering in project cosmic by MissionCriticalCloud.
the class VolumeOrchestrator method getTasks.
private List<VolumeTask> getTasks(final List<VolumeVO> vols, final Map<Volume, StoragePool> destVols, final VirtualMachineProfile vm) throws StorageUnavailableException {
final boolean recreate = RecreatableSystemVmEnabled.value();
final List<VolumeTask> tasks = new ArrayList<>();
for (final VolumeVO vol : vols) {
StoragePoolVO assignedPool = null;
if (destVols != null) {
final StoragePool pool = destVols.get(vol);
if (pool != null) {
assignedPool = this._storagePoolDao.findById(pool.getId());
}
}
if (assignedPool == null && recreate) {
assignedPool = this._storagePoolDao.findById(vol.getPoolId());
}
if (assignedPool != null) {
final Volume.State state = vol.getState();
if (state == Volume.State.Allocated || state == Volume.State.Creating) {
final VolumeTask task = new VolumeTask(VolumeTaskType.RECREATE, vol, null);
tasks.add(task);
} else {
if (vol.isRecreatable()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Volume " + vol + " will be recreated on storage pool " + assignedPool + " assigned by deploymentPlanner");
}
final VolumeTask task = new VolumeTask(VolumeTaskType.RECREATE, vol, null);
tasks.add(task);
} else {
if (assignedPool.getId() != vol.getPoolId()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Mismatch in storage pool " + assignedPool + " assigned by deploymentPlanner and the one associated with volume " + vol);
}
final DiskOffering diskOffering = this._entityMgr.findById(DiskOffering.class, vol.getDiskOfferingId());
if (diskOffering.getUseLocalStorage()) {
// Currently migration of local volume is not supported so bail out
if (s_logger.isDebugEnabled()) {
s_logger.debug("Local volume " + vol + " cannot be recreated on storagepool " + assignedPool + " assigned by deploymentPlanner");
}
throw new CloudRuntimeException("Local volume " + vol + " cannot be recreated on storagepool " + assignedPool + " assigned by deploymentPlanner");
} else {
// Check if storage migration is enabled in config
final Boolean isHAOperation = (Boolean) vm.getParameter(VirtualMachineProfile.Param.HaOperation);
Boolean storageMigrationEnabled = true;
if (isHAOperation != null && isHAOperation) {
storageMigrationEnabled = StorageHAMigrationEnabled.value();
} else {
storageMigrationEnabled = StorageMigrationEnabled.value();
}
// Always allow ISOs volumes to be "migrated"
if (storageMigrationEnabled || vol.getIsoId() != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Shared volume " + vol + " will be migrated on storage pool " + assignedPool + " assigned by deploymentPlanner");
}
final VolumeTask task = new VolumeTask(VolumeTaskType.MIGRATE, vol, assignedPool);
tasks.add(task);
} else {
throw new CloudRuntimeException("Cannot start VM on the hypervisor it was last running on, due to not enough capacity. Please try to start on" + " " + "another hypervisor in the same cluster, or migrate the volumes to another storage pool. Automatic Volume Migration is disabled, " + "so this is not handled automatically.");
}
}
} else {
final StoragePoolVO pool = this._storagePoolDao.findById(vol.getPoolId());
final VolumeTask task = new VolumeTask(VolumeTaskType.NOP, vol, pool);
tasks.add(task);
}
}
}
} else {
if (vol.getPoolId() == null) {
throw new StorageUnavailableException("Volume has no pool associate and also no storage pool assigned in DeployDestination, Unable to create " + vol, Volume.class, vol.getId());
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("No need to recreate the volume: " + vol + ", since it already has a pool assigned: " + vol.getPoolId() + ", adding disk to VM");
}
final StoragePoolVO pool = this._storagePoolDao.findById(vol.getPoolId());
final VolumeTask task = new VolumeTask(VolumeTaskType.NOP, vol, pool);
tasks.add(task);
}
}
return tasks;
}
use of com.cloud.legacymodel.storage.DiskOffering in project cosmic by MissionCriticalCloud.
the class VolumeOrchestrator method createVolumeFromSnapshot.
@DB
@Override
public VolumeInfo createVolumeFromSnapshot(final Volume volume, final Snapshot snapshot, final UserVm vm) throws StorageUnavailableException {
final Account account = this._entityMgr.findById(Account.class, volume.getAccountId());
final HashSet<StoragePool> poolsToAvoid = new HashSet<>();
StoragePool pool = null;
final Set<Long> podsToAvoid = new HashSet<>();
Pair<Pod, Long> pod = null;
final DiskOffering diskOffering = this._entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
final DataCenter dc = this._entityMgr.findById(DataCenter.class, volume.getDataCenterId());
final DiskProfile dskCh = new DiskProfile(volume, diskOffering, snapshot.getHypervisorType());
String msg = "There are no available storage pools to store the volume in";
if (vm != null) {
final Pod podofVM = this._entityMgr.findById(Pod.class, vm.getPodIdToDeployIn());
if (podofVM != null) {
pod = new Pair<>(podofVM, podofVM.getId());
}
}
if (vm != null && pod != null) {
// if VM is running use the hostId to find the clusterID. If it is stopped, refer the cluster where the ROOT volume of the VM exists.
Long hostId = null;
Long clusterId = null;
if (vm.getState() == State.Running) {
hostId = vm.getHostId();
if (hostId != null) {
final Host vmHost = this._entityMgr.findById(Host.class, hostId);
clusterId = vmHost.getClusterId();
}
} else {
final List<VolumeVO> rootVolumesOfVm = this._volsDao.findByInstanceAndType(vm.getId(), VolumeType.ROOT);
if (rootVolumesOfVm.size() != 1) {
throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state. Please contact Cloud Support.");
} else {
final VolumeVO rootVolumeOfVm = rootVolumesOfVm.get(0);
final StoragePoolVO rootDiskPool = this._storagePoolDao.findById(rootVolumeOfVm.getPoolId());
clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId());
}
}
// Determine what storage pool to store the volume in
while ((pool = findStoragePool(dskCh, dc, pod.first(), clusterId, hostId, vm, poolsToAvoid)) != null) {
break;
}
if (pool == null) {
// pool could not be found in the VM's pod/cluster.
if (s_logger.isDebugEnabled()) {
s_logger.debug("Could not find any storage pool to create Volume in the pod/cluster of the provided VM " + vm.getUuid());
}
final StringBuilder addDetails = new StringBuilder(msg);
addDetails.append(", Could not find any storage pool to create Volume in the pod/cluster of the VM ");
addDetails.append(vm.getUuid());
msg = addDetails.toString();
}
} else {
// Determine what pod to store the volume in
while ((pod = findPod(null, null, dc, account.getId(), podsToAvoid)) != null) {
podsToAvoid.add(pod.first().getId());
// Determine what storage pool to store the volume in
while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, null, poolsToAvoid)) != null) {
break;
}
if (pool != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Found a suitable pool for create volume: " + pool.getId());
}
break;
}
}
}
if (pool == null) {
s_logger.info(msg);
throw new StorageUnavailableException(msg, -1);
}
final VolumeInfo vol = this.volFactory.getVolume(volume.getId());
final DataStore store = this.dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
final DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
if (snapInfo == null && dataStoreRole == DataStoreRole.Image) {
// snapshot is not backed up to secondary, let's do that now.
snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
if (snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId());
}
// We need to copy the snapshot onto secondary.
final SnapshotStrategy snapshotStrategy = this._storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
snapshotStrategy.backupSnapshot(snapInfo);
// Attempt to grab it again.
snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
if (snapInfo == null) {
throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId() + " on secondary and could not create backup");
}
}
// don't try to perform a sync if the DataStoreRole of the snapshot is equal to DataStoreRole.Primary
if (!DataStoreRole.Primary.equals(dataStoreRole)) {
try {
// sync snapshot to region store if necessary
final DataStore snapStore = snapInfo.getDataStore();
final long snapVolId = snapInfo.getVolumeId();
this._snapshotSrv.syncVolumeSnapshotsToRegionStore(snapVolId, snapStore);
} catch (final Exception ex) {
// log but ignore the sync error to avoid any potential S3 down issue, it should be sync next time
s_logger.warn(ex.getMessage(), ex);
}
}
// create volume on primary from snapshot
final AsyncCallFuture<VolumeService.VolumeApiResult> future = this.volService.createVolumeFromSnapshot(vol, store, snapInfo);
try {
final VolumeService.VolumeApiResult result = future.get();
if (result.isFailed()) {
s_logger.debug("Failed to create volume from snapshot:" + result.getResult());
throw new CloudRuntimeException("Failed to create volume from snapshot:" + result.getResult());
}
return result.getVolume();
} catch (final InterruptedException e) {
s_logger.debug("Failed to create volume from snapshot", e);
throw new CloudRuntimeException("Failed to create volume from snapshot", e);
} catch (final ExecutionException e) {
s_logger.debug("Failed to create volume from snapshot", e);
throw new CloudRuntimeException("Failed to create volume from snapshot", e);
}
}
use of com.cloud.legacymodel.storage.DiskOffering in project cosmic by MissionCriticalCloud.
the class VolumeOrchestrator method createVolumeOnPrimaryStorage.
@Override
public VolumeInfo createVolumeOnPrimaryStorage(final VirtualMachine vm, final VolumeInfo volume, final HypervisorType rootDiskHyperType, final StoragePool storagePool) {
final VirtualMachineTemplate rootDiskTmplt = this._entityMgr.findById(VirtualMachineTemplate.class, vm.getTemplateId());
final DataCenter dcVO = this._entityMgr.findById(DataCenter.class, vm.getDataCenterId());
final Pod pod = this._entityMgr.findById(Pod.class, storagePool.getPodId());
final ServiceOffering svo = this._entityMgr.findById(ServiceOffering.class, vm.getServiceOfferingId());
final DiskOffering diskVO = this._entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId());
VolumeInfo vol = null;
if (volume.getState() == Volume.State.Allocated) {
vol = createVolume(storagePool, volume, rootDiskTmplt, dcVO, svo, diskVO, volume.getSize(), rootDiskHyperType);
} else if (volume.getState() == Volume.State.Uploaded) {
vol = copyVolume(storagePool, volume, vm, rootDiskTmplt, dcVO, pod, diskVO, rootDiskHyperType);
if (vol != null) {
// Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
this._resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, volume.getSize());
this._resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, volume.getSize());
}
}
if (vol == null) {
throw new CloudRuntimeException("Volume shouldn't be null " + volume.getId());
}
final VolumeVO volVO = this._volsDao.findById(vol.getId());
if (volVO.getFormat() == null) {
volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType));
}
this._volsDao.update(volVO.getId(), volVO);
return this.volFactory.getVolume(volVO.getId());
}
use of com.cloud.legacymodel.storage.DiskOffering in project cosmic by MissionCriticalCloud.
the class ConfigurationManagerImpl method updateDiskOffering.
@Override
@ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_EDIT, eventDescription = "updating disk offering")
public DiskOffering updateDiskOffering(final UpdateDiskOfferingCmd cmd) {
final Long diskOfferingId = cmd.getId();
final String name = cmd.getDiskOfferingName();
final String displayText = cmd.getDisplayText();
final Integer sortKey = cmd.getSortKey();
final Boolean displayDiskOffering = cmd.getDisplayOffering();
// Check if diskOffering exists
final DiskOffering diskOfferingHandle = _entityMgr.findById(DiskOffering.class, diskOfferingId);
if (diskOfferingHandle == null) {
throw new InvalidParameterValueException("Unable to find disk offering by id " + diskOfferingId);
}
Long userId = CallContext.current().getCallingUserId();
if (userId == null) {
userId = Long.valueOf(User.UID_SYSTEM);
}
final User user = _userDao.findById(userId);
if (user == null || user.getRemoved() != null) {
throw new InvalidParameterValueException("Unable to find active user by id " + userId);
}
final Account account = _accountDao.findById(user.getAccountId());
if (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
if (diskOfferingHandle.getDomainId() == null) {
throw new InvalidParameterValueException("Unable to update public disk offering by id " + userId + " because it is domain-admin");
}
if (!_domainDao.isChildDomain(account.getDomainId(), diskOfferingHandle.getDomainId())) {
throw new InvalidParameterValueException("Unable to update disk offering by another domain admin with id " + userId);
}
} else if (account.getType() != Account.ACCOUNT_TYPE_ADMIN) {
throw new InvalidParameterValueException("Unable to update disk offering by id " + userId + " because it is not root-admin or domain-admin");
}
final boolean updateNeeded = name != null || displayText != null || sortKey != null || displayDiskOffering != null;
if (!updateNeeded) {
return _diskOfferingDao.findById(diskOfferingId);
}
final DiskOfferingVO diskOffering = _diskOfferingDao.createForUpdate(diskOfferingId);
if (name != null) {
diskOffering.setName(name);
}
if (displayText != null) {
diskOffering.setDisplayText(displayText);
}
if (sortKey != null) {
diskOffering.setSortKey(sortKey);
}
if (displayDiskOffering != null) {
diskOffering.setDisplayOffering(displayDiskOffering);
}
if (_diskOfferingDao.update(diskOfferingId, diskOffering)) {
CallContext.current().setEventDetails("Disk offering id=" + diskOffering.getId());
return _diskOfferingDao.findById(diskOfferingId);
} else {
return null;
}
}
use of com.cloud.legacymodel.storage.DiskOffering in project cosmic by MissionCriticalCloud.
the class CreateDiskOfferingCmd method execute.
// ///////////////////////////////////////////////////
// ///////////// API Implementation///////////////////
// ///////////////////////////////////////////////////
@Override
public void execute() {
final DiskOffering offering = _configService.createDiskOffering(this);
if (offering != null) {
final DiskOfferingResponse response = _responseGenerator.createDiskOfferingResponse(offering);
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create disk offering");
}
}
Aggregations