Scripting Impacts of Embedded vCLS VMs having no Datastores
search cancel

Scripting Impacts of Embedded vCLS VMs having no Datastores

book

Article ID: 370225

calendar_today

Updated On:

Products

VMware vSphere ESX 8.x VMware vCenter Server 8.0

Issue/Introduction

Embedded vCLS VMs (introduced in 8.0 U3) have no datastores. This change impacts scripts that assume all VMs have at least one datastore. This article explains the reasons for committing the change, the risks to scripts that assume a VM's datastore list is non-empty, some signs of such a script, and some practices when working with VirtualMachine objects in VMODL to avoid hitting this issue.

Historically, VMs have always had at least one datastore. Even if one was somehow able to run without any disks, it would still need a place to have its VMX files stored. Based on this assumption, despite an empty list being a valid data state, some scripts might be written to access vm.datastore[0] or vm.layout.disk[2000] unconditionally when generically-inspecting VMs. Depending on the language being used, this could result in an exception, crash, or invalid memory access. Alternatively, a script might expect the VM's config directory to be present in the VM's layout or be accessible in the datastore browser, and could get confused by an Embedded vCLS VM not honoring that assumption.

Environment

vCenter Server 8.0 U3

ESXi 8.0 U3

Cause

Embedded vCLS is packaged with ESX as a static container image and uses a ramdisk for its VM configuration files. These VMs do not need to take up any space on inventory datastores, which reduces the setup work needed by admins and lessens the impact that these VMs have on the overall inventory. However, this also means that examining the VM will show that it has an empty datastore list. From an API perspective, an empty datastore list is still considered valid data. There is a general expectation that code operating on a list can handle it being empty. However, there are no historical cases where this list was actually empty, and callers may not be prepared for such a condition.

Resolution

Checking for this issue preemptively is recommended prior to upgrading to vSphere 8.0 Update 3.

Code that arbitrarily links a VM to a single datastore is most at risk. It should always contain a check for the list being empty and act accordingly. Consider this PyVmomi example where some basic info about a VM is printed.

# Issue hit.
def dumpVmInfoUnsafe(vm):
    print("VM Name:", vm.name)
    print("Datastore:", vm.datastore[0]) # IndexError
 
# Issue avoided.
def dumpVmInfoSafe(vm):
    print("VM Name:", vm.name)
    print("Datastore:", vm.datastore[0] if vm.datastore else None) # OK

Code that iterates over a VM's datastore list is likely safe since iteration in most languages can safely handle an empty list. The surrounding code should avoid assuming that the iteration loop was entered at least once. Consider this PyVmomi example where the VM's datastores are used to compute a value that needs to be zero-checked.

# Issue hit.
def dumpVmInfoUnsafe(vm):
    print("VM Name:", vm.name)
    totalFree = 0
    totalCapacity = 0
    for ds in vm.datastore:
        totalFree += ds.summary.freeSpace
        totalCapacity += ds.summary.capacity
    avgFree = totalFree / totalCapacity # ZeroDivisionError
    print("Avg free space percentage:", avgFree * 100.0)
 
# Issue avoided.
def dumpVmInfoSafe(vm):
    print("VM Name:", vm.name)
    totalFree = 0
    totalCapacity = 0
    for ds in vm.datastore:
        totalFree += ds.summary.freeSpace
        totalCapacity += ds.summary.capacity
    avgFree = (totalFree / totalCapacity) if totalCapacity else 1.0 # OK
    print("Avg free space percentage:", avgFree * 100.0)

Script code should also be able to tolerate a VM's file list being unassociated with a datastore, and therefore not accessible to a datastore browser.