Allow full clone volumes with thin provisioning in KVM (#11177)

It adds a configuration called create.full.clone to the agent.properties file. When set to true, all QCOW2 volumes created will be full-clone. If false (default), the current behavior remains, where only FAT and SPARSE volumes are full-clone and THIN volumes are linked-clone.
This commit is contained in:
João Jandre 2025-07-31 07:42:17 -03:00 committed by GitHub
parent f62b85dffe
commit 5ea1ada59a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 24 additions and 3 deletions

View File

@ -447,3 +447,6 @@ iscsi.session.cleanup.enabled=false
# Timeout (in seconds) to wait for the incremental snapshot to complete.
# incremental.snapshot.timeout=10800
# If set to true, creates VMs as full clones of their templates on KVM hypervisor. Creates as linked clones otherwise.
# create.full.clone=false

View File

@ -863,6 +863,14 @@ public class AgentProperties{
* */
public static final Property<Integer> REVERT_SNAPSHOT_TIMEOUT = new Property<>("revert.snapshot.timeout", 10800);
/**
* If set to true, creates VMs as full clones of their templates on KVM hypervisor. Creates as linked clones otherwise. <br>
* Data type: Boolean. <br>
* Default value: <code>false</code>
*/
public static final Property<Boolean> CREATE_FULL_CLONE = new Property<>("create.full.clone", false);
public static class Property <T>{
private String name;
private T defaultValue;

View File

@ -32,6 +32,8 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import com.cloud.agent.properties.AgentProperties;
import com.cloud.agent.properties.AgentPropertiesFileHandler;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.utils.cryptsetup.KeyFile;
import org.apache.cloudstack.utils.qemu.QemuImageOptions;
@ -1315,14 +1317,22 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
passphraseObjects.add(QemuObject.prepareSecretForQemuImg(format, QemuObject.EncryptFormat.LUKS, keyFile.toString(), "sec0", options));
disk.setQemuEncryptFormat(QemuObject.EncryptFormat.LUKS);
}
QemuImgFile srcFile = new QemuImgFile(template.getPath(), template.getFormat());
Boolean createFullClone = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.CREATE_FULL_CLONE);
switch(provisioningType){
case THIN:
QemuImgFile backingFile = new QemuImgFile(template.getPath(), template.getFormat());
qemu.create(destFile, backingFile, options, passphraseObjects);
logger.info("Creating volume [{}] {} backing file [{}] as the property [{}] is [{}].", destFile.getFileName(), createFullClone ? "without" : "with",
template.getPath(), AgentProperties.CREATE_FULL_CLONE.getName(), createFullClone);
if (createFullClone) {
qemu.convert(srcFile, destFile, options, passphraseObjects, null, false);
} else {
qemu.create(destFile, srcFile, options, passphraseObjects);
}
break;
case SPARSE:
case FAT:
QemuImgFile srcFile = new QemuImgFile(template.getPath(), template.getFormat());
srcFile = new QemuImgFile(template.getPath(), template.getFormat());
qemu.convert(srcFile, destFile, options, passphraseObjects, null, false);
break;
}