|
26 | 26 | import java.io.FileOutputStream; |
27 | 27 | import java.io.IOException; |
28 | 28 | import java.nio.file.Files; |
| 29 | +import java.nio.file.Path; |
29 | 30 | import java.nio.file.Paths; |
30 | 31 | import java.text.DateFormat; |
31 | 32 | import java.text.SimpleDateFormat; |
| 33 | +import java.util.ArrayList; |
32 | 34 | import java.util.Arrays; |
33 | 35 | import java.util.Date; |
34 | 36 | import java.util.HashMap; |
|
63 | 65 | import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer; |
64 | 66 | import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand; |
65 | 67 | import org.apache.cloudstack.storage.command.SyncVolumePathCommand; |
| 68 | +import org.apache.cloudstack.storage.formatinspector.Qcow2Inspector; |
66 | 69 | import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; |
67 | 70 | import org.apache.cloudstack.storage.to.SnapshotObjectTO; |
68 | 71 | import org.apache.cloudstack.storage.to.TemplateObjectTO; |
69 | 72 | import org.apache.cloudstack.storage.to.VolumeObjectTO; |
| 73 | +import org.apache.cloudstack.utils.cryptsetup.KeyFile; |
| 74 | +import org.apache.cloudstack.utils.qemu.QemuImageOptions; |
70 | 75 | import org.apache.cloudstack.utils.qemu.QemuImg; |
71 | 76 | import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; |
72 | 77 | import org.apache.cloudstack.utils.qemu.QemuImgException; |
73 | 78 | import org.apache.cloudstack.utils.qemu.QemuImgFile; |
74 | 79 | import org.apache.cloudstack.utils.qemu.QemuObject; |
| 80 | +import org.apache.cloudstack.utils.qemu.QemuObject.EncryptFormat; |
75 | 81 | import org.apache.commons.collections.MapUtils; |
76 | 82 | import org.apache.commons.io.FileUtils; |
77 | 83 | import org.apache.commons.lang3.BooleanUtils; |
|
80 | 86 | import org.apache.commons.lang3.builder.ToStringStyle; |
81 | 87 | import org.apache.logging.log4j.Logger; |
82 | 88 | import org.apache.logging.log4j.LogManager; |
| 89 | + |
83 | 90 | import org.libvirt.Connect; |
84 | 91 | import org.libvirt.Domain; |
85 | 92 | import org.libvirt.DomainInfo; |
|
134 | 141 | import com.cloud.utils.script.Script; |
135 | 142 | import com.cloud.utils.storage.S3.S3Utils; |
136 | 143 | import com.cloud.vm.VmDetailConstants; |
137 | | -import org.apache.cloudstack.utils.cryptsetup.KeyFile; |
138 | | -import org.apache.cloudstack.utils.qemu.QemuImageOptions; |
139 | | -import org.apache.cloudstack.utils.qemu.QemuObject.EncryptFormat; |
140 | | -import java.util.ArrayList; |
| 144 | + |
141 | 145 |
|
142 | 146 | public class KVMStorageProcessor implements StorageProcessor { |
143 | 147 | protected Logger logger = LogManager.getLogger(getClass()); |
@@ -2452,6 +2456,22 @@ public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd) |
2452 | 2456 |
|
2453 | 2457 | template = storagePoolMgr.createPhysicalDiskFromDirectDownloadTemplate(tempFilePath, destTemplatePath, destPool, cmd.getFormat(), cmd.getWaitInMillSeconds()); |
2454 | 2458 |
|
| 2459 | + String templatePath = template.getPath(); |
| 2460 | + if (templatePath != null) { |
| 2461 | + try { |
| 2462 | + Qcow2Inspector.validateQcow2File(templatePath); |
| 2463 | + } catch (RuntimeException e) { |
| 2464 | + try { |
| 2465 | + Files.deleteIfExists(Path.of(templatePath)); |
| 2466 | + } catch (IOException ioException) { |
| 2467 | + logger.warn("Unable to remove file [{}]; consider removing it manually.", templatePath, ioException); |
| 2468 | + } |
| 2469 | + |
| 2470 | + logger.error("The downloaded file [{}] is not a valid QCOW2.", templatePath, e); |
| 2471 | + return new DirectDownloadAnswer(false, "The downloaded file is not a valid QCOW2. Ask the administrator to check the logs for more details.", true); |
| 2472 | + } |
| 2473 | + } |
| 2474 | + |
2455 | 2475 | if (!storagePoolMgr.disconnectPhysicalDisk(pool.getPoolType(), pool.getUuid(), destTemplatePath)) { |
2456 | 2476 | logger.warn("Unable to disconnect physical disk at path: " + destTemplatePath + ", in storage pool id: " + pool.getUuid()); |
2457 | 2477 | } |
|
0 commit comments