bug 8510: update resource count for template after the DB record is created. Decrement it if actual snapshot creation fails

This commit is contained in:
alena 2011-03-15 17:28:23 -07:00
parent 82f25426e7
commit 7b5d7806d2
1 changed files with 154 additions and 140 deletions

View File

@ -1339,7 +1339,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
true,
hyperType);
return _templateDao.persist(privateTemplate);
VMTemplateVO template = _templateDao.persist(privateTemplate);
// Increment the number of templates
if (template != null) {
_accountMgr.incrementResourceCount(accountId, ResourceType.template);
}
return template;
}
@Override @DB
@ -1360,151 +1366,159 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
HostVO secondaryStorageHost = null;
long zoneId;
Long accountId = null;
if (snapshotId != null) { // create template from snapshot
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
if( snapshot == null ) {
throw new CloudRuntimeException("Unable to find Snapshot for Id " + snapshotId);
}
zoneId = snapshot.getDataCenterId();
secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
if ( secondaryStorageHost == null ) {
throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
}
String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
try {
if (snapshotId != null) { // create template from snapshot
SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
if( snapshot == null ) {
throw new CloudRuntimeException("Unable to find Snapshot for Id " + snapshotId);
}
zoneId = snapshot.getDataCenterId();
secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
if ( secondaryStorageHost == null ) {
throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
}
String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
String name = command.getTemplateName();
String backupSnapshotUUID = snapshot.getBackupSnapshotId();
if (backupSnapshotUUID == null) {
throw new CloudRuntimeException("Unable to create private template from snapshot " + snapshotId + " due to there is no backupSnapshotUUID for this snapshot");
}
Long dcId = snapshot.getDataCenterId();
accountId = snapshot.getAccountId();
volumeId = snapshot.getVolumeId();
String name = command.getTemplateName();
String backupSnapshotUUID = snapshot.getBackupSnapshotId();
if (backupSnapshotUUID == null) {
throw new CloudRuntimeException("Unable to create private template from snapshot " + snapshotId + " due to there is no backupSnapshotUUID for this snapshot");
}
Long dcId = snapshot.getDataCenterId();
accountId = snapshot.getAccountId();
volumeId = snapshot.getVolumeId();
String origTemplateInstallPath = null;
List<StoragePoolVO> storagePools = _storagePoolDao.listByDataCenterId(zoneId);
if( storagePools == null || storagePools.size() == 0) {
throw new CloudRuntimeException("Unable to find storage pools in zone " + zoneId);
String origTemplateInstallPath = null;
List<StoragePoolVO> storagePools = _storagePoolDao.listByDataCenterId(zoneId);
if( storagePools == null || storagePools.size() == 0) {
throw new CloudRuntimeException("Unable to find storage pools in zone " + zoneId);
}
pool = storagePools.get(0);
if ( snapshot.getVersion() == "2.1" ) {
VolumeVO volume = _volsDao.findByIdIncludingRemoved(volumeId);
if ( volume == null ) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unable to find orignal volume:" + volumeId + ", try it later ");
}
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(volume.getTemplateId());
if ( template == null ) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unalbe to find orignal template :" + volume.getTemplateId() + ", try it later ");
}
Long origTemplateId = template.getId();
Long origTmpltAccountId = template.getAccountId();
if( ! _volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to volume:" + volumeId + " is being used, try it later ");
}
cmd = new UpgradeSnapshotCommand(null, secondaryStorageURL, dcId, accountId,
volumeId, origTemplateId, origTmpltAccountId, null, snapshot.getBackupSnapshotId(), snapshot.getName(), "2.1" );
if( ! _volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("Creating template failed due to volume:" + volumeId + " is being used, try it later ");
}
Answer answer = null;
try {
answer = _storageMgr.sendToPool(pool, cmd);
cmd = null;
} catch (StorageUnavailableException e) {
} finally {
_volsDao.unlockFromLockTable(volumeId.toString());
}
if ((answer != null) && answer.getResult()) {
_snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
} else {
throw new CloudRuntimeException("Unable to upgrade snapshot");
}
}
cmd = new CreatePrivateTemplateFromSnapshotCommand(pool.getUuid(),
secondaryStorageURL, dcId, accountId, snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
origTemplateInstallPath, templateId, name);
} else if (volumeId != null) {
VolumeVO volume = _volsDao.findById(volumeId);
if( volume == null ) {
throw new CloudRuntimeException("Unable to find volume for Id " + volumeId);
}
if( volume.getPoolId() == null ) {
_templateDao.remove(templateId);
throw new CloudRuntimeException("Volume " + volumeId + " is empty, can't create template on it");
}
String vmName = _storageMgr.getVmNameOnVolume(volume);
zoneId = volume.getDataCenterId();
secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
if ( secondaryStorageHost == null ) {
throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
}
String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
pool = _storagePoolDao.findById(volume.getPoolId());
cmd = new CreatePrivateTemplateFromVolumeCommand(secondaryStorageURL, templateId, volume.getAccountId(),
command.getTemplateName(), uniqueName, volume.getPath(), vmName);
} else {
throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
}
pool = storagePools.get(0);
if ( snapshot.getVersion() == "2.1" ) {
VolumeVO volume = _volsDao.findByIdIncludingRemoved(volumeId);
if ( volume == null ) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unable to find orignal volume:" + volumeId + ", try it later ");
}
VMTemplateVO template = _templateDao.findByIdIncludingRemoved(volume.getTemplateId());
if ( template == null ) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to unalbe to find orignal template :" + volume.getTemplateId() + ", try it later ");
}
Long origTemplateId = template.getId();
Long origTmpltAccountId = template.getAccountId();
if( ! _volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("failed to upgrade snapshot " + snapshotId + " due to volume:" + volumeId + " is being used, try it later ");
}
cmd = new UpgradeSnapshotCommand(null, secondaryStorageURL, dcId, accountId,
volumeId, origTemplateId, origTmpltAccountId, null, snapshot.getBackupSnapshotId(), snapshot.getName(), "2.1" );
if( ! _volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("Creating template failed due to volume:" + volumeId + " is being used, try it later ");
}
Answer answer = null;
try {
answer = _storageMgr.sendToPool(pool, cmd);
cmd = null;
} catch (StorageUnavailableException e) {
} finally {
_volsDao.unlockFromLockTable(volumeId.toString());
}
if ((answer != null) && answer.getResult()) {
_snapshotDao.updateSnapshotVersion(volumeId, "2.1", "2.2");
// FIXME: before sending the command, check if there's enough capacity
// on the storage server to create the template
// This can be sent to a KVM host too.
CreatePrivateTemplateAnswer answer = null;
if( ! _volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("Creating template failed due to volume:" + volumeId + " is being used, try it later ");
}
try {
answer = (CreatePrivateTemplateAnswer)_storageMgr.sendToPool(pool, cmd);
} catch (StorageUnavailableException e) {
} finally {
_volsDao.unlockFromLockTable(volumeId.toString());
}
if ((answer != null) && answer.getResult()) {
privateTemplate = _templateDao.findById(templateId);
String answerUniqueName = answer.getUniqueName();
if (answerUniqueName != null) {
privateTemplate.setUniqueName(answerUniqueName);
} else {
throw new CloudRuntimeException("Unable to upgrade snapshot");
privateTemplate.setUniqueName(uniqueName);
}
}
cmd = new CreatePrivateTemplateFromSnapshotCommand(pool.getUuid(),
secondaryStorageURL, dcId, accountId, snapshot.getVolumeId(), backupSnapshotUUID, snapshot.getName(),
origTemplateInstallPath, templateId, name);
} else if (volumeId != null) {
VolumeVO volume = _volsDao.findById(volumeId);
if( volume == null ) {
throw new CloudRuntimeException("Unable to find volume for Id " + volumeId);
}
if( volume.getPoolId() == null ) {
ImageFormat format = answer.getImageFormat();
if (format != null) {
privateTemplate.setFormat(format);
} else {
// This never occurs.
// Specify RAW format makes it unusable for snapshots.
privateTemplate.setFormat(ImageFormat.RAW);
}
_templateDao.update(templateId, privateTemplate);
// add template zone ref for this template
_templateDao.addTemplateToZone(privateTemplate, zoneId);
VMTemplateHostVO templateHostVO = new VMTemplateHostVO(secondaryStorageHost.getId(), templateId);
templateHostVO.setDownloadPercent(100);
templateHostVO.setDownloadState(Status.DOWNLOADED);
templateHostVO.setInstallPath(answer.getPath());
templateHostVO.setLastUpdated(new Date());
templateHostVO.setSize(answer.getVirtualSize());
templateHostVO.setPhysicalSize(answer.getphysicalSize());
_templateHostDao.persist(templateHostVO);
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), secondaryStorageHost.getDataCenterId(), privateTemplate.getId(), privateTemplate.getName(), null, null , templateHostVO.getSize());
_usageEventDao.persist(usageEvent);
}
} finally {
if (privateTemplate == null) {
Transaction txn = Transaction.currentTxn();
txn.start();
// Remove the template record
_templateDao.remove(templateId);
throw new CloudRuntimeException("Volume " + volumeId + " is empty, can't create template on it");
}
String vmName = _storageMgr.getVmNameOnVolume(volume);
zoneId = volume.getDataCenterId();
secondaryStorageHost = _storageMgr.getSecondaryStorageHost(zoneId);
if ( secondaryStorageHost == null ) {
throw new CloudRuntimeException("Can not find the secondary storage for zoneId " + zoneId);
}
String secondaryStorageURL = secondaryStorageHost.getStorageUrl();
pool = _storagePoolDao.findById(volume.getPoolId());
cmd = new CreatePrivateTemplateFromVolumeCommand(secondaryStorageURL, templateId, volume.getAccountId(),
command.getTemplateName(), uniqueName, volume.getPath(), vmName);
} else {
throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId");
}
// FIXME: before sending the command, check if there's enough capacity
// on the storage server to create the template
// This can be sent to a KVM host too.
CreatePrivateTemplateAnswer answer = null;
if( ! _volsDao.lockInLockTable(volumeId.toString(), 10)) {
throw new CloudRuntimeException("Creating template failed due to volume:" + volumeId + " is being used, try it later ");
}
try {
answer = (CreatePrivateTemplateAnswer)_storageMgr.sendToPool(pool, cmd);
} catch (StorageUnavailableException e) {
} finally {
_volsDao.unlockFromLockTable(volumeId.toString());
}
if ((answer != null) && answer.getResult()) {
privateTemplate = _templateDao.findById(templateId);
String answerUniqueName = answer.getUniqueName();
if (answerUniqueName != null) {
privateTemplate.setUniqueName(answerUniqueName);
} else {
privateTemplate.setUniqueName(uniqueName);
}
ImageFormat format = answer.getImageFormat();
if (format != null) {
privateTemplate.setFormat(format);
} else {
// This never occurs.
// Specify RAW format makes it unusable for snapshots.
privateTemplate.setFormat(ImageFormat.RAW);
}
_templateDao.update(templateId, privateTemplate);
// add template zone ref for this template
_templateDao.addTemplateToZone(privateTemplate, zoneId);
VMTemplateHostVO templateHostVO = new VMTemplateHostVO(secondaryStorageHost.getId(), templateId);
templateHostVO.setDownloadPercent(100);
templateHostVO.setDownloadState(Status.DOWNLOADED);
templateHostVO.setInstallPath(answer.getPath());
templateHostVO.setLastUpdated(new Date());
templateHostVO.setSize(answer.getVirtualSize());
templateHostVO.setPhysicalSize(answer.getphysicalSize());
_templateHostDao.persist(templateHostVO);
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), secondaryStorageHost.getDataCenterId(), privateTemplate.getId(), privateTemplate.getName(), null, null , templateHostVO.getSize());
_usageEventDao.persist(usageEvent);
// Increment the number of templates
_accountMgr.incrementResourceCount(accountId, ResourceType.template);
} else {
// Remove the template record
_templateDao.remove(templateId);
throw new CloudRuntimeException("Creating private Template failed due to " + answer.getDetails());
}
//decrement resource count
_accountMgr.decrementResourceCount(accountId, ResourceType.template);
txn.commit();
}
}
return privateTemplate;
}