mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-6181: Merge of resize root feature (resize-root branch)
This commit is contained in:
parent
ae1d6a771b
commit
d638d04cbf
@ -121,6 +121,9 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
|
|||||||
@Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, description = "the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId")
|
@Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, description = "the arbitrary size for the DATADISK volume. Mutually exclusive with diskOfferingId")
|
||||||
private Long size;
|
private Long size;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.ROOT_DISK_SIZE, type = CommandType.LONG, description = "Optional field to resize root disk on deploy. Only applies to template-based deployments. Analogous to details[0].rootdisksize, which takes precedence over this parameter if both are provided")
|
||||||
|
private Long rootdisksize;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "an optional group for the virtual machine")
|
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "an optional group for the virtual machine")
|
||||||
private String group;
|
private String group;
|
||||||
|
|
||||||
@ -226,6 +229,9 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rootdisksize != null && !customparameterMap.containsKey("rootdisksize")) {
|
||||||
|
customparameterMap.put("rootdisksize", rootdisksize.toString());
|
||||||
|
}
|
||||||
return customparameterMap;
|
return customparameterMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
debian/rules
vendored
2
debian/rules
vendored
@ -35,7 +35,7 @@ build: build-indep
|
|||||||
build-indep: build-indep-stamp
|
build-indep: build-indep-stamp
|
||||||
|
|
||||||
build-indep-stamp: configure
|
build-indep-stamp: configure
|
||||||
mvn clean package -Pawsapi -DskipTests -Dsystemvm \
|
mvn -T C1.5 clean package -Pawsapi -DskipTests -Dsystemvm \
|
||||||
-Dcs.replace.properties=replace.properties.tmp \
|
-Dcs.replace.properties=replace.properties.tmp \
|
||||||
${ACS_BUILD_OPTS}
|
${ACS_BUILD_OPTS}
|
||||||
touch $@
|
touch $@
|
||||||
|
|||||||
@ -612,8 +612,14 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
|
assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
|
||||||
|
|
||||||
Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
|
Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
|
||||||
if (rootDisksize != null) {
|
if (rootDisksize != null ) {
|
||||||
size = (rootDisksize * 1024 * 1024 * 1024);
|
rootDisksize = rootDisksize * 1024 * 1024 * 1024;
|
||||||
|
if (rootDisksize > size) {
|
||||||
|
s_logger.debug("Using root disk size of " + rootDisksize + " for volume " + name);
|
||||||
|
size = rootDisksize;
|
||||||
|
} else {
|
||||||
|
s_logger.debug("Using root disk size of " + size + " for volume " + name + "since specified root disk size of " + rootDisksize + " is smaller than template");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
minIops = minIops != null ? minIops : offering.getMinIops();
|
minIops = minIops != null ? minIops : offering.getMinIops();
|
||||||
|
|||||||
@ -1827,6 +1827,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
boolean shrinkOk = cmd.getShrinkOk();
|
boolean shrinkOk = cmd.getShrinkOk();
|
||||||
StorageFilerTO spool = cmd.getPool();
|
StorageFilerTO spool = cmd.getPool();
|
||||||
|
|
||||||
|
if ( currentSize == newSize) {
|
||||||
|
// nothing to do
|
||||||
|
s_logger.info("No need to resize volume: current size " + currentSize + " is same as new size " + newSize);
|
||||||
|
return new ResizeVolumeAnswer(cmd, true, "success", currentSize);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
KVMStoragePool pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid());
|
KVMStoragePool pool = _storagePoolMgr.getStoragePool(spool.getType(), spool.getUuid());
|
||||||
KVMPhysicalDisk vol = pool.getPhysicalDisk(volid);
|
KVMPhysicalDisk vol = pool.getPhysicalDisk(volid);
|
||||||
|
|||||||
@ -302,17 +302,21 @@ public class KVMStoragePoolManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, KVMStoragePool destPool, int timeout) {
|
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, KVMStoragePool destPool, int timeout) {
|
||||||
|
return createDiskFromTemplate(template, name, destPool, template.getSize(), timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, KVMStoragePool destPool, long size, int timeout) {
|
||||||
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
|
StorageAdaptor adaptor = getStorageAdaptor(destPool.getType());
|
||||||
|
|
||||||
// LibvirtStorageAdaptor-specific statement
|
// LibvirtStorageAdaptor-specific statement
|
||||||
if (destPool.getType() == StoragePoolType.RBD) {
|
if (destPool.getType() == StoragePoolType.RBD) {
|
||||||
return adaptor.createDiskFromTemplate(template, name, PhysicalDiskFormat.RAW, template.getSize(), destPool, timeout);
|
return adaptor.createDiskFromTemplate(template, name, PhysicalDiskFormat.RAW, size, destPool, timeout);
|
||||||
} else if (destPool.getType() == StoragePoolType.CLVM) {
|
} else if (destPool.getType() == StoragePoolType.CLVM) {
|
||||||
return adaptor.createDiskFromTemplate(template, name, PhysicalDiskFormat.RAW, template.getSize(), destPool, timeout);
|
return adaptor.createDiskFromTemplate(template, name, PhysicalDiskFormat.RAW, size, destPool, timeout);
|
||||||
} else if (template.getFormat() == PhysicalDiskFormat.DIR) {
|
} else if (template.getFormat() == PhysicalDiskFormat.DIR) {
|
||||||
return adaptor.createDiskFromTemplate(template, name, PhysicalDiskFormat.DIR, template.getSize(), destPool, timeout);
|
return adaptor.createDiskFromTemplate(template, name, PhysicalDiskFormat.DIR, size, destPool, timeout);
|
||||||
} else {
|
} else {
|
||||||
return adaptor.createDiskFromTemplate(template, name, PhysicalDiskFormat.QCOW2, template.getSize(), destPool, timeout);
|
return adaptor.createDiskFromTemplate(template, name, PhysicalDiskFormat.QCOW2, size, destPool, timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -182,13 +182,14 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tmplVol == null) {
|
|
||||||
return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
|
tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tmplVol == null) {
|
||||||
|
return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy volume to primary storage */
|
/* Copy volume to primary storage */
|
||||||
s_logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat() );
|
s_logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat() );
|
||||||
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
|
KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
|
||||||
@ -196,6 +197,14 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
KVMPhysicalDisk primaryVol = null;
|
KVMPhysicalDisk primaryVol = null;
|
||||||
if (destData instanceof VolumeObjectTO) {
|
if (destData instanceof VolumeObjectTO) {
|
||||||
VolumeObjectTO volume = (VolumeObjectTO)destData;
|
VolumeObjectTO volume = (VolumeObjectTO)destData;
|
||||||
|
// pass along volume's target size if it's bigger than template's size, for storage types that copy template rather than cloning on deploy
|
||||||
|
if (volume.getSize() != null && volume.getSize() > tmplVol.getVirtualSize()) {
|
||||||
|
s_logger.debug("Using configured size of " + volume.getSize());
|
||||||
|
tmplVol.setSize(volume.getSize());
|
||||||
|
tmplVol.setVirtualSize(volume.getSize());
|
||||||
|
} else {
|
||||||
|
s_logger.debug("Using template's size of " + tmplVol.getVirtualSize());
|
||||||
|
}
|
||||||
primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, volume.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
|
primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, volume.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
|
||||||
} else if (destData instanceof TemplateObjectTO) {
|
} else if (destData instanceof TemplateObjectTO) {
|
||||||
TemplateObjectTO destTempl = (TemplateObjectTO)destData;
|
TemplateObjectTO destTempl = (TemplateObjectTO)destData;
|
||||||
@ -239,7 +248,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this is much like PrimaryStorageDownloadCommand, but keeping it separate. copies template direct to root disk
|
// this is much like PrimaryStorageDownloadCommand, but keeping it separate. copies template direct to root disk
|
||||||
private KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool, String volUuid, int timeout) {
|
private KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool, String volUuid, Long size, int timeout) {
|
||||||
int index = templateUrl.lastIndexOf("/");
|
int index = templateUrl.lastIndexOf("/");
|
||||||
String mountpoint = templateUrl.substring(0, index);
|
String mountpoint = templateUrl.substring(0, index);
|
||||||
String templateName = null;
|
String templateName = null;
|
||||||
@ -275,6 +284,14 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
/* Copy volume to primary storage */
|
/* Copy volume to primary storage */
|
||||||
|
|
||||||
|
if (size > templateVol.getSize()) {
|
||||||
|
s_logger.debug("Overriding provided template's size with new size " + size);
|
||||||
|
templateVol.setSize(size);
|
||||||
|
templateVol.setVirtualSize(size);
|
||||||
|
} else {
|
||||||
|
s_logger.debug("Using templates disk size of " + templateVol.getVirtualSize() + "since size passed was " + size);
|
||||||
|
}
|
||||||
|
|
||||||
KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, timeout);
|
KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, timeout);
|
||||||
return primaryVol;
|
return primaryVol;
|
||||||
} catch (CloudRuntimeException e) {
|
} catch (CloudRuntimeException e) {
|
||||||
@ -306,14 +323,14 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
if (primaryPool.getType() == StoragePoolType.CLVM) {
|
if (primaryPool.getType() == StoragePoolType.CLVM) {
|
||||||
templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
|
templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
|
||||||
vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), cmd.getWaitInMillSeconds());
|
vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), volume.getSize(), cmd.getWaitInMillSeconds());
|
||||||
} else {
|
} else {
|
||||||
if (templatePath.contains("/mnt")) {
|
if (templatePath.contains("/mnt")) {
|
||||||
//upgrade issue, if the path contains path, need to extract the volume uuid from path
|
//upgrade issue, if the path contains path, need to extract the volume uuid from path
|
||||||
templatePath = templatePath.substring(templatePath.lastIndexOf(File.separator) + 1);
|
templatePath = templatePath.substring(templatePath.lastIndexOf(File.separator) + 1);
|
||||||
}
|
}
|
||||||
BaseVol = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath);
|
BaseVol = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath);
|
||||||
vol = storagePoolMgr.createDiskFromTemplate(BaseVol, volume.getUuid(), BaseVol.getPool(), cmd.getWaitInMillSeconds());
|
vol = storagePoolMgr.createDiskFromTemplate(BaseVol, volume.getUuid(), BaseVol.getPool(), volume.getSize(), cmd.getWaitInMillSeconds());
|
||||||
}
|
}
|
||||||
if (vol == null) {
|
if (vol == null) {
|
||||||
return new CopyCmdAnswer(" Can't create storage volume on storage pool");
|
return new CopyCmdAnswer(" Can't create storage volume on storage pool");
|
||||||
|
|||||||
@ -823,11 +823,21 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
|||||||
} else if (format == PhysicalDiskFormat.QCOW2) {
|
} else if (format == PhysicalDiskFormat.QCOW2) {
|
||||||
QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
|
QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
|
||||||
QemuImgFile destFile = new QemuImgFile(disk.getPath());
|
QemuImgFile destFile = new QemuImgFile(disk.getPath());
|
||||||
|
if (size > template.getVirtualSize()) {
|
||||||
|
destFile.setSize(size);
|
||||||
|
} else {
|
||||||
|
destFile.setSize(template.getVirtualSize());
|
||||||
|
}
|
||||||
QemuImg qemu = new QemuImg(timeout);
|
QemuImg qemu = new QemuImg(timeout);
|
||||||
qemu.create(destFile, backingFile);
|
qemu.create(destFile, backingFile);
|
||||||
} else if (format == PhysicalDiskFormat.RAW) {
|
} else if (format == PhysicalDiskFormat.RAW) {
|
||||||
QemuImgFile sourceFile = new QemuImgFile(template.getPath(), template.getFormat());
|
QemuImgFile sourceFile = new QemuImgFile(template.getPath(), template.getFormat());
|
||||||
QemuImgFile destFile = new QemuImgFile(disk.getPath(), PhysicalDiskFormat.RAW);
|
QemuImgFile destFile = new QemuImgFile(disk.getPath(), PhysicalDiskFormat.RAW);
|
||||||
|
if (size > template.getVirtualSize()) {
|
||||||
|
destFile.setSize(size);
|
||||||
|
} else {
|
||||||
|
destFile.setSize(template.getVirtualSize());
|
||||||
|
}
|
||||||
QemuImg qemu = new QemuImg(timeout);
|
QemuImg qemu = new QemuImg(timeout);
|
||||||
qemu.convert(sourceFile, destFile);
|
qemu.convert(sourceFile, destFile);
|
||||||
}
|
}
|
||||||
@ -835,8 +845,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
|||||||
format = PhysicalDiskFormat.RAW;
|
format = PhysicalDiskFormat.RAW;
|
||||||
disk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + newUuid, newUuid, destPool);
|
disk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + newUuid, newUuid, destPool);
|
||||||
disk.setFormat(format);
|
disk.setFormat(format);
|
||||||
disk.setSize(template.getVirtualSize());
|
if (size > template.getVirtualSize()) {
|
||||||
disk.setVirtualSize(disk.getSize());
|
disk.setSize(size);
|
||||||
|
disk.setVirtualSize(size);
|
||||||
|
} else {
|
||||||
|
// leave these as they were if size isn't applicable
|
||||||
|
disk.setSize(template.getVirtualSize());
|
||||||
|
disk.setVirtualSize(disk.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
QemuImg qemu = new QemuImg(timeout);
|
QemuImg qemu = new QemuImg(timeout);
|
||||||
QemuImgFile srcFile;
|
QemuImgFile srcFile;
|
||||||
@ -844,6 +860,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
|||||||
new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(),
|
new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(),
|
||||||
destPool.getAuthSecret(), disk.getPath()));
|
destPool.getAuthSecret(), disk.getPath()));
|
||||||
destFile.setFormat(format);
|
destFile.setFormat(format);
|
||||||
|
if (size > template.getVirtualSize()) {
|
||||||
|
destFile.setSize(size);
|
||||||
|
} else {
|
||||||
|
destFile.setSize(template.getVirtualSize());
|
||||||
|
}
|
||||||
|
|
||||||
if (srcPool.getType() != StoragePoolType.RBD) {
|
if (srcPool.getType() != StoragePoolType.RBD) {
|
||||||
srcFile = new QemuImgFile(template.getPath(), template.getFormat());
|
srcFile = new QemuImgFile(template.getPath(), template.getFormat());
|
||||||
@ -877,9 +898,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
|||||||
if (srcImage.isOldFormat()) {
|
if (srcImage.isOldFormat()) {
|
||||||
/* The source image is RBD format 1, we have to do a regular copy */
|
/* The source image is RBD format 1, we have to do a regular copy */
|
||||||
s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() +
|
s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() +
|
||||||
" is RBD format 1. We have to perform a regular copy (" + template.getVirtualSize() + " bytes)");
|
" is RBD format 1. We have to perform a regular copy (" + disk.getVirtualSize() + " bytes)");
|
||||||
|
|
||||||
rbd.create(disk.getName(), template.getVirtualSize(), rbdFeatures, rbdOrder);
|
rbd.create(disk.getName(), disk.getVirtualSize(), rbdFeatures, rbdOrder);
|
||||||
RbdImage destImage = rbd.open(disk.getName());
|
RbdImage destImage = rbd.open(disk.getName());
|
||||||
|
|
||||||
s_logger.debug("Starting to copy " + srcImage.getName() + " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir());
|
s_logger.debug("Starting to copy " + srcImage.getName() + " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir());
|
||||||
@ -923,7 +944,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
|
|||||||
|
|
||||||
s_logger.debug("Creating " + disk.getName() + " on the destination cluster " + rDest.confGet("mon_host") + " in pool " +
|
s_logger.debug("Creating " + disk.getName() + " on the destination cluster " + rDest.confGet("mon_host") + " in pool " +
|
||||||
destPool.getSourceDir());
|
destPool.getSourceDir());
|
||||||
dRbd.create(disk.getName(), template.getVirtualSize(), rbdFeatures, rbdOrder);
|
dRbd.create(disk.getName(), disk.getVirtualSize(), rbdFeatures, rbdOrder);
|
||||||
|
|
||||||
RbdImage srcImage = sRbd.open(template.getName());
|
RbdImage srcImage = sRbd.open(template.getName());
|
||||||
RbdImage destImage = dRbd.open(disk.getName());
|
RbdImage destImage = dRbd.open(disk.getName());
|
||||||
|
|||||||
@ -111,10 +111,12 @@ public class QemuImg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.add(file.getFileName());
|
s.add(file.getFileName());
|
||||||
|
if (file.getSize() != 0L) {
|
||||||
if (backingFile == null) {
|
|
||||||
s.add(Long.toString(file.getSize()));
|
s.add(Long.toString(file.getSize()));
|
||||||
|
} else if (backingFile == null) {
|
||||||
|
throw new QemuImgException("No size was passed, and no backing file was passed");
|
||||||
}
|
}
|
||||||
|
|
||||||
String result = s.execute();
|
String result = s.execute();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
throw new QemuImgException(result);
|
throw new QemuImgException(result);
|
||||||
@ -206,6 +208,10 @@ public class QemuImg {
|
|||||||
if (result != null) {
|
if (result != null) {
|
||||||
throw new QemuImgException(result);
|
throw new QemuImgException(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (srcFile.getSize() < destFile.getSize()) {
|
||||||
|
this.resize(destFile, destFile.getSize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -701,27 +701,17 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
|
|
||||||
newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId());
|
newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId());
|
||||||
|
|
||||||
/*
|
/* Only works for KVM/Xen/VMware for now, and volumes with 'None' since they're just allocated in db */
|
||||||
* Volumes with no hypervisor have never been assigned, and can be
|
if (_volsDao.getHypervisorType(volume.getId()) != HypervisorType.KVM
|
||||||
* resized by recreating. perhaps in the future we can just update the
|
&& _volsDao.getHypervisorType(volume.getId()) != HypervisorType.XenServer
|
||||||
* db entry for the volume
|
&& _volsDao.getHypervisorType(volume.getId()) != HypervisorType.VMware
|
||||||
*/
|
&& _volsDao.getHypervisorType(volume.getId()) != HypervisorType.None) {
|
||||||
if (_volsDao.getHypervisorType(volume.getId()) == HypervisorType.None) {
|
throw new InvalidParameterValueException("Cloudstack currently only supports volumes marked as KVM, VMware, XenServer hypervisor for resize");
|
||||||
throw new InvalidParameterValueException("Can't resize a volume that has never been attached, not sure which hypervisor type. Recreate volume to resize.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only works for KVM/Xen for now */
|
if (volume.getState() != Volume.State.Ready && volume.getState() != Volume.State.Allocated) {
|
||||||
if (_volsDao.getHypervisorType(volume.getId()) != HypervisorType.KVM && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.XenServer
|
throw new InvalidParameterValueException("Volume should be in ready or allocated state before attempting a resize. "
|
||||||
&& _volsDao.getHypervisorType(volume.getId()) != HypervisorType.VMware) {
|
+ "Volume " + volume.getUuid() + " state is:" + volume.getState());
|
||||||
throw new InvalidParameterValueException("Cloudstack currently only supports volumes marked as KVM or XenServer hypervisor for resize");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (volume.getState() != Volume.State.Ready) {
|
|
||||||
throw new InvalidParameterValueException("Volume should be in ready state before attempting a resize");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!volume.getVolumeType().equals(Volume.Type.DATADISK)) {
|
|
||||||
throw new InvalidParameterValueException("Can only resize DATA volumes");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -729,7 +719,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
* required, get the correct size value
|
* required, get the correct size value
|
||||||
*/
|
*/
|
||||||
if (newDiskOffering == null) {
|
if (newDiskOffering == null) {
|
||||||
if (diskOffering.isCustomized()) {
|
if (diskOffering.isCustomized() || volume.getVolumeType().equals(Volume.Type.ROOT)) {
|
||||||
newSize = cmd.getSize();
|
newSize = cmd.getSize();
|
||||||
|
|
||||||
if (newSize == null) {
|
if (newSize == null) {
|
||||||
@ -741,6 +731,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
throw new InvalidParameterValueException("current offering" + volume.getDiskOfferingId() + " cannot be resized, need to specify a disk offering");
|
throw new InvalidParameterValueException("current offering" + volume.getDiskOfferingId() + " cannot be resized, need to specify a disk offering");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (!volume.getVolumeType().equals(Volume.Type.DATADISK)) {
|
||||||
|
throw new InvalidParameterValueException("Can only resize Data volumes via new disk offering");
|
||||||
|
}
|
||||||
|
|
||||||
if (newDiskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) {
|
if (newDiskOffering.getRemoved() != null || !DiskOfferingVO.Type.Disk.equals(newDiskOffering.getType())) {
|
||||||
throw new InvalidParameterValueException("Disk offering ID is missing or invalid");
|
throw new InvalidParameterValueException("Disk offering ID is missing or invalid");
|
||||||
@ -784,8 +777,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
/* does the caller have the authority to act on this volume? */
|
/* does the caller have the authority to act on this volume? */
|
||||||
_accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
|
_accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, volume);
|
||||||
|
|
||||||
UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
|
|
||||||
|
|
||||||
long currentSize = volume.getSize();
|
long currentSize = volume.getSize();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -805,6 +796,20 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
- currentSize));
|
- currentSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If this volume has never been beyond allocated state, short circuit everything and simply update the database */
|
||||||
|
if (volume.getState() == Volume.State.Allocated) {
|
||||||
|
s_logger.debug("Volume is allocated, but never created, simply updating database with new size");
|
||||||
|
volume.setSize(newSize);
|
||||||
|
if (newDiskOffering != null) {
|
||||||
|
volume.setDiskOfferingId(cmd.getNewDiskOfferingId());
|
||||||
|
}
|
||||||
|
_volsDao.update(volume.getId(), volume);
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
|
||||||
|
|
||||||
|
|
||||||
if (userVm != null) {
|
if (userVm != null) {
|
||||||
// serialize VM operation
|
// serialize VM operation
|
||||||
AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||||
|
|||||||
@ -2835,11 +2835,31 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
vm.setIsoId(template.getId());
|
vm.setIsoId(template.getId());
|
||||||
}
|
}
|
||||||
Long rootDiskSize = null;
|
Long rootDiskSize = null;
|
||||||
|
// custom root disk size, resizes base template to larger size
|
||||||
if (customParameters.containsKey("rootdisksize")) {
|
if (customParameters.containsKey("rootdisksize")) {
|
||||||
if (NumbersUtil.parseLong(customParameters.get("rootdisksize"), -1) <= 0) {
|
if (NumbersUtil.parseLong(customParameters.get("rootdisksize"), -1) <= 0) {
|
||||||
throw new InvalidParameterValueException("rootdisk size should be a non zero number.");
|
throw new InvalidParameterValueException("rootdisk size should be a non zero number.");
|
||||||
}
|
}
|
||||||
rootDiskSize = Long.parseLong(customParameters.get("rootDisksize"));
|
rootDiskSize = Long.parseLong(customParameters.get("rootdisksize"));
|
||||||
|
|
||||||
|
// only KVM supports rootdisksize override
|
||||||
|
if (hypervisor != HypervisorType.KVM) {
|
||||||
|
throw new InvalidParameterValueException("Hypervisor " + hypervisor + " does not support rootdisksize override");
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotdisksize must be larger than template
|
||||||
|
VMTemplateVO templateVO = _templateDao.findById(template.getId());
|
||||||
|
if (templateVO == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to look up template by id " + template.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((rootDiskSize << 30) < templateVO.getSize()) {
|
||||||
|
throw new InvalidParameterValueException("unsupported: rootdisksize override is smaller than template size " + templateVO.getSize());
|
||||||
|
} else {
|
||||||
|
s_logger.debug("rootdisksize of " + (rootDiskSize << 30) + " was larger than template size of " + templateVO.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
s_logger.debug("found root disk size of " + rootDiskSize);
|
||||||
customParameters.remove("rootdisksize");
|
customParameters.remove("rootdisksize");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
263
test/integration/smoke/test_deploy_vm_root_resize.py
Normal file
263
test/integration/smoke/test_deploy_vm_root_resize.py
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
#Test from the Marvin - Testing in Python wiki
|
||||||
|
|
||||||
|
#All tests inherit from cloudstackTestCase
|
||||||
|
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||||
|
|
||||||
|
#Import Integration Libraries
|
||||||
|
|
||||||
|
#base - contains all resources as entities and defines create, delete, list operations on them
|
||||||
|
from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering
|
||||||
|
|
||||||
|
#utils - utility classes for common cleanup, external library wrappers etc
|
||||||
|
from marvin.integration.lib.utils import cleanup_resources
|
||||||
|
|
||||||
|
#common - commonly used methods for all tests are listed here
|
||||||
|
from marvin.integration.lib.common import get_zone, get_domain, get_template, list_volumes
|
||||||
|
|
||||||
|
from nose.plugins.attrib import attr
|
||||||
|
|
||||||
|
class TestData(object):
|
||||||
|
"""Test data object that is required to create resources
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self.testdata = {
|
||||||
|
#data to create an account
|
||||||
|
"account": {
|
||||||
|
"email": "test@test.com",
|
||||||
|
"firstname": "Test",
|
||||||
|
"lastname": "User",
|
||||||
|
"username": "test",
|
||||||
|
"password": "password",
|
||||||
|
},
|
||||||
|
#data reqd for virtual machine creation
|
||||||
|
"virtual_machine" : {
|
||||||
|
"name" : "testvm",
|
||||||
|
"displayname" : "Test VM",
|
||||||
|
},
|
||||||
|
#small service offering
|
||||||
|
"service_offering": {
|
||||||
|
"small": {
|
||||||
|
"name": "Small Instance",
|
||||||
|
"displaytext": "Small Instance",
|
||||||
|
"cpunumber": 1,
|
||||||
|
"cpuspeed": 100,
|
||||||
|
"memory": 256,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ostype": 'CentOS 5.3 (64-bit)',
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestDeployVM(cloudstackTestCase):
|
||||||
|
"""Test deploy a VM into a user account
|
||||||
|
"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.testdata = TestData().testdata
|
||||||
|
self.apiclient = self.testClient.getApiClient()
|
||||||
|
|
||||||
|
# Get Zone, Domain and Default Built-in template
|
||||||
|
self.domain = get_domain(self.apiclient, self.testdata)
|
||||||
|
self.zone = get_zone(self.apiclient, self.testdata)
|
||||||
|
self.testdata["mode"] = self.zone.networktype
|
||||||
|
self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"])
|
||||||
|
# for testing with specific template
|
||||||
|
# self.template = get_template(self.apiclient, self.zone.id, self.testdata["ostype"], templatetype='USER', services = {"template":'31f52a4d-5681-43f7-8651-ad4aaf823618'})
|
||||||
|
|
||||||
|
|
||||||
|
#create a user account
|
||||||
|
self.account = Account.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.testdata["account"],
|
||||||
|
domainid=self.domain.id
|
||||||
|
)
|
||||||
|
#create a service offering
|
||||||
|
self.service_offering = ServiceOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.testdata["service_offering"]["small"]
|
||||||
|
)
|
||||||
|
#build cleanup list
|
||||||
|
self.cleanup = [
|
||||||
|
self.service_offering,
|
||||||
|
self.account
|
||||||
|
]
|
||||||
|
|
||||||
|
@attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
|
||||||
|
def test_00_deploy_vm_root_resize(self):
|
||||||
|
"""Test deploy virtual machine with root resize
|
||||||
|
|
||||||
|
# Validate the following:
|
||||||
|
# 1. listVirtualMachines returns accurate information
|
||||||
|
# 2. root disk has new size per listVolumes
|
||||||
|
# 3. Rejects non-supported hypervisor types
|
||||||
|
"""
|
||||||
|
if(self.apiclient.hypervisor == 'kvm'):
|
||||||
|
newrootsize = (self.template.size >> 30) + 2
|
||||||
|
self.virtual_machine = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.testdata["virtual_machine"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
zoneid=self.zone.id,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.service_offering.id,
|
||||||
|
templateid=self.template.id,
|
||||||
|
rootdisksize=newrootsize
|
||||||
|
)
|
||||||
|
|
||||||
|
list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id)
|
||||||
|
|
||||||
|
self.debug(
|
||||||
|
"Verify listVirtualMachines response for virtual machine: %s"\
|
||||||
|
% self.virtual_machine.id
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
isinstance(list_vms, list),
|
||||||
|
True,
|
||||||
|
"List VM response was not a valid list"
|
||||||
|
)
|
||||||
|
self.assertNotEqual(
|
||||||
|
len(list_vms),
|
||||||
|
0,
|
||||||
|
"List VM response was empty"
|
||||||
|
)
|
||||||
|
|
||||||
|
vm = list_vms[0]
|
||||||
|
self.assertEqual(
|
||||||
|
vm.id,
|
||||||
|
self.virtual_machine.id,
|
||||||
|
"Virtual Machine ids do not match"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
vm.name,
|
||||||
|
self.virtual_machine.name,
|
||||||
|
"Virtual Machine names do not match"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
vm.state,
|
||||||
|
"Running",
|
||||||
|
msg="VM is not in Running state"
|
||||||
|
)
|
||||||
|
|
||||||
|
# get root vol from created vm, verify it is correct size
|
||||||
|
list_volume_response = list_volumes(
|
||||||
|
self.apiclient,
|
||||||
|
virtualmachineid=self.virtual_machine.id,
|
||||||
|
type='ROOT',
|
||||||
|
listall=True
|
||||||
|
)
|
||||||
|
|
||||||
|
rootvolume = list_volume_response[0]
|
||||||
|
success = False
|
||||||
|
if rootvolume is not None and rootvolume.size == (newrootsize << 30):
|
||||||
|
success = True
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
success,
|
||||||
|
True,
|
||||||
|
"Check if the root volume resized appropriately"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.debug("hypervisor %s unsupported for test 00, verifying it errors properly" % self.apiclient.hypervisor)
|
||||||
|
|
||||||
|
newrootsize = (self.template.size >> 30) + 2
|
||||||
|
success = False
|
||||||
|
try:
|
||||||
|
self.virtual_machine = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.testdata["virtual_machine"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
zoneid=self.zone.id,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.service_offering.id,
|
||||||
|
templateid=self.template.id,
|
||||||
|
rootdisksize=newrootsize
|
||||||
|
)
|
||||||
|
except Exception as ex:
|
||||||
|
if "Hypervisor XenServer does not support rootdisksize override" in str(ex):
|
||||||
|
success = True
|
||||||
|
else:
|
||||||
|
self.debug("virtual machine create did not fail appropriately. Error was actually : " + str(ex));
|
||||||
|
|
||||||
|
self.assertEqual(success, True, "Check if unsupported hypervisor %s fails appropriately" % self.apiclient.hypervisor)
|
||||||
|
|
||||||
|
@attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
|
||||||
|
def test_01_deploy_vm_root_resize(self):
|
||||||
|
"""Test proper failure to deploy virtual machine with rootdisksize of 0
|
||||||
|
"""
|
||||||
|
if (self.apiclient.hypervisor == 'kvm'):
|
||||||
|
newrootsize = 0
|
||||||
|
success = False
|
||||||
|
try:
|
||||||
|
self.virtual_machine = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.testdata["virtual_machine"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
zoneid=self.zone.id,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.service_offering.id,
|
||||||
|
templateid=self.template.id,
|
||||||
|
rootdisksize=newrootsize
|
||||||
|
)
|
||||||
|
except Exception as ex:
|
||||||
|
if "rootdisk size should be a non zero number" in str(ex):
|
||||||
|
success = True
|
||||||
|
else:
|
||||||
|
self.debug("virtual machine create did not fail appropriately. Error was actually : " + str(ex));
|
||||||
|
|
||||||
|
self.assertEqual(success, True, "Check if passing 0 as rootdisksize fails appropriately")
|
||||||
|
else:
|
||||||
|
self.debug("test 01 does not support hypervisor type " + self.apiclient.hypervisor);
|
||||||
|
|
||||||
|
@attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
|
||||||
|
def test_02_deploy_vm_root_resize(self):
|
||||||
|
"""Test proper failure to deploy virtual machine with rootdisksize less than template size
|
||||||
|
"""
|
||||||
|
if (self.apiclient.hypervisor == 'kvm'):
|
||||||
|
newrootsize = (self.template.size >> 30) - 1
|
||||||
|
|
||||||
|
self.assertEqual(newrootsize > 0, True, "Provided template is less than 1G in size, cannot run test")
|
||||||
|
|
||||||
|
success = False
|
||||||
|
try:
|
||||||
|
self.virtual_machine = VirtualMachine.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.testdata["virtual_machine"],
|
||||||
|
accountid=self.account.name,
|
||||||
|
zoneid=self.zone.id,
|
||||||
|
domainid=self.account.domainid,
|
||||||
|
serviceofferingid=self.service_offering.id,
|
||||||
|
templateid=self.template.id,
|
||||||
|
rootdisksize=newrootsize
|
||||||
|
)
|
||||||
|
except Exception as ex:
|
||||||
|
if "rootdisksize override is smaller than template size" in str(ex):
|
||||||
|
success = True
|
||||||
|
else:
|
||||||
|
self.debug("virtual machine create did not fail appropriately. Error was actually : " + str(ex));
|
||||||
|
|
||||||
|
self.assertEqual(success, True, "Check if passing rootdisksize < templatesize fails appropriately")
|
||||||
|
else:
|
||||||
|
self.debug("test 01 does not support hypervisor type " + self.apiclient.hypervisor);
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
try:
|
||||||
|
cleanup_resources(self.apiclient, self.cleanup)
|
||||||
|
except Exception as e:
|
||||||
|
self.debug("Warning! Exception in tearDown: %s" % e)
|
||||||
@ -571,6 +571,31 @@ class TestVolumes(cloudstackTestCase):
|
|||||||
success,
|
success,
|
||||||
True,
|
True,
|
||||||
"ResizeVolume - verify disk offering is handled appropriately")
|
"ResizeVolume - verify disk offering is handled appropriately")
|
||||||
|
|
||||||
|
# try to resize a root disk with a disk offering, root can only be resized by size=
|
||||||
|
# get root vol from created vm
|
||||||
|
list_volume_response = list_volumes(
|
||||||
|
self.apiClient,
|
||||||
|
virtualmachineid=self.virtual_machine.id,
|
||||||
|
type='ROOT',
|
||||||
|
listall=True
|
||||||
|
)
|
||||||
|
|
||||||
|
rootvolume = list_volume_response[0]
|
||||||
|
|
||||||
|
cmd.id = rootvolume.id
|
||||||
|
cmd.diskofferingid = self.services['diskofferingid']
|
||||||
|
success = False
|
||||||
|
try:
|
||||||
|
response = self.apiClient.resizeVolume(cmd)
|
||||||
|
except Exception as ex:
|
||||||
|
if "Can only resize Data volumes" in str(ex):
|
||||||
|
success = True
|
||||||
|
self.assertEqual(
|
||||||
|
success,
|
||||||
|
True,
|
||||||
|
"ResizeVolume - verify root disks cannot be resized by disk offering id")
|
||||||
|
|
||||||
# Ok, now let's try and resize a volume that is not custom.
|
# Ok, now let's try and resize a volume that is not custom.
|
||||||
cmd.id = self.volume.id
|
cmd.id = self.volume.id
|
||||||
cmd.diskofferingid = self.services['diskofferingid']
|
cmd.diskofferingid = self.services['diskofferingid']
|
||||||
@ -647,6 +672,7 @@ class TestVolumes(cloudstackTestCase):
|
|||||||
elif hosts[0].hypervisor.lower() == "vmware":
|
elif hosts[0].hypervisor.lower() == "vmware":
|
||||||
self.skipTest("Resize Volume is unsupported on VmWare")
|
self.skipTest("Resize Volume is unsupported on VmWare")
|
||||||
|
|
||||||
|
# resize the data disk
|
||||||
self.debug("Resize Volume ID: %s" % self.volume.id)
|
self.debug("Resize Volume ID: %s" % self.volume.id)
|
||||||
|
|
||||||
cmd = resizeVolume.resizeVolumeCmd()
|
cmd = resizeVolume.resizeVolumeCmd()
|
||||||
@ -675,7 +701,48 @@ class TestVolumes(cloudstackTestCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
success,
|
success,
|
||||||
True,
|
True,
|
||||||
"Check if the volume resized appropriately"
|
"Check if the data volume resized appropriately"
|
||||||
|
)
|
||||||
|
|
||||||
|
# resize the root disk
|
||||||
|
self.debug("Resize Root for : %s" % self.virtual_machine.id)
|
||||||
|
|
||||||
|
# get root vol from created vm
|
||||||
|
list_volume_response = list_volumes(
|
||||||
|
self.apiClient,
|
||||||
|
virtualmachineid=self.virtual_machine.id,
|
||||||
|
type='ROOT',
|
||||||
|
listall=True
|
||||||
|
)
|
||||||
|
|
||||||
|
rootvolume = list_volume_response[0]
|
||||||
|
|
||||||
|
cmd = resizeVolume.resizeVolumeCmd()
|
||||||
|
cmd.id = rootvolume.id
|
||||||
|
cmd.size = 10
|
||||||
|
|
||||||
|
self.apiClient.resizeVolume(cmd)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
success = False
|
||||||
|
while count < 3:
|
||||||
|
list_volume_response = list_volumes(
|
||||||
|
self.apiClient,
|
||||||
|
id=rootvolume.id
|
||||||
|
)
|
||||||
|
for vol in list_volume_response:
|
||||||
|
if vol.id == rootvolume.id and vol.size == 10737418240L and vol.state == 'Ready':
|
||||||
|
success = True
|
||||||
|
if success:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
time.sleep(10)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
success,
|
||||||
|
True,
|
||||||
|
"Check if the root volume resized appropriately"
|
||||||
)
|
)
|
||||||
|
|
||||||
#start the vm if it is on xenserver
|
#start the vm if it is on xenserver
|
||||||
|
|||||||
@ -120,20 +120,14 @@
|
|||||||
"port": 3306,
|
"port": 3306,
|
||||||
"user": "cloud"
|
"user": "cloud"
|
||||||
},
|
},
|
||||||
"logger": [
|
"logger": {
|
||||||
{
|
"LogFolderPath": "/tmp/"
|
||||||
"name": "TestClient",
|
},
|
||||||
"file": "/var/log/testclient.log"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "TestCase",
|
|
||||||
"file": "/var/log/testcase.log"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mgtSvr": [
|
"mgtSvr": [
|
||||||
{
|
{
|
||||||
"mgtSvrIp": "172.17.10.10",
|
"mgtSvrIp": "172.17.10.10",
|
||||||
"port": 8096
|
"port": 8096,
|
||||||
|
"hypervisor": "kvm"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,7 +133,8 @@
|
|||||||
"mgtSvr": [
|
"mgtSvr": [
|
||||||
{
|
{
|
||||||
"mgtSvrIp": "172.17.10.10",
|
"mgtSvrIp": "172.17.10.10",
|
||||||
"port": 8096
|
"port": 8096,
|
||||||
|
"hypervisor": "kvm"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -104,7 +104,8 @@
|
|||||||
"mgtSvr": [
|
"mgtSvr": [
|
||||||
{
|
{
|
||||||
"mgtSvrIp": "127.0.0.1",
|
"mgtSvrIp": "127.0.0.1",
|
||||||
"port": 8096
|
"port": 8096,
|
||||||
|
"hypervisor": "kvm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dbSvr":
|
"dbSvr":
|
||||||
|
|||||||
@ -325,7 +325,7 @@ class VirtualMachine:
|
|||||||
securitygroupids=None, projectid=None, startvm=None,
|
securitygroupids=None, projectid=None, startvm=None,
|
||||||
diskofferingid=None, affinitygroupnames=None, affinitygroupids=None, group=None,
|
diskofferingid=None, affinitygroupnames=None, affinitygroupids=None, group=None,
|
||||||
hostid=None, keypair=None, ipaddress=None, mode='default', method='GET',
|
hostid=None, keypair=None, ipaddress=None, mode='default', method='GET',
|
||||||
customcpunumber=None, customcpuspeed=None, custommemory=None):
|
customcpunumber=None, customcpuspeed=None, custommemory=None, rootdisksize=None):
|
||||||
"""Create the instance"""
|
"""Create the instance"""
|
||||||
|
|
||||||
cmd = deployVirtualMachine.deployVirtualMachineCmd()
|
cmd = deployVirtualMachine.deployVirtualMachineCmd()
|
||||||
@ -413,7 +413,7 @@ class VirtualMachine:
|
|||||||
if "userdata" in services:
|
if "userdata" in services:
|
||||||
cmd.userdata = base64.urlsafe_b64encode(services["userdata"])
|
cmd.userdata = base64.urlsafe_b64encode(services["userdata"])
|
||||||
|
|
||||||
cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":""}]
|
cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":"","rootdisksize":""}]
|
||||||
|
|
||||||
if customcpunumber:
|
if customcpunumber:
|
||||||
cmd.details[0]["cpuNumber"] = customcpunumber
|
cmd.details[0]["cpuNumber"] = customcpunumber
|
||||||
@ -424,6 +424,9 @@ class VirtualMachine:
|
|||||||
if custommemory:
|
if custommemory:
|
||||||
cmd.details[0]["memory"] = custommemory
|
cmd.details[0]["memory"] = custommemory
|
||||||
|
|
||||||
|
if rootdisksize:
|
||||||
|
cmd.details[0]["rootdisksize"] = rootdisksize
|
||||||
|
|
||||||
if group:
|
if group:
|
||||||
cmd.group = group
|
cmd.group = group
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user