mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Refactoring the LibvirtComputingResource
- Adding LibvirtCreateCommandWrapper and LibvirtMaintainCommandWrapper - 4 unit tests added - KVM hypervisor plugin with 12.7% coverage
This commit is contained in:
parent
6f757c6bf0
commit
cb4670279f
@ -101,8 +101,6 @@ import com.cloud.agent.api.FenceCommand;
|
|||||||
import com.cloud.agent.api.GetStorageStatsAnswer;
|
import com.cloud.agent.api.GetStorageStatsAnswer;
|
||||||
import com.cloud.agent.api.GetStorageStatsCommand;
|
import com.cloud.agent.api.GetStorageStatsCommand;
|
||||||
import com.cloud.agent.api.HostVmStateReportEntry;
|
import com.cloud.agent.api.HostVmStateReportEntry;
|
||||||
import com.cloud.agent.api.MaintainAnswer;
|
|
||||||
import com.cloud.agent.api.MaintainCommand;
|
|
||||||
import com.cloud.agent.api.ManageSnapshotAnswer;
|
import com.cloud.agent.api.ManageSnapshotAnswer;
|
||||||
import com.cloud.agent.api.ManageSnapshotCommand;
|
import com.cloud.agent.api.ManageSnapshotCommand;
|
||||||
import com.cloud.agent.api.ModifyStoragePoolAnswer;
|
import com.cloud.agent.api.ModifyStoragePoolAnswer;
|
||||||
@ -1305,9 +1303,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (cmd instanceof MaintainCommand) {
|
if (cmd instanceof CreateCommand) {
|
||||||
return execute((MaintainCommand)cmd);
|
|
||||||
} else if (cmd instanceof CreateCommand) {
|
|
||||||
return execute((CreateCommand)cmd);
|
return execute((CreateCommand)cmd);
|
||||||
} else if (cmd instanceof DestroyCommand) {
|
} else if (cmd instanceof DestroyCommand) {
|
||||||
return execute((DestroyCommand)cmd);
|
return execute((DestroyCommand)cmd);
|
||||||
@ -1769,7 +1765,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this is much like PrimaryStorageDownloadCommand, but keeping it separate
|
// this is much like PrimaryStorageDownloadCommand, but keeping it separate
|
||||||
protected KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid) {
|
public KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid) {
|
||||||
final int index = templateUrl.lastIndexOf("/");
|
final int index = templateUrl.lastIndexOf("/");
|
||||||
final String mountpoint = templateUrl.substring(0, index);
|
final String mountpoint = templateUrl.substring(0, index);
|
||||||
String templateName = null;
|
String templateName = null;
|
||||||
@ -2866,10 +2862,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
return new Answer(cmd, result, "");
|
return new Answer(cmd, result, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MaintainAnswer execute(final MaintainCommand cmd) {
|
|
||||||
return new MaintainAnswer(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PowerState convertToPowerState(final DomainState ps) {
|
protected PowerState convertToPowerState(final DomainState ps) {
|
||||||
final PowerState state = s_powerStatesTable.get(ps);
|
final PowerState state = s_powerStatesTable.get(ps);
|
||||||
return state == null ? PowerState.PowerUnknown : state;
|
return state == null ? PowerState.PowerUnknown : state;
|
||||||
|
|||||||
@ -0,0 +1,83 @@
|
|||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
package com.cloud.hypervisor.kvm.resource.wrapper;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.Answer;
|
||||||
|
import com.cloud.agent.api.storage.CreateAnswer;
|
||||||
|
import com.cloud.agent.api.storage.CreateCommand;
|
||||||
|
import com.cloud.agent.api.to.StorageFilerTO;
|
||||||
|
import com.cloud.agent.api.to.VolumeTO;
|
||||||
|
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||||
|
import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk;
|
||||||
|
import com.cloud.hypervisor.kvm.storage.KVMStoragePool;
|
||||||
|
import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager;
|
||||||
|
import com.cloud.resource.CommandWrapper;
|
||||||
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.vm.DiskProfile;
|
||||||
|
|
||||||
|
public final class LibvirtCreateCommandWrapper extends CommandWrapper<CreateCommand, Answer, LibvirtComputingResource> {
|
||||||
|
|
||||||
|
private static final Logger s_logger = Logger.getLogger(LibvirtCreateCommandWrapper.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Answer execute(final CreateCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||||
|
final StorageFilerTO pool = command.getPool();
|
||||||
|
final DiskProfile dskch = command.getDiskCharacteristics();
|
||||||
|
KVMPhysicalDisk baseVol = null;
|
||||||
|
KVMStoragePool primaryPool = null;
|
||||||
|
KVMPhysicalDisk vol = null;
|
||||||
|
long disksize;
|
||||||
|
try {
|
||||||
|
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
|
||||||
|
primaryPool = storagePoolMgr.getStoragePool(pool.getType(), pool.getUuid());
|
||||||
|
disksize = dskch.getSize();
|
||||||
|
|
||||||
|
if (command.getTemplateUrl() != null) {
|
||||||
|
if (primaryPool.getType() == StoragePoolType.CLVM) {
|
||||||
|
vol = libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primaryPool, dskch.getPath());
|
||||||
|
} else {
|
||||||
|
baseVol = primaryPool.getPhysicalDisk(command.getTemplateUrl());
|
||||||
|
vol = storagePoolMgr.createDiskFromTemplate(baseVol,
|
||||||
|
dskch.getPath(), dskch.getProvisioningType(), primaryPool, 0);
|
||||||
|
}
|
||||||
|
if (vol == null) {
|
||||||
|
return new Answer(command, false, " Can't create storage volume on storage pool");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vol = primaryPool.createPhysicalDisk(dskch.getPath(), dskch.getProvisioningType(), dskch.getSize());
|
||||||
|
}
|
||||||
|
final VolumeTO volume =
|
||||||
|
new VolumeTO(command.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), pool.getPath(), vol.getName(), vol.getName(), disksize, null);
|
||||||
|
|
||||||
|
volume.setBytesReadRate(dskch.getBytesReadRate());
|
||||||
|
volume.setBytesWriteRate(dskch.getBytesWriteRate());
|
||||||
|
volume.setIopsReadRate(dskch.getIopsReadRate());
|
||||||
|
volume.setIopsWriteRate(dskch.getIopsWriteRate());
|
||||||
|
volume.setCacheMode(dskch.getCacheMode());
|
||||||
|
return new CreateAnswer(command, volume);
|
||||||
|
} catch (final CloudRuntimeException e) {
|
||||||
|
s_logger.debug("Failed to create volume: " + e.toString());
|
||||||
|
return new CreateAnswer(command, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
package com.cloud.hypervisor.kvm.resource.wrapper;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.Answer;
|
||||||
|
import com.cloud.agent.api.MaintainAnswer;
|
||||||
|
import com.cloud.agent.api.MaintainCommand;
|
||||||
|
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||||
|
import com.cloud.resource.CommandWrapper;
|
||||||
|
|
||||||
|
public final class LibvirtMaintainCommandWrapper extends CommandWrapper<MaintainCommand, Answer, LibvirtComputingResource> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Answer execute(final MaintainCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||||
|
return new MaintainAnswer(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,6 +30,7 @@ import com.cloud.agent.api.GetHostStatsCommand;
|
|||||||
import com.cloud.agent.api.GetVmDiskStatsCommand;
|
import com.cloud.agent.api.GetVmDiskStatsCommand;
|
||||||
import com.cloud.agent.api.GetVmStatsCommand;
|
import com.cloud.agent.api.GetVmStatsCommand;
|
||||||
import com.cloud.agent.api.GetVncPortCommand;
|
import com.cloud.agent.api.GetVncPortCommand;
|
||||||
|
import com.cloud.agent.api.MaintainCommand;
|
||||||
import com.cloud.agent.api.MigrateCommand;
|
import com.cloud.agent.api.MigrateCommand;
|
||||||
import com.cloud.agent.api.ModifySshKeysCommand;
|
import com.cloud.agent.api.ModifySshKeysCommand;
|
||||||
import com.cloud.agent.api.PingTestCommand;
|
import com.cloud.agent.api.PingTestCommand;
|
||||||
@ -40,6 +41,7 @@ import com.cloud.agent.api.RebootRouterCommand;
|
|||||||
import com.cloud.agent.api.StopCommand;
|
import com.cloud.agent.api.StopCommand;
|
||||||
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
|
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
|
||||||
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
|
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
|
||||||
|
import com.cloud.agent.api.storage.CreateCommand;
|
||||||
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||||
import com.cloud.resource.CommandWrapper;
|
import com.cloud.resource.CommandWrapper;
|
||||||
import com.cloud.resource.RequestWrapper;
|
import com.cloud.resource.RequestWrapper;
|
||||||
@ -80,6 +82,8 @@ public class LibvirtRequestWrapper extends RequestWrapper {
|
|||||||
linbvirtCommands.put(CheckConsoleProxyLoadCommand.class, new LibvirtCheckConsoleProxyLoadCommandWrapper());
|
linbvirtCommands.put(CheckConsoleProxyLoadCommand.class, new LibvirtCheckConsoleProxyLoadCommandWrapper());
|
||||||
linbvirtCommands.put(GetVncPortCommand.class, new LibvirtGetVncPortCommandWrapper());
|
linbvirtCommands.put(GetVncPortCommand.class, new LibvirtGetVncPortCommandWrapper());
|
||||||
linbvirtCommands.put(ModifySshKeysCommand.class, new LibvirtModifySshKeysCommandWrapper());
|
linbvirtCommands.put(ModifySshKeysCommand.class, new LibvirtModifySshKeysCommandWrapper());
|
||||||
|
linbvirtCommands.put(MaintainCommand.class, new LibvirtMaintainCommandWrapper());
|
||||||
|
linbvirtCommands.put(CreateCommand.class, new LibvirtCreateCommandWrapper());
|
||||||
|
|
||||||
resources.put(LibvirtComputingResource.class, linbvirtCommands);
|
resources.put(LibvirtComputingResource.class, linbvirtCommands);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,6 +72,7 @@ import com.cloud.agent.api.GetHostStatsCommand;
|
|||||||
import com.cloud.agent.api.GetVmDiskStatsCommand;
|
import com.cloud.agent.api.GetVmDiskStatsCommand;
|
||||||
import com.cloud.agent.api.GetVmStatsCommand;
|
import com.cloud.agent.api.GetVmStatsCommand;
|
||||||
import com.cloud.agent.api.GetVncPortCommand;
|
import com.cloud.agent.api.GetVncPortCommand;
|
||||||
|
import com.cloud.agent.api.MaintainCommand;
|
||||||
import com.cloud.agent.api.MigrateCommand;
|
import com.cloud.agent.api.MigrateCommand;
|
||||||
import com.cloud.agent.api.ModifySshKeysCommand;
|
import com.cloud.agent.api.ModifySshKeysCommand;
|
||||||
import com.cloud.agent.api.PingTestCommand;
|
import com.cloud.agent.api.PingTestCommand;
|
||||||
@ -83,8 +84,10 @@ import com.cloud.agent.api.StopCommand;
|
|||||||
import com.cloud.agent.api.VmStatsEntry;
|
import com.cloud.agent.api.VmStatsEntry;
|
||||||
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
|
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
|
||||||
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
|
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
|
||||||
|
import com.cloud.agent.api.storage.CreateCommand;
|
||||||
import com.cloud.agent.api.to.DiskTO;
|
import com.cloud.agent.api.to.DiskTO;
|
||||||
import com.cloud.agent.api.to.NicTO;
|
import com.cloud.agent.api.to.NicTO;
|
||||||
|
import com.cloud.agent.api.to.StorageFilerTO;
|
||||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||||
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
|
import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
|
||||||
import com.cloud.exception.InternalErrorException;
|
import com.cloud.exception.InternalErrorException;
|
||||||
@ -100,6 +103,7 @@ import com.cloud.storage.Storage.StoragePoolType;
|
|||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
|
import com.cloud.vm.DiskProfile;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
import com.cloud.vm.VirtualMachine.PowerState;
|
import com.cloud.vm.VirtualMachine.PowerState;
|
||||||
|
|
||||||
@ -1217,4 +1221,102 @@ public class LibvirtComputingResourceTest {
|
|||||||
|
|
||||||
verify(libvirtComputingResource, times(1)).getTimeout();
|
verify(libvirtComputingResource, times(1)).getTimeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMaintainCommand() {
|
||||||
|
final MaintainCommand command = new MaintainCommand();
|
||||||
|
|
||||||
|
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||||
|
assertNotNull(wrapper);
|
||||||
|
|
||||||
|
final Answer answer = wrapper.execute(command, libvirtComputingResource);
|
||||||
|
assertTrue(answer.getResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateCommandNoTemplate() {
|
||||||
|
final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
|
||||||
|
final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
|
||||||
|
final boolean executeInSequence = false;
|
||||||
|
|
||||||
|
final CreateCommand command = new CreateCommand(diskCharacteristics, pool, executeInSequence );
|
||||||
|
|
||||||
|
final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
|
||||||
|
final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
|
||||||
|
final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
|
||||||
|
|
||||||
|
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
|
||||||
|
when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
|
||||||
|
|
||||||
|
when(primary.createPhysicalDisk(diskCharacteristics.getPath(), diskCharacteristics.getProvisioningType(), diskCharacteristics.getSize())).thenReturn(vol);
|
||||||
|
|
||||||
|
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||||
|
assertNotNull(wrapper);
|
||||||
|
|
||||||
|
final Answer answer = wrapper.execute(command, libvirtComputingResource);
|
||||||
|
assertTrue(answer.getResult());
|
||||||
|
|
||||||
|
verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
|
||||||
|
verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateCommand() {
|
||||||
|
final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
|
||||||
|
final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
|
||||||
|
final String templateUrl = "http://template";
|
||||||
|
final boolean executeInSequence = false;
|
||||||
|
|
||||||
|
final CreateCommand command = new CreateCommand(diskCharacteristics, templateUrl, pool, executeInSequence );
|
||||||
|
|
||||||
|
final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
|
||||||
|
final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
|
||||||
|
final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
|
||||||
|
|
||||||
|
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
|
||||||
|
when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
|
||||||
|
|
||||||
|
when(primary.getType()).thenReturn(StoragePoolType.CLVM);
|
||||||
|
when(libvirtComputingResource.templateToPrimaryDownload(command.getTemplateUrl(), primary, diskCharacteristics.getPath())).thenReturn(vol);
|
||||||
|
|
||||||
|
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||||
|
assertNotNull(wrapper);
|
||||||
|
|
||||||
|
final Answer answer = wrapper.execute(command, libvirtComputingResource);
|
||||||
|
assertTrue(answer.getResult());
|
||||||
|
|
||||||
|
verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
|
||||||
|
verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateCommandCLVM() {
|
||||||
|
final DiskProfile diskCharacteristics = Mockito.mock(DiskProfile.class);
|
||||||
|
final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
|
||||||
|
final String templateUrl = "http://template";
|
||||||
|
final boolean executeInSequence = false;
|
||||||
|
|
||||||
|
final CreateCommand command = new CreateCommand(diskCharacteristics, templateUrl, pool, executeInSequence );
|
||||||
|
|
||||||
|
final KVMStoragePoolManager poolManager = Mockito.mock(KVMStoragePoolManager.class);
|
||||||
|
final KVMStoragePool primary = Mockito.mock(KVMStoragePool.class);
|
||||||
|
final KVMPhysicalDisk vol = Mockito.mock(KVMPhysicalDisk.class);
|
||||||
|
final KVMPhysicalDisk baseVol = Mockito.mock(KVMPhysicalDisk.class);
|
||||||
|
|
||||||
|
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(poolManager);
|
||||||
|
when(poolManager.getStoragePool(pool.getType(), pool.getUuid())).thenReturn(primary);
|
||||||
|
|
||||||
|
when(primary.getPhysicalDisk(command.getTemplateUrl())).thenReturn(baseVol);
|
||||||
|
when(poolManager.createDiskFromTemplate(baseVol,
|
||||||
|
diskCharacteristics.getPath(), diskCharacteristics.getProvisioningType(), primary, 0)).thenReturn(vol);
|
||||||
|
|
||||||
|
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
|
||||||
|
assertNotNull(wrapper);
|
||||||
|
|
||||||
|
final Answer answer = wrapper.execute(command, libvirtComputingResource);
|
||||||
|
assertTrue(answer.getResult());
|
||||||
|
|
||||||
|
verify(libvirtComputingResource, times(1)).getStoragePoolMgr();
|
||||||
|
verify(poolManager, times(1)).getStoragePool(pool.getType(), pool.getUuid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user