mirror of https://github.com/apache/cloudstack.git
Summary: Direct template imaging for CLVM, bypass copy template to primary
Detail: Because of the way most other primary storage types work with cloudstack (i.e. backing stores) CLVM actually copies the template to a local logical volume on primary storage, then uses that. This causes all of your primary storage to be littered with a copy of every template used. Since we're not using these, dump the template direct to the newly created logical volume. This is faster as well since the template is sparse; we're not creating a fat template on primary storage and then copying that to a logical volume when we deploy from template. BUG-ID: CLOUDSTACK-508 Bugfix-for: 4.1 Signed-off-by: Marcus Sorensen <marcus@betterservers.com> 1353221260 -0700
This commit is contained in:
parent
bbb2a56acb
commit
88180fc139
|
|
@ -1190,11 +1190,13 @@ public class LibvirtComputingResource extends ServerResourceBase implements
|
||||||
disksize = dskch.getSize();
|
disksize = dskch.getSize();
|
||||||
|
|
||||||
if (cmd.getTemplateUrl() != null) {
|
if (cmd.getTemplateUrl() != null) {
|
||||||
|
if(primaryPool.getType() == StoragePoolType.CLVM) {
|
||||||
BaseVol = primaryPool.getPhysicalDisk(cmd.getTemplateUrl());
|
vol = templateToPrimaryDownload(cmd.getTemplateUrl(),primaryPool);
|
||||||
vol = _storagePoolMgr.createDiskFromTemplate(BaseVol, UUID
|
} else {
|
||||||
|
BaseVol = primaryPool.getPhysicalDisk(cmd.getTemplateUrl());
|
||||||
|
vol = _storagePoolMgr.createDiskFromTemplate(BaseVol, UUID
|
||||||
.randomUUID().toString(), primaryPool);
|
.randomUUID().toString(), primaryPool);
|
||||||
|
}
|
||||||
if (vol == null) {
|
if (vol == null) {
|
||||||
return new Answer(cmd, false,
|
return new Answer(cmd, false,
|
||||||
" Can't create storage volume on storage pool");
|
" Can't create storage volume on storage pool");
|
||||||
|
|
@ -1213,6 +1215,55 @@ public class LibvirtComputingResource extends ServerResourceBase implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is much like PrimaryStorageDownloadCommand, but keeping it separate
|
||||||
|
protected KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool) {
|
||||||
|
int index = templateUrl.lastIndexOf("/");
|
||||||
|
String mountpoint = templateUrl.substring(0, index);
|
||||||
|
String templateName = null;
|
||||||
|
if (index < templateUrl.length() - 1) {
|
||||||
|
templateName = templateUrl.substring(index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
KVMPhysicalDisk templateVol = null;
|
||||||
|
KVMStoragePool secondaryPool = null;
|
||||||
|
try {
|
||||||
|
secondaryPool = _storagePoolMgr.getStoragePoolByURI(mountpoint);
|
||||||
|
/* Get template vol */
|
||||||
|
if (templateName == null) {
|
||||||
|
secondaryPool.refresh();
|
||||||
|
List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
|
||||||
|
if (disks == null || disks.isEmpty()) {
|
||||||
|
s_logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (KVMPhysicalDisk disk : disks) {
|
||||||
|
if (disk.getName().endsWith("qcow2")) {
|
||||||
|
templateVol = disk;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (templateVol == null) {
|
||||||
|
s_logger.error("Failed to get template from pool: " + secondaryPool.getUuid());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
templateVol = secondaryPool.getPhysicalDisk(templateName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy volume to primary storage */
|
||||||
|
|
||||||
|
KVMPhysicalDisk primaryVol = _storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), primaryPool);
|
||||||
|
return primaryVol;
|
||||||
|
} catch (CloudRuntimeException e) {
|
||||||
|
s_logger.error("Failed to download template to primary storage",e);
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
if (secondaryPool != null) {
|
||||||
|
secondaryPool.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Answer execute(DestroyCommand cmd) {
|
public Answer execute(DestroyCommand cmd) {
|
||||||
VolumeTO vol = cmd.getVolume();
|
VolumeTO vol = cmd.getVolume();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -835,11 +835,23 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
|
if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) {
|
||||||
tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
|
if (pool.getPoolType() == StoragePoolType.CLVM) {
|
||||||
if (tmpltStoredOn == null) {
|
//prepareISOForCreate does what we need, which is to tell us where the template is
|
||||||
continue;
|
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
|
||||||
|
if (tmpltHostOn == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
HostVO secondaryStorageHost = _hostDao.findById(tmpltHostOn.getHostId());
|
||||||
|
String tmpltHostUrl = secondaryStorageHost.getStorageUrl();
|
||||||
|
String fullTmpltUrl = tmpltHostUrl + "/" + tmpltHostOn.getInstallPath();
|
||||||
|
cmd = new CreateCommand(dskCh, fullTmpltUrl, new StorageFilerTO(pool));
|
||||||
|
} else {
|
||||||
|
tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
|
||||||
|
if (tmpltStoredOn == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cmd = new CreateCommand(dskCh, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
|
||||||
}
|
}
|
||||||
cmd = new CreateCommand(dskCh, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
|
|
||||||
} else {
|
} else {
|
||||||
if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO == template.getFormat()) {
|
if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO == template.getFormat()) {
|
||||||
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
|
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
|
||||||
|
|
@ -3434,12 +3446,25 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (template != null && template.getFormat() != Storage.ImageFormat.ISO) {
|
if (template != null && template.getFormat() != Storage.ImageFormat.ISO) {
|
||||||
tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
|
if (pool.getPoolType() == StoragePoolType.CLVM) {
|
||||||
if (tmpltStoredOn == null) {
|
//prepareISOForCreate does what we need, which is to tell us where the template is
|
||||||
s_logger.debug("Cannot use this pool " + pool + " because we can't propagate template " + template);
|
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
|
||||||
return null;
|
if (tmpltHostOn == null) {
|
||||||
|
s_logger.debug("cannot find template " + template.getId() + " " + template.getName());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
HostVO secondaryStorageHost = _hostDao.findById(tmpltHostOn.getHostId());
|
||||||
|
String tmpltHostUrl = secondaryStorageHost.getStorageUrl();
|
||||||
|
String fullTmpltUrl = tmpltHostUrl + "/" + tmpltHostOn.getInstallPath();
|
||||||
|
cmd = new CreateCommand(diskProfile, fullTmpltUrl, new StorageFilerTO(pool));
|
||||||
|
} else {
|
||||||
|
tmpltStoredOn = _tmpltMgr.prepareTemplateForCreate(template, pool);
|
||||||
|
if (tmpltStoredOn == null) {
|
||||||
|
s_logger.debug("Cannot use this pool " + pool + " because we can't propagate template " + template);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
|
||||||
}
|
}
|
||||||
cmd = new CreateCommand(diskProfile, tmpltStoredOn.getLocalDownloadPath(), new StorageFilerTO(pool));
|
|
||||||
} else {
|
} else {
|
||||||
if (template != null && Storage.ImageFormat.ISO == template.getFormat()) {
|
if (template != null && Storage.ImageFormat.ISO == template.getFormat()) {
|
||||||
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
|
VMTemplateHostVO tmpltHostOn = _tmpltMgr.prepareISOForCreate(template, pool);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue