Skip to content

Commit 72cf974

Browse files
committed
Merge branch '4.18'
2 parents 5d9ae31 + a20ab40 commit 72cf974

File tree

4 files changed

+81
-37
lines changed

4 files changed

+81
-37
lines changed

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,11 +1715,11 @@ public Answer createSnapshot(final CreateObjectCommand cmd) {
17151715
snapshotPath = getSnapshotPathInPrimaryStorage(primaryPool.getLocalPath(), snapshotName);
17161716

17171717
String diskLabel = takeVolumeSnapshot(resource.getDisks(conn, vmName), snapshotName, diskPath, vm);
1718-
String copyResult = copySnapshotToPrimaryStorageDir(primaryPool, diskPath, snapshotPath, volume);
1718+
String convertResult = convertBaseFileToSnapshotFileInPrimaryStorageDir(primaryPool, diskPath, snapshotPath, volume, cmd.getWait());
17191719

17201720
mergeSnapshotIntoBaseFile(vm, diskLabel, diskPath, snapshotName, volume, conn);
17211721

1722-
validateCopyResult(copyResult, snapshotPath);
1722+
validateConvertResult(convertResult, snapshotPath);
17231723
} catch (LibvirtException e) {
17241724
if (!e.getMessage().contains(LIBVIRT_OPERATION_NOT_SUPPORTED_MESSAGE)) {
17251725
throw e;
@@ -1784,8 +1784,8 @@ public Answer createSnapshot(final CreateObjectCommand cmd) {
17841784
}
17851785
} else {
17861786
snapshotPath = getSnapshotPathInPrimaryStorage(primaryPool.getLocalPath(), snapshotName);
1787-
String copyResult = copySnapshotToPrimaryStorageDir(primaryPool, diskPath, snapshotPath, volume);
1788-
validateCopyResult(copyResult, snapshotPath);
1787+
String convertResult = convertBaseFileToSnapshotFileInPrimaryStorageDir(primaryPool, diskPath, snapshotPath, volume, cmd.getWait());
1788+
validateConvertResult(convertResult, snapshotPath);
17891789
}
17901790
}
17911791

@@ -1838,13 +1838,13 @@ protected void takeFullVmSnapshotForBinariesThatDoesNotSupportLiveDiskSnapshot(D
18381838
s_logger.debug(String.format("Full VM Snapshot [%s] of VM [%s] took [%s] seconds to finish.", snapshotName, vmName, (System.currentTimeMillis() - start)/1000));
18391839
}
18401840

