mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
[VMWare] Limit IOPS in Compute/Disk Offerings (#6386)
This commit is contained in:
parent
38f3027a7c
commit
d04d60b079
@ -51,6 +51,7 @@ import com.cloud.agent.api.PatchSystemVmAnswer;
|
|||||||
import com.cloud.agent.api.PatchSystemVmCommand;
|
import com.cloud.agent.api.PatchSystemVmCommand;
|
||||||
import com.cloud.resource.ServerResourceBase;
|
import com.cloud.resource.ServerResourceBase;
|
||||||
import com.cloud.utils.FileUtil;
|
import com.cloud.utils.FileUtil;
|
||||||
|
import com.cloud.utils.LogUtils;
|
||||||
import com.cloud.utils.validation.ChecksumUtil;
|
import com.cloud.utils.validation.ChecksumUtil;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||||
@ -2431,7 +2432,9 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
|||||||
scsiUnitNumber++;
|
scsiUnitNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), deviceNumber, i + 1);
|
Long maxIops = volumeTO.getIopsWriteRate() + volumeTO.getIopsReadRate();
|
||||||
|
VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), deviceNumber, i + 1, maxIops);
|
||||||
|
s_logger.debug(LogUtils.logGsonWithoutException("The following definitions will be used to start the VM: virtual device [%s], volume [%s].", device, volumeTO));
|
||||||
|
|
||||||
diskStoragePolicyId = volumeTO.getvSphereStoragePolicyId();
|
diskStoragePolicyId = volumeTO.getvSphereStoragePolicyId();
|
||||||
if (StringUtils.isNotEmpty(diskStoragePolicyId)) {
|
if (StringUtils.isNotEmpty(diskStoragePolicyId)) {
|
||||||
|
|||||||
@ -50,8 +50,8 @@ import org.apache.cloudstack.storage.command.ResignatureAnswer;
|
|||||||
import org.apache.cloudstack.storage.command.ResignatureCommand;
|
import org.apache.cloudstack.storage.command.ResignatureCommand;
|
||||||
import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
|
import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
|
||||||
import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
|
import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
|
||||||
import org.apache.cloudstack.storage.command.SyncVolumePathCommand;
|
|
||||||
import org.apache.cloudstack.storage.command.SyncVolumePathAnswer;
|
import org.apache.cloudstack.storage.command.SyncVolumePathAnswer;
|
||||||
|
import org.apache.cloudstack.storage.command.SyncVolumePathCommand;
|
||||||
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
|
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
|
||||||
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
||||||
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
||||||
@ -97,6 +97,7 @@ import com.cloud.storage.StorageLayer;
|
|||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.template.OVAProcessor;
|
import com.cloud.storage.template.OVAProcessor;
|
||||||
import com.cloud.template.TemplateManager;
|
import com.cloud.template.TemplateManager;
|
||||||
|
import com.cloud.utils.LogUtils;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.Ternary;
|
import com.cloud.utils.Ternary;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
@ -2128,7 +2129,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||||||
diskController = vmMo.getRecommendedDiskController(null);
|
diskController = vmMo.getRecommendedDiskController(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController, storagePolicyId);
|
vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController, storagePolicyId, volumeTO.getIopsReadRate() + volumeTO.getIopsWriteRate());
|
||||||
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
|
||||||
VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumePath, dsMo.getName());
|
VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumePath, dsMo.getName());
|
||||||
chainInfo = _gson.toJson(diskInfo);
|
chainInfo = _gson.toJson(diskInfo);
|
||||||
@ -2409,7 +2410,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Answer createVolume(CreateObjectCommand cmd) {
|
public Answer createVolume(CreateObjectCommand cmd) {
|
||||||
|
s_logger.debug(LogUtils.logGsonWithoutException("Executing CreateObjectCommand cmd: [%s].", cmd));
|
||||||
VolumeObjectTO volume = (VolumeObjectTO)cmd.getData();
|
VolumeObjectTO volume = (VolumeObjectTO)cmd.getData();
|
||||||
DataStoreTO primaryStore = volume.getDataStore();
|
DataStoreTO primaryStore = volume.getDataStore();
|
||||||
String vSphereStoragePolicyId = volume.getvSphereStoragePolicyId();
|
String vSphereStoragePolicyId = volume.getvSphereStoragePolicyId();
|
||||||
|
|||||||
@ -20,8 +20,10 @@
|
|||||||
package com.cloud.utils;
|
package com.cloud.utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.log4j.Appender;
|
import org.apache.log4j.Appender;
|
||||||
@ -29,8 +31,11 @@ import org.apache.log4j.FileAppender;
|
|||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.apache.log4j.xml.DOMConfigurator;
|
import org.apache.log4j.xml.DOMConfigurator;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
public class LogUtils {
|
public class LogUtils {
|
||||||
public static final Logger LOGGER = Logger.getLogger(LogUtils.class);
|
public static final Logger LOGGER = Logger.getLogger(LogUtils.class);
|
||||||
|
private static final Gson GSON = new Gson();
|
||||||
|
|
||||||
private static String configFileLocation = null;
|
private static String configFileLocation = null;
|
||||||
|
|
||||||
@ -72,4 +77,23 @@ public class LogUtils {
|
|||||||
}
|
}
|
||||||
return fileNames;
|
return fileNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String logGsonWithoutException(String formatMessage, Object ... objects) {
|
||||||
|
List<String> gsons = new ArrayList<>();
|
||||||
|
for (Object object : objects) {
|
||||||
|
try {
|
||||||
|
gsons.add(GSON.toJson(object));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.debug(String.format("Failed to log object [%s] using GSON.", object != null ? object.getClass().getSimpleName() : "null"));
|
||||||
|
gsons.add("error to decode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return String.format(formatMessage, gsons.toArray());
|
||||||
|
} catch (Exception e) {
|
||||||
|
String errorMsg = String.format("Failed to log objects using GSON due to: [%s].", e.getMessage());
|
||||||
|
LOGGER.error(errorMsg, e);
|
||||||
|
return errorMsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
39
utils/src/test/java/com/cloud/utils/LogUtilsTest.java
Normal file
39
utils/src/test/java/com/cloud/utils/LogUtilsTest.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// 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.utils;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class LogUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void logGsonWithoutExceptionTestLogCorrectlyPrimitives() {
|
||||||
|
String expected = "test primitives: int [1], double [1.11], float [1.2222], boolean [true], null [], char [\"c\"].";
|
||||||
|
String log = LogUtils.logGsonWithoutException("test primitives: int [%s], double [%s], float [%s], boolean [%s], null [%s], char [%s].",
|
||||||
|
1, 1.11d, 1.2222f, true, null, 'c');
|
||||||
|
assertEquals(expected, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void logGsonWithoutExceptionTestPassWrongNumberOfArgs() {
|
||||||
|
String expected = "Failed to log objects using GSON due to: [Format specifier '%s'].";
|
||||||
|
String result = LogUtils.logGsonWithoutException("teste wrong [%s] %s args.", "blablabla");
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -69,6 +69,7 @@ import com.vmware.vim25.VirtualMachineConfigSpec;
|
|||||||
import com.vmware.vim25.VirtualNicManagerNetConfig;
|
import com.vmware.vim25.VirtualNicManagerNetConfig;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||||
|
import com.cloud.utils.LogUtils;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
|
|
||||||
public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
||||||
@ -643,6 +644,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
@Override
|
@Override
|
||||||
public boolean createVm(VirtualMachineConfigSpec vmSpec) throws Exception {
|
public boolean createVm(VirtualMachineConfigSpec vmSpec) throws Exception {
|
||||||
assert (vmSpec != null);
|
assert (vmSpec != null);
|
||||||
|
s_logger.debug(LogUtils.logGsonWithoutException("Creating VM with configuration: [%s].", vmSpec));
|
||||||
DatacenterMO dcMo = new DatacenterMO(_context, getHyperHostDatacenter());
|
DatacenterMO dcMo = new DatacenterMO(_context, getHyperHostDatacenter());
|
||||||
ManagedObjectReference morPool = getHyperHostOwnerResourcePool();
|
ManagedObjectReference morPool = getHyperHostOwnerResourcePool();
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,7 @@ import com.cloud.network.Networks.BroadcastDomainType;
|
|||||||
import com.cloud.offering.NetworkOffering;
|
import com.cloud.offering.NetworkOffering;
|
||||||
import com.cloud.storage.Storage.StoragePoolType;
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
import com.cloud.utils.ActionDelegate;
|
import com.cloud.utils.ActionDelegate;
|
||||||
|
import com.cloud.utils.LogUtils;
|
||||||
import com.cloud.utils.NumbersUtil;
|
import com.cloud.utils.NumbersUtil;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
|
import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
|
||||||
@ -1622,6 +1623,7 @@ public class HypervisorHostHelper {
|
|||||||
DatacenterMO dataCenterMo = new DatacenterMO(host.getContext(), host.getHyperHostDatacenter());
|
DatacenterMO dataCenterMo = new DatacenterMO(host.getContext(), host.getHyperHostDatacenter());
|
||||||
setVMHardwareVersion(vmConfig, clusterMo, dataCenterMo);
|
setVMHardwareVersion(vmConfig, clusterMo, dataCenterMo);
|
||||||
|
|
||||||
|
s_logger.debug(LogUtils.logGsonWithoutException("Creating blank VM with configuration [%s].", vmConfig));
|
||||||
if (host.createVm(vmConfig)) {
|
if (host.createVm(vmConfig)) {
|
||||||
// Here, when attempting to find the VM, we need to use the name
|
// Here, when attempting to find the VM, we need to use the name
|
||||||
// with which we created it. This is the only such place where
|
// with which we created it. This is the only such place where
|
||||||
@ -2128,7 +2130,7 @@ public class HypervisorHostHelper {
|
|||||||
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||||
|
|
||||||
// Reconfigure worker VM with datadisk
|
// Reconfigure worker VM with datadisk
|
||||||
VirtualDevice device = VmwareHelper.prepareDiskDevice(workerVmMo, null, -1, disks, morDs, -1, 1);
|
VirtualDevice device = VmwareHelper.prepareDiskDevice(workerVmMo, null, -1, disks, morDs, -1, 1, null);
|
||||||
deviceConfigSpec.setDevice(device);
|
deviceConfigSpec.setDevice(device);
|
||||||
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
||||||
vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
|
vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
|
||||||
|
|||||||
@ -52,6 +52,7 @@ import com.cloud.hypervisor.vmware.mo.SnapshotDescriptor.SnapshotInfo;
|
|||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||||
import com.cloud.utils.ActionDelegate;
|
import com.cloud.utils.ActionDelegate;
|
||||||
|
import com.cloud.utils.LogUtils;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.Ternary;
|
import com.cloud.utils.Ternary;
|
||||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||||
@ -1395,7 +1396,10 @@ public class VirtualMachineMO extends BaseMO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController, String vSphereStoragePolicyId) throws Exception {
|
public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController, String vSphereStoragePolicyId) throws Exception {
|
||||||
|
attachDisk(vmdkDatastorePathChain, morDs, diskController, vSphereStoragePolicyId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController, String vSphereStoragePolicyId, Long maxIops) throws Exception {
|
||||||
if(s_logger.isTraceEnabled())
|
if(s_logger.isTraceEnabled())
|
||||||
s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: "
|
s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: "
|
||||||
+ GSON.toJson(vmdkDatastorePathChain) + ", datastore: " + morDs.getValue());
|
+ GSON.toJson(vmdkDatastorePathChain) + ", datastore: " + morDs.getValue());
|
||||||
@ -1425,7 +1429,7 @@ public class VirtualMachineMO extends BaseMO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (_mor.getValue().intern()) {
|
synchronized (_mor.getValue().intern()) {
|
||||||
VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, controllerKey, vmdkDatastorePathChain, morDs, unitNumber, 1);
|
VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, controllerKey, vmdkDatastorePathChain, morDs, unitNumber, 1, maxIops);
|
||||||
if (StringUtils.isNotBlank(diskController)) {
|
if (StringUtils.isNotBlank(diskController)) {
|
||||||
String vmdkFileName = vmdkDatastorePathChain[0];
|
String vmdkFileName = vmdkDatastorePathChain[0];
|
||||||
updateVmdkAdapter(vmdkFileName, diskController);
|
updateVmdkAdapter(vmdkFileName, diskController);
|
||||||
@ -2086,7 +2090,7 @@ public class VirtualMachineMO extends BaseMO {
|
|||||||
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
|
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
|
||||||
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||||
|
|
||||||
VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, null, -1, disks, morDs, -1, 1);
|
VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, null, -1, disks, morDs, -1, 1, null);
|
||||||
|
|
||||||
deviceConfigSpec.setDevice(device);
|
deviceConfigSpec.setDevice(device);
|
||||||
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
|
||||||
@ -2120,6 +2124,7 @@ public class VirtualMachineMO extends BaseMO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void plugDevice(VirtualDevice device) throws Exception {
|
public void plugDevice(VirtualDevice device) throws Exception {
|
||||||
|
s_logger.debug(LogUtils.logGsonWithoutException("Pluging device [%s] to VM [%s].", device, getVmName()));
|
||||||
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
|
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
|
||||||
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
|
||||||
deviceConfigSpec.setDevice(device);
|
deviceConfigSpec.setDevice(device);
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import com.cloud.hypervisor.vmware.mo.LicenseAssignmentManagerMO;
|
|||||||
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
|
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
|
||||||
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
|
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
|
||||||
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
|
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
|
||||||
|
import com.cloud.utils.LogUtils;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.Ternary;
|
import com.cloud.utils.Ternary;
|
||||||
import com.cloud.utils.exception.ExceptionUtil;
|
import com.cloud.utils.exception.ExceptionUtil;
|
||||||
@ -61,6 +62,7 @@ import com.vmware.vim25.OptionValue;
|
|||||||
import com.vmware.vim25.PerfCounterInfo;
|
import com.vmware.vim25.PerfCounterInfo;
|
||||||
import com.vmware.vim25.PerfMetricId;
|
import com.vmware.vim25.PerfMetricId;
|
||||||
import com.vmware.vim25.ResourceAllocationInfo;
|
import com.vmware.vim25.ResourceAllocationInfo;
|
||||||
|
import com.vmware.vim25.StorageIOAllocationInfo;
|
||||||
import com.vmware.vim25.VirtualCdrom;
|
import com.vmware.vim25.VirtualCdrom;
|
||||||
import com.vmware.vim25.VirtualCdromIsoBackingInfo;
|
import com.vmware.vim25.VirtualCdromIsoBackingInfo;
|
||||||
import com.vmware.vim25.VirtualCdromRemotePassthroughBackingInfo;
|
import com.vmware.vim25.VirtualCdromRemotePassthroughBackingInfo;
|
||||||
@ -87,7 +89,6 @@ import com.vmware.vim25.VirtualVmxnet2;
|
|||||||
import com.vmware.vim25.VirtualVmxnet3;
|
import com.vmware.vim25.VirtualVmxnet3;
|
||||||
|
|
||||||
public class VmwareHelper {
|
public class VmwareHelper {
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private static final Logger s_logger = Logger.getLogger(VmwareHelper.class);
|
private static final Logger s_logger = Logger.getLogger(VmwareHelper.class);
|
||||||
|
|
||||||
public static final int MAX_SCSI_CONTROLLER_COUNT = 4;
|
public static final int MAX_SCSI_CONTROLLER_COUNT = 4;
|
||||||
@ -141,7 +142,6 @@ public class VmwareHelper {
|
|||||||
|
|
||||||
public static VirtualDevice prepareNicOpaque(VirtualMachineMO vmMo, VirtualEthernetCardType deviceType, String portGroupName,
|
public static VirtualDevice prepareNicOpaque(VirtualMachineMO vmMo, VirtualEthernetCardType deviceType, String portGroupName,
|
||||||
String macAddress, int contextNumber, boolean connected, boolean connectOnStart) throws Exception {
|
String macAddress, int contextNumber, boolean connected, boolean connectOnStart) throws Exception {
|
||||||
|
|
||||||
assert(vmMo.getRunningHost().hasOpaqueNSXNetwork());
|
assert(vmMo.getRunningHost().hasOpaqueNSXNetwork());
|
||||||
|
|
||||||
VirtualEthernetCard nic = createVirtualEthernetCard(deviceType);
|
VirtualEthernetCard nic = createVirtualEthernetCard(deviceType);
|
||||||
@ -215,8 +215,10 @@ public class VmwareHelper {
|
|||||||
|
|
||||||
// vmdkDatastorePath: [datastore name] vmdkFilePath
|
// vmdkDatastorePath: [datastore name] vmdkFilePath
|
||||||
public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[],
|
public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[],
|
||||||
ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception {
|
ManagedObjectReference morDs, int deviceNumber, int contextNumber, Long maxIops) throws Exception {
|
||||||
|
s_logger.debug(LogUtils.logGsonWithoutException("Trying to prepare disk device to virtual machine [%s], using the following details: Virtual device [%s], "
|
||||||
|
+ "ManagedObjectReference [%s], ControllerKey [%s], VMDK path chain [%s], DeviceNumber [%s], ContextNumber [%s] and max IOPS [%s].",
|
||||||
|
vmMo, device, morDs, controllerKey, vmdkDatastorePathChain, deviceNumber, contextNumber, maxIops));
|
||||||
assert (vmdkDatastorePathChain != null);
|
assert (vmdkDatastorePathChain != null);
|
||||||
assert (vmdkDatastorePathChain.length >= 1);
|
assert (vmdkDatastorePathChain.length >= 1);
|
||||||
|
|
||||||
@ -243,6 +245,13 @@ public class VmwareHelper {
|
|||||||
disk.setKey(-contextNumber);
|
disk.setKey(-contextNumber);
|
||||||
disk.setUnitNumber(deviceNumber);
|
disk.setUnitNumber(deviceNumber);
|
||||||
|
|
||||||
|
if (maxIops != null && maxIops > 0) {
|
||||||
|
s_logger.debug(LogUtils.logGsonWithoutException("Defining [%s] as the max IOPS of disk [%s].", maxIops, disk));
|
||||||
|
StorageIOAllocationInfo storageIOAllocationInfo = new StorageIOAllocationInfo();
|
||||||
|
storageIOAllocationInfo.setLimit(maxIops);
|
||||||
|
disk.setStorageIOAllocation(storageIOAllocationInfo);
|
||||||
|
}
|
||||||
|
|
||||||
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
|
VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
|
||||||
connectInfo.setConnected(true);
|
connectInfo.setConnected(true);
|
||||||
connectInfo.setStartConnected(true);
|
connectInfo.setStartConnected(true);
|
||||||
@ -255,6 +264,9 @@ public class VmwareHelper {
|
|||||||
setParentBackingInfo(backingInfo, morDs, parentDisks);
|
setParentBackingInfo(backingInfo, morDs, parentDisks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s_logger.debug(LogUtils.logGsonWithoutException("Prepared disk device, to attach to virtual machine [%s], has the following details: Virtual device [%s], "
|
||||||
|
+ "ManagedObjectReference [%s], ControllerKey [%s], VMDK path chain [%s], DeviceNumber [%s], ContextNumber [%s] and max IOPS [%s], is: [%s].",
|
||||||
|
vmMo, device, morDs, controllerKey, vmdkDatastorePathChain, deviceNumber, contextNumber, maxIops, disk));
|
||||||
return disk;
|
return disk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,5 +762,4 @@ public class VmwareHelper {
|
|||||||
}
|
}
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
// 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.vmware.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
|
||||||
|
import com.vmware.vim25.VirtualDisk;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class VmwareHelperTest {
|
||||||
|
@Mock
|
||||||
|
private VirtualMachineMO virtualMachineMO;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void prepareDiskDeviceTestNotLimitingIOPS() throws Exception {
|
||||||
|
Mockito.when(virtualMachineMO.getIDEDeviceControllerKey()).thenReturn(1);
|
||||||
|
VirtualDisk virtualDisk = (VirtualDisk) VmwareHelper.prepareDiskDevice(virtualMachineMO, null, -1, new String[1], null, 0, 0, null);
|
||||||
|
assertEquals(null, virtualDisk.getStorageIOAllocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void prepareDiskDeviceTestLimitingIOPS() throws Exception {
|
||||||
|
Mockito.when(virtualMachineMO.getIDEDeviceControllerKey()).thenReturn(1);
|
||||||
|
VirtualDisk virtualDisk = (VirtualDisk) VmwareHelper.prepareDiskDevice(virtualMachineMO, null, -1, new String[1], null, 0, 0, Long.valueOf(1000));
|
||||||
|
assertEquals(Long.valueOf(1000), virtualDisk.getStorageIOAllocation().getLimit());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void prepareDiskDeviceTestLimitingIOPSToZero() throws Exception {
|
||||||
|
Mockito.when(virtualMachineMO.getIDEDeviceControllerKey()).thenReturn(1);
|
||||||
|
VirtualDisk virtualDisk = (VirtualDisk) VmwareHelper.prepareDiskDevice(virtualMachineMO, null, -1, new String[1], null, 0, 0, Long.valueOf(0));
|
||||||
|
assertEquals(null, virtualDisk.getStorageIOAllocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user