Category Archives: vSphere API

posts on vSphere API/SDK samples/scripts

vSphere 6.7: What is per-VM EVC and How to configure & manage it using pyVmomi?

Enhanced vMotion Compatibility (EVC) is without a doubt has been one of the famous vSphere features. As you know already,  EVC is a cluster level feature, which makes it possible to have vMotion across different generations of CPU within the cluster.  vSphere 6.7 has taken EVC to the next level.  This latest release has introduced one of cool features around EVC i.e. per-VM EVC.  Recently I got an opportunity to explore this cool feature and I thought to share my learning with you. In this blog post, I will take a through below items around per-VM EVC.

  • What is per-VM EVC?
  • Notes on per-VM EVC
  • per-VM EVC UI workflow
  • Configuring per-VM EVC using pyVmomi
  • Playing around featureMask using pyVmomi
  • Disabling per-VM EVC using pyVmomi
What is per-VM EVC?

As name indicates, per -VM EVC can be enabled on individual VM. Great thing about per VM EVC is that, it not only works on VMs inside the cluster but also VMs outside of the cluster.  Unlike cluster level EVC, this feature enables vMotion across clusters, standalone hosts, cross vCenters & hybrid clouds such as VMware cloud on AWS (from on-prem vCenter). How cool is that?

Notes on per-VM EVC
  • User needs to have vSphere 6.7
  • VM hardware version must be vmx-14
  • User must powered off the VM before configuring per-VM EVC
  • If user is enabling per -VM EVC on a VM, which is inside EVC enabled cluster, EVC mode on the VM should be equal or lower than that of EVC mode configured on cluster.
  • If  user wants to enable this feature from UI, only vSphere H5 client  supports it and not the flex based client.
  • per-VM EVC works fine with vSphere DRS
  • If user clones per-VM EVC configured VM, it will retain per-VM EVC configuration on cloned VM.
  • If underlying host does not support EVC mode configured on VM, VM can not power ON
  • User can enable per-VM EVC on a VM though VM is already part of a EVC enabled cluster.
per-VM EVC UI workflow

If you ask me, it is pretty easy to configure per-VM EVC from vSphere H5 client (flex client does not support). User just needs to click on the VM >> Configure >> VMware EVC >>Edit >> Configure EVC mode of your choice (of course EVC mode supported by underlying host/Cluster). Please take a look at below H5 client screenshots.

Per VM EVC UI configuration workflow

I configured “Intel ivy-bridge” EVC mode and below is how it looks like post configuration.

per VM EVC UI post configuration
Configuring per-VM EVC using pyVmomi

vSphere 6.7 has exposed a vSphere API to configure per-VM EVC i.e. ApplyEvcModeVM_Task(). We need to pass right “featureMask” to this API in order to configure appropriate EVC mode on the VM. Note that every EVC mode defines its own set of featureMask. Ex. intel-sandybridge EVC mode will have corresponding set of featureMask, so is for intel-ivybridge and so on..

Since we need to pass “featureMask” for particular EVC mode, first important thing user needs to get hold of is right EVC mode. Once we get hold of right EVC mode, we need to get corresponding  “featureMask”.  In our case, lets configure per-VM EVC on a VM residing  on a standalone host.  As I said, first we need to find max EVC mode supported on the host. This can be easily found using the script I discussed in my blog post here (Refer section on “Getting max EVCMode key“). It can be quickly found from vSphere web client or H5 client host summary as well. In my case, my host “max EVCMode”was “intel-haswell”. It does mean that I can enable per-VM EVC with featureMask for either “intel-haswell” EVC mode or lower EVCMode such as “intel-ivybridge” , “intel-sandybridge” etc.  I chose to enable per-VM EVC on “intel-ivybridge” EVC mode.

Now that we have finalized EVC mode i.e. intel-ivybridge, we now need to get hold of corresponding “featureMask”. Please take a look at below code snippet.

[python]
si= SmartConnect(host=args.host, user=args.user, pwd=args.password, sslContext=s)
supported_evc_mode=si.capability.supportedEVCMode
for evc_mode in supported_evc_mode:
if(evc_mode.key == "intel-ivybridge"):
ivy_mask=evc_mode.featureMask
break
[/python]

If you take a look above snippet, it is fairly easy to get featuremask for particular EVC Mode.

putting it together

This script is available on my github-repo here

[python]
# Author: Vikas Shitole
# Website: www.vThinkBeyondVM.com
# Product: vCenter server/ per-VM EVC (Enhanced Compatibility Mode)
# Description: Script to get enbale/disable per-VM EVC on VM
# Reference:
# How to setup pyVmomi environment?:
# On linux: https://vthinkbeyondvm.com/how-did-i-get-started-with-the-vsphere-python-sdk-pyvmomi-on-ubuntu-distro/
# On windows: https://vthinkbeyondvm.com/getting-started-with-pyvmomi-on-windows-supports-vsphere-6-7/

from pyVim.connect import SmartConnect
import ssl
from pyVmomi import vim
import atexit
import sys
import argparse
import getpass

def get_args():
""" Get arguments from CLI """
parser = argparse.ArgumentParser(
description=’Arguments for talking to vCenter’)

parser.add_argument(‘-s’, ‘–host’,
required=True,
action=’store’,
help=’vSpehre service to connect to’)

parser.add_argument(‘-o’, ‘–port’,
type=int,
default=443,
action=’store’,
help=’Port to connect on’)

parser.add_argument(‘-u’, ‘–user’,
required=True,
action=’store’,
help=’Username to use’)

parser.add_argument(‘-p’, ‘–password’,
required=False,
action=’store’,
help=’Password to use’)

parser.add_argument(‘-v’, ‘–vmname’,
required=True,
action=’store’,
default=None,
help=’Name of the VM to be configured per VM EVC’)

args = parser.parse_args()

if not args.password:
args.password = getpass.getpass(
prompt=’Enter vCenter password:’)

return args

# Below method helps us to get MOR of the object (vim type) that we passed.
def get_obj(content, vimtype, name):
obj = None
container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
for c in container.view:
if name and c.name == name:
obj = c
break
container.Destroy()
return obj

args = get_args()
s=ssl.SSLContext(ssl.PROTOCOL_SSLv23) # For VC 6.5/6.0 s=ssl.SSLContext(ssl.PROTOCOL_TLSv1)
s.verify_mode=ssl.CERT_NONE

si= SmartConnect(host=args.host, user=args.user, pwd=args.password, sslContext=s)
content=si.content
vm= get_obj(content, [vim.VirtualMachine],args.vmname)

if(vm and vm.capability.perVmEvcSupported):
print ("VM available in vCenter server and it supports perVm EVC, thats good")
else:
print ("VM either NOT found or perVMEvc is NOT supported on the VM")
quit()

supported_evc_mode=si.capability.supportedEVCMode
for evc_mode in supported_evc_mode:
if(evc_mode.key == "intel-ivybridge"):
ivy_mask=evc_mode.featureMask
break

vm.ApplyEvcModeVM_Task(ivy_mask,True)
print ("ApplyEvcModeVM_Task() API is invoked, check out your H5 client")
[/python]

Line #80: This confirms whether VM found or not and it also confirms whether VM supports per-VM EVC or not.
#86-90: It is about getting right featureMask corresponding to particular EVC Mode.
#92: Finally we called the API “ApplyEvcModeVM_Task()”

How to run this script
“python perVMEVCNew.py -s 10.161.81.159 -u Administrator@vsphere.local -v DRSPerVMEVC”, user needs to enter vCenter password. Below is how it looks like.

I looked into vSphere H5 client and this is how it looks like. isn’t it cool?

Playing with featureMask

In line #86, we learned how to get hold of featureMask. is it the only way we can get featureMask and pass it to this API? Answer is NO. There are multiple ways. However, I recommend to follow the way I did on line #86 above.
Sometime you may want to configure per-VM EVC with the same featureMask as that of EVC enabled cluster.  This can be handy specially for the VMs those are outside of the EVC cluster. In such case, you can simply copy the featureMask from EVC cluster and pass it to the per-VM EVC API. Let us take look at below code snippet.

[python]
#Cluster object
cluster = get_obj(content,[vim.ClusterComputeResource], args.cluster)

if(cluster):
print ("Cluster available in vCenter server, thats good")
else:
print ("Cluster is NOT available in vCenter server, please enter correct name")
quit()

evc_cluster_manager=cluster.EvcManager()

evc_state=evc_cluster_manager.evcState
current_evcmode_key= evc_state.currentEVCModeKey

if(current_evcmode_key):
print ("Current EVC Mode::"+current_evcmode_key)
else:
print ("EVC is NOT enabled on the cluster")
quit()
features_masked = evc_state.featureMask
[/python]

Above EVC API property I had already discussed in my post on cluster level EVC APIs here (Refer: section #4 : Exploring EVC Cluster state). Here is the complete script, where featureMask is copied from EVC cluster. In addition, you can also choose to copy the featureMask from already per-VM EVC configured VM but if you do not document it properly, it can lead to confusion in future, hence it is always better to follow one way consistently to avoid any issues in future.

Disabling per-VM EVC

If you ask me, it is pretty easy. We just need to invoke the same API but without any featureMask as follows

[python]

vm.ApplyEvcModeVM_Task(None,True)

[/python]

Some useful resources on EVC

1. Part-1: Managing EVC using pyVmomi
2. Part 2: Managing EVC using pyVmomi
3. Tutorial on getting started pyVmomi  on linux
4. Tutorial on getting started pyVmomi on Windows

I hope you enjoyed this post, let me know if you have any questions/doubts.