1841-
protected void validateCopyResult(String copyResult, String snapshotPath) throws CloudRuntimeException, IOException {
1842-
if (copyResult == null) {
1841+
protected void validateConvertResult(String convertResult, String snapshotPath) throws CloudRuntimeException, IOException {
1842+
if (convertResult == null) {
18431843
return;
18441844
}
18451845

18461846
Files.deleteIfExists(Paths.get(snapshotPath));
1847-
throw new CloudRuntimeException(copyResult);
1847+
throw new CloudRuntimeException(convertResult);
18481848
}
18491849

18501850
/**
@@ -1901,20 +1901,31 @@ protected void manuallyDeleteUnusedSnapshotFile(boolean isLibvirtSupportingFlagD
19011901
}
19021902

19031903
/**
1904-
* Creates the snapshot directory in the primary storage, if it does not exist; then copies the base file (VM's old writing file) to the snapshot dir..
1904+
* Creates the snapshot directory in the primary storage, if it does not exist; then, converts the base file (VM's old writing file) to the snapshot directory.
19051905
* @param primaryPool Storage to create folder, if not exists;
1906-
* @param baseFile Base file of VM, which will be copied;
1907-
* @param snapshotPath Path to copy the base file;
1908-
* @return null if copies successfully or a error message.
1906+
* @param baseFile Base file of VM, which will be converted;
1907+
* @param snapshotPath Path to convert the base file;
1908+
* @return null if the conversion occurs successfully or an error message that must be handled.
19091909
*/
1910-
protected String copySnapshotToPrimaryStorageDir(KVMStoragePool primaryPool, String baseFile, String snapshotPath, VolumeObjectTO volume) {
1910+
protected String convertBaseFileToSnapshotFileInPrimaryStorageDir(KVMStoragePool primaryPool, String baseFile, String snapshotPath, VolumeObjectTO volume, int wait) {
19111911
try {
1912+
s_logger.debug(String.format("Trying to convert volume [%s] (%s) to snapshot [%s].", volume, baseFile, snapshotPath));
1913+
19121914
primaryPool.createFolder(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR);
1913-
Files.copy(Paths.get(baseFile), Paths.get(snapshotPath));
1914-
s_logger.debug(String.format("Copied %s snapshot from [%s] to [%s].", volume, baseFile, snapshotPath));
1915+
1916+
QemuImgFile srcFile = new QemuImgFile(baseFile);
1917+
srcFile.setFormat(PhysicalDiskFormat.QCOW2);
1918+
1919+
QemuImgFile destFile = new QemuImgFile(snapshotPath);
1920+
destFile.setFormat(PhysicalDiskFormat.QCOW2);
1921+
1922+
QemuImg q = new QemuImg(wait);
1923+
q.convert(srcFile, destFile);
1924+
1925+
s_logger.debug(String.format("Converted volume [%s] (from path \"%s\") to snapshot [%s].", volume, baseFile, snapshotPath));
19151926
return null;
1916-
} catch (IOException ex) {
1917-
return String.format("Unable to copy %s snapshot [%s] to [%s] due to [%s].", volume, baseFile, snapshotPath, ex.getMessage());
1927+
} catch (QemuImgException | LibvirtException ex) {
1928+
return String.format("Failed to convert %s snapshot of volume [%s] to [%s] due to [%s].", volume, baseFile, snapshotPath, ex.getMessage());
19181929
}
19191930
}
19201931

plugins/hypervisors/kvm/src/test/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessorTest.java

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
import java.util.Set;
4040
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
4141
import org.apache.cloudstack.storage.to.VolumeObjectTO;
42+
import org.apache.cloudstack.utils.qemu.QemuImg;
43+
import org.apache.cloudstack.utils.qemu.QemuImgException;
44+
import org.apache.cloudstack.utils.qemu.QemuImgFile;
4245
import org.junit.After;
4346
import org.junit.Assert;
4447
import org.junit.Before;
@@ -88,6 +91,11 @@ public class KVMStorageProcessorTest {
8891
@Mock
8992
Connect connectMock;
9093

94+
@Mock
95+
QemuImg qemuImgMock;
96+
97+
@Mock
98+
LibvirtDomainXMLParser libvirtDomainXMLParserMock;
9199
@Mock
92100
LibvirtVMDef.DiskDef diskDefMock;
93101

@@ -251,36 +259,47 @@ public void validateTakeVolumeSnapshotSuccessReturnDiskLabel() throws LibvirtExc
251259
}
252260

253261
@Test
254-
public void validateCopySnapshotToPrimaryStorageDirFailToCopyReturnErrorMessage() throws Exception {
262+
public void convertBaseFileToSnapshotFileInPrimaryStorageDirTestFailToConvertWithQemuImgExceptionReturnErrorMessage() throws Exception {
255263
String baseFile = "baseFile";
256264
String snapshotPath = "snapshotPath";
257265
String errorMessage = "error";
258-
String expectedResult = String.format("Unable to copy %s snapshot [%s] to [%s] due to [%s].", volumeObjectToMock, baseFile, snapshotPath, errorMessage);
266+
String expectedResult = String.format("Failed to convert %s snapshot of volume [%s] to [%s] due to [%s].", volumeObjectToMock, baseFile, snapshotPath, errorMessage);
259267

260268
Mockito.doReturn(true).when(kvmStoragePoolMock).createFolder(Mockito.anyString());
261-
try (MockedStatic<Files> ignored = Mockito.mockStatic(Files.class)) {
262-
Mockito.when(Files.copy(Mockito.any(Path.class), Mockito.any(Path.class), Mockito.any())).thenThrow(
263-
new IOException(errorMessage));
264-
265-
String result = storageProcessorSpy.copySnapshotToPrimaryStorageDir(kvmStoragePoolMock, baseFile,
266-
snapshotPath, volumeObjectToMock);
267-
269+
try (MockedConstruction<QemuImg> ignored = Mockito.mockConstruction(QemuImg.class, (mock,context) -> {
270+
Mockito.doThrow(new QemuImgException(errorMessage)).when(mock).convert(Mockito.any(QemuImgFile.class), Mockito.any(QemuImgFile.class));
271+
})) {
272+
String result = storageProcessorSpy.convertBaseFileToSnapshotFileInPrimaryStorageDir(kvmStoragePoolMock, baseFile, snapshotPath, volumeObjectToMock, 1);
268273
Assert.assertEquals(expectedResult, result);
269274
}
270275
}
271276

272277
@Test
273-
public void validateCopySnapshotToPrimaryStorageDirCopySuccessReturnNull() throws Exception {
278+
public void convertBaseFileToSnapshotFileInPrimaryStorageDirTestFailToConvertWithLibvirtExceptionReturnErrorMessage() throws Exception {
274279
String baseFile = "baseFile";
275280
String snapshotPath = "snapshotPath";
281+
String errorMessage = "null";
282+
String expectedResult = String.format("Failed to convert %s snapshot of volume [%s] to [%s] due to [%s].", volumeObjectToMock, baseFile, snapshotPath, errorMessage);
276283

277284
Mockito.doReturn(true).when(kvmStoragePoolMock).createFolder(Mockito.anyString());
278-
try (MockedStatic<Files> ignored = Mockito.mockStatic(Files.class)) {
279-
Mockito.when(Files.copy(Mockito.any(Path.class), Mockito.any(Path.class), Mockito.any())).thenReturn(null);
285+
try (MockedConstruction<QemuImg> ignored = Mockito.mockConstruction(QemuImg.class, (mock,context) -> {
286+
Mockito.doThrow(LibvirtException.class).when(mock).convert(Mockito.any(QemuImgFile.class), Mockito.any(QemuImgFile.class));
287+
})) {
288+
String result = storageProcessorSpy.convertBaseFileToSnapshotFileInPrimaryStorageDir(kvmStoragePoolMock, baseFile, snapshotPath, volumeObjectToMock, 1);
289+
Assert.assertEquals(expectedResult, result);
290+
}
291+
}
280292

281-
String result = storageProcessorSpy.copySnapshotToPrimaryStorageDir(kvmStoragePoolMock, baseFile,
282-
snapshotPath, volumeObjectToMock);
293+
@Test
294+
public void convertBaseFileToSnapshotFileInPrimaryStorageDirTestConvertSuccessReturnNull() throws Exception {
295+
String baseFile = "baseFile";
296+
String snapshotPath = "snapshotPath";
283297

298+
Mockito.doReturn(true).when(kvmStoragePoolMock).createFolder(Mockito.anyString());
299+
try (MockedConstruction<QemuImg> ignored = Mockito.mockConstruction(QemuImg.class, (mock, context) -> {
300+
Mockito.doNothing().when(mock).convert(Mockito.any(QemuImgFile.class), Mockito.any(QemuImgFile.class));
301+
})) {
302+
String result = storageProcessorSpy.convertBaseFileToSnapshotFileInPrimaryStorageDir(kvmStoragePoolMock, baseFile, snapshotPath, volumeObjectToMock, 1);
284303
Assert.assertNull(result);
285304
}
286305
}
@@ -334,22 +353,22 @@ public void validateIsAvailablePoolSizeDividedByDiskSizeLesserThanMinRate(){
334353

335354
@Test
336355
public void validateValidateCopyResultResultIsNullReturn() throws CloudRuntimeException, IOException{
337-
storageProcessorSpy.validateCopyResult(null, "");
356+
storageProcessorSpy.validateConvertResult(null, "");
338357
}
339358

340359
@Test (expected = IOException.class)
341360
public void validateValidateCopyResultFailToDeleteThrowIOException() throws CloudRuntimeException, IOException{
342361
try (MockedStatic<Files> ignored = Mockito.mockStatic(Files.class)) {
343362
Mockito.when(Files.deleteIfExists(Mockito.any())).thenThrow(new IOException(""));
344-
storageProcessorSpy.validateCopyResult("", "");
363+
storageProcessorSpy.validateConvertResult("", "");
345364
}
346365
}
347366

348367
@Test (expected = CloudRuntimeException.class)
349368
public void validateValidateCopyResulResultNotNullThrowCloudRuntimeException() throws CloudRuntimeException, IOException{
350369
try (MockedStatic<Files> ignored = Mockito.mockStatic(Files.class)) {
351370
Mockito.when(Files.deleteIfExists(Mockito.any())).thenReturn(true);
352-
storageProcessorSpy.validateCopyResult("", "");
371+
storageProcessorSpy.validateConvertResult("", "");
353372
}
354373
}
355374

plugins/integrations/prometheus/src/main/java/org/apache/cloudstack/metrics/PrometheusExporterImpl.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,12 @@ private void addHostMetrics(final List<Item> metricsList, final long dcId, final
163163
final CapacityVO cpuCapacity = capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU);
164164
final double cpuUsedMhz = hostStats.getCpuUtilization() * host.getCpus() * host.getSpeed() / 100.0 ;
165165

166-
if (cpuCapacity != null && cpuCapacity.getCapacityState() == CapacityState.Enabled) {
166+
if (host.isInMaintenanceStates()) {
167+
metricsList.add(new ItemHostCpu(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), cpuFactor, ALLOCATED, 0L, isDedicated, hostTags));
168+
metricsList.add(new ItemHostCpu(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), cpuFactor, USED, 0L, isDedicated, hostTags));
169+
metricsList.add(new ItemHostCpu(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), cpuFactor, TOTAL, 0L, isDedicated, hostTags));
170+
}
171+
else if (cpuCapacity != null && cpuCapacity.getCapacityState() == CapacityState.Enabled) {
167172
metricsList.add(new ItemHostCpu(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), cpuFactor, ALLOCATED, cpuCapacity.getUsedCapacity(), isDedicated, hostTags));
168173
metricsList.add(new ItemHostCpu(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), cpuFactor, USED, cpuUsedMhz, isDedicated, hostTags));
169174
metricsList.add(new ItemHostCpu(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), cpuFactor, TOTAL, cpuCapacity.getTotalCapacity(), isDedicated, hostTags));
@@ -175,7 +180,12 @@ private void addHostMetrics(final List<Item> metricsList, final long dcId, final
175180

176181
final String memoryFactor = String.valueOf(CapacityManager.MemOverprovisioningFactor.valueIn(host.getClusterId()));
177182
final CapacityVO memCapacity = capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_MEMORY);
178-
if (memCapacity != null && memCapacity.getCapacityState() == CapacityState.Enabled) {
183+
if (host.isInMaintenanceStates()) {
184+
metricsList.add(new ItemHostMemory(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), memoryFactor, ALLOCATED, 0L, isDedicated, hostTags));
185+
metricsList.add(new ItemHostMemory(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), memoryFactor, USED, 0, isDedicated, hostTags));
186+
metricsList.add(new ItemHostMemory(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), memoryFactor, TOTAL, 0L, isDedicated, hostTags));
187+
}
188+
else if (memCapacity != null && memCapacity.getCapacityState() == CapacityState.Enabled) {
179189
metricsList.add(new ItemHostMemory(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), memoryFactor, ALLOCATED, memCapacity.getUsedCapacity(), isDedicated, hostTags));
180190
metricsList.add(new ItemHostMemory(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), memoryFactor, USED, hostStats.getUsedMemory(), isDedicated, hostTags));
181191
metricsList.add(new ItemHostMemory(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), memoryFactor, TOTAL, memCapacity.getTotalCapacity(), isDedicated, hostTags));
@@ -188,7 +198,11 @@ private void addHostMetrics(final List<Item> metricsList, final long dcId, final
188198
metricsList.add(new ItemHostVM(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), vmDao.listByHostId(host.getId()).size()));
189199

190200
final CapacityVO coreCapacity = capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU_CORE);
191-
if (coreCapacity != null && coreCapacity.getCapacityState() == CapacityState.Enabled) {
201+
if (host.isInMaintenanceStates()) {
202+
metricsList.add(new ItemVMCore(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), USED, 0L, isDedicated, hostTags));
203+
metricsList.add(new ItemVMCore(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), TOTAL, 0L, isDedicated, hostTags));
204+
}
205+
else if (coreCapacity != null && coreCapacity.getCapacityState() == CapacityState.Enabled) {
192206
metricsList.add(new ItemVMCore(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), USED, coreCapacity.getUsedCapacity(), isDedicated, hostTags));
193207
metricsList.add(new ItemVMCore(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), TOTAL, coreCapacity.getTotalCapacity(), isDedicated, hostTags));
194208
} else {

systemvm/debian/opt/cloud/bin/setup/cloud-early-config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ patch() {
6666
if [ "$TYPE" != "cksnode" ]; then
6767
while [ $retry -gt 0 ]
6868
do
69-
if [ -f $patchfile ]; then
69+
if tar tf $patchfile &> /dev/null; then
7070
eval $(validate_checksums $md5file $patchfile)
7171
if [ "$oldmd5" != "$newmd5" ] && [ -f ${patchfile} ] && [ "$newmd5" != "" ]
7272
then

0 commit comments

Comments
 (0)