目 录CONTENT

文章目录

pyVmomi操作VMware

phyger
2022-02-23 / 0 评论 / 3 点赞 / 1,253 阅读 / 7,450 字 / 正在检测是否收录...

前言

VMware,一个优秀的虚拟化平台。其拥有优秀的 Api 和稳定的性能,其也拥有完善的 SDK,但是官方的 SDK 并不好用,今天我们就用简单的例子来认识一款简单好用的 VMwarePython 库,它就是 pyVmomi

环境准备

pyVmomi 支持 Python3,我们在 Python3 的环境上直接安装 pyVmomi 即可。

pip install pyvmomi

我们还需要准备 VMware 的环境信息,主要就是 vSphere 的登录 ip,端口,用户名和密码。

呆猫

连接 vSphere 获取所有虚机

这个例子可以让我们了解如何通过 pyVmomi 连接 vSphere,再通过 vim 的类型获取指定的资源。

from pyVim import connect
from pyVmomi import vim
import pchelper
from pyVim.task import WaitForTask

# 根据vim的对象类型获取对象容器,本方法获取虚机容器
def Conn(host='192.168.x.x',user='user@vsphere.local',pwd='pwd@pwd',port=443):
    # 获取链接
    vm_ins = connect.SmartConnectNoSSL(host=host,user=user,port=port,pwd=pwd)
    # 获取上下文
    content = vm_ins.RetrieveContent()
    # 获取根路径容器
    container = content.rootFolder
    # 指定vim类型
    vm_type=[vim.VirtualMachine]
    recursive = True
    # 回去容器视图,这里面装的就是所有的VirtualMachine虚机
    containerView = content.viewManager.CreateContainerView(container, vm_type, recursive)
    # 将虚机容器返回
    return containerView

if __name__=='__main__':
     ds = Conn()
     for i in ds.view:
         # 打印虚机的name和电源状态
         print(i.name,i.runtime.powerState)

获取虚机的name和电源状态

创建虚机

pyVmomi 创建虚机接口不支持定义启动盘和网卡等信息,所以需要创建完后单独进行挂载。

pyVmomi 创建虚机支持定义 CPU、内存、nameDataCenterDataStorehost 信息。

这个例子我们将创建一个不含启动盘和网络信息的虚机。

from pyVim import connect
from pyVmomi import vim
import pchelper
from pyVim.task import WaitForTask

# 获取vm的实例
def Si(host='192.168.x.x',user='user@vsphere.local',pwd='pwd@pwd',port=443):
    vm_ins = connect.SmartConnectNoSSL(host=host,user=user,port=port,pwd=pwd)
    return vm_ins

# 初始化虚机配置
def create_config_spec(datastore_name, name, memory=4, guest="otherGuest",
                       annotation="Sample", cpus=1):
    # 获取配置对象
    config = vim.vm.ConfigSpec()
    # 为配置对象增加配置
    config.annotation = annotation
    config.memoryMB = int(memory)
    config.guestId = guest
    config.name = name
    config.numCPUs = cpus
    files = vim.vm.FileInfo()
    files.vmPathName = "["+datastore_name+"]"
    config.files = files
    # 返回配置对象
    return config

# 创建虚机
def create_vm(si, vm_name, datacenter_name='Datacenter', host_ip='192.168.x.x', datastore_name='xx-LUN_SHARE01'):

    # 获取上下文
    content = si.RetrieveContent()
    destination_host = pchelper.get_obj(content, [vim.HostSystem], host_ip)
    source_pool = destination_host.parent.resourcePool
    if datastore_name is None:
        datastore_name = destination_host.datastore[0].name

    config = create_config_spec(datastore_name=datastore_name, name=vm_name)
    for child in content.rootFolder.childEntity:
        if child.name == datacenter_name:
            vm_folder = child.vmFolder  # child is a datacenter
            break
    else:
        print("Datacenter %s not found!" % datacenter_name)
        sys.exit(1)

    try:
        WaitForTask(vm_folder.CreateVm(config, pool=source_pool, host=destination_host))
        print("VM created: %s" % vm_name)
    except vim.fault.DuplicateName:
        print("VM duplicate name: %s" % vm_name, file=sys.stderr)
    except vim.fault.AlreadyExists:
        print("VM name %s already exists." % vm_name, file=sys.stderr)

if __name__=='__main__':
    create_vm(si=Si(),vm_name='Python全栈开发')

虚机创建成功

vSphere上创建成功

根据名称获取虚机对象

当我们需要对虚机进行操作的时候,我们需要获取虚机对象。这个例子就会告诉我们如何获取虚机对象。

from pyVim import connect
from pyVmomi import vim
import pchelper
from pyVim.task import WaitForTask

# 根据vim的对象类型获取对象容器,本方法获取虚机容器
def Conn(host='192.168.x.x',user='user@vsphere.local',pwd='pwd@pwd',port=443):
    # 获取链接
    vm_ins = connect.SmartConnectNoSSL(host=host,user=user,port=port,pwd=pwd)
    # 获取上下文
    content = vm_ins.RetrieveContent()
    # 获取根路径容器
    container = content.rootFolder
    # 指定vim类型
    vm_type=[vim.VirtualMachine]
    recursive = True
    # 回去容器视图,这里面装的就是所有的VirtualMachine虚机
    containerView = content.viewManager.CreateContainerView(container, vm_type, recursive)
    # 将虚机容器返回
    return containerView

# 根据名称找虚机对象
def getVmbyName(name):
    vms = Conn()
    for i in vms.view:
        if i.name == name:
            print(i,i.name)
            return i

if __name__=='__main__':
    getVmbyName('Python全栈开发')

获取到了虚机对象

拿到虚机对象后,我们就可以对虚机进行很多操作了。

操作虚机

拿到虚机对象后,我们如何操作虚机呢?我们直接 dir 去获取虚机对象的属性即可。

VMObj = getVmbyName('Python全栈开发')
print(dir(VMObj))

常用的虚机操作

克隆虚机

因为 VMware 创建虚机流程复杂,通常我们会采用克隆的方式来创建虚机,然后再对虚机进行配置以达到创建虚机的效果。

from pyVim import connect
from pyVmomi import vim
import pchelper
from pyVim.task import WaitForTask

# 根据vim的对象类型获取对象容器,本方法获取虚机容器
def Conn(host='192.168.x.x',user='user@vsphere.local',pwd='pwd@pwd',port=443):
    # 获取链接
    vm_ins = connect.SmartConnectNoSSL(host=host,user=user,port=port,pwd=pwd)
    # 获取上下文
    content = vm_ins.RetrieveContent()
    # 获取根路径容器
    container = content.rootFolder
    # 指定vim类型
    vm_type=[vim.VirtualMachine]
    recursive = True
    # 回去容器视图,这里面装的就是所有的VirtualMachine虚机
    containerView = content.viewManager.CreateContainerView(container, vm_type, recursive)
    # 将虚机容器返回
    return containerView


# 获取vm的实例
def Si(host='192.168.x.x',user='user@vsphere.local',pwd='pwd@pwd',port=443):
    vm_ins = connect.SmartConnectNoSSL(host=host,user=user,port=port,pwd=pwd)
    return vm_ins

# 根据名称找虚机对象
def getVmbyName(name):
    vms = Conn()
    for i in vms.view:
        if i.name == name:
            print(i,i.name)
            return i

# 克隆虚机
def getFloder(datacenter_name='Datacenter'):

    # 获取上下文
    content = Si().RetrieveContent()
    for child in content.rootFolder.childEntity:
        if child.name == datacenter_name:
            vm_folder = child.vmFolder  # child is a datacenter
            return vm_folder

def wait_for_task(task):
    """ wait for a vCenter task to finish """
    task_done = False
    while not task_done:
        if task.info.state == 'success':
            return task.info.result

        if task.info.state == 'error':
            print("there was an error")
            print(task.info.error)
            task_done = True


def clone_vm(
        content, template, vm_name, datacenter_name, vm_folder, datastore_name,
        cluster_name, resource_pool, power_on, datastorecluster_name):
    """
    Clone a VM from a template/VM, datacenter_name, vm_folder, datastore_name
    cluster_name, resource_pool, and power_on are all optional.
    """

    # if none git the first one
    datacenter = pchelper.get_obj(content, [vim.Datacenter], datacenter_name)

    if vm_folder:
        #destfolder = pchelper.search_for_obj(content, [vim.Folder], vm_folder)
        destfolder = datacenter.vmFolder
    else:
        destfolder = datacenter.vmFolder

    if datastore_name:
        datastore = pchelper.search_for_obj(content, [vim.Datastore], datastore_name)
    else:
        datastore = pchelper.get_obj(
            content, [vim.Datastore], template.datastore[0].info.name)

    # if None, get the first one
    cluster = pchelper.search_for_obj(content, [vim.ClusterComputeResource], cluster_name)
    if not cluster:
        clusters = pchelper.get_all_obj(content, [vim.ResourcePool])
        cluster = list(clusters)[0]

    if resource_pool:
        resource_pool = pchelper.search_for_obj(content, [vim.ResourcePool], resource_pool)
    else:
        resource_pool = cluster.resourcePool

    vmconf = vim.vm.ConfigSpec()

    if datastorecluster_name:
        podsel = vim.storageDrs.PodSelectionSpec()
        pod = pchelper.get_obj(content, [vim.StoragePod], datastorecluster_name)
        podsel.storagePod = pod

        storagespec = vim.storageDrs.StoragePlacementSpec()
        storagespec.podSelectionSpec = podsel
        storagespec.type = 'create'
        storagespec.folder = destfolder
        storagespec.resourcePool = resource_pool
        storagespec.configSpec = vmconf

        try:
            rec = content.storageResourceManager.RecommendDatastores(
                storageSpec=storagespec)
            rec_action = rec.recommendations[0].action[0]
            real_datastore_name = rec_action.destination.name
        except Exception:
            real_datastore_name = template.datastore[0].info.name

        datastore = pchelper.get_obj(content, [vim.Datastore], real_datastore_name)

    # set relospec
    relospec = vim.vm.RelocateSpec()
    relospec.datastore = datastore
    relospec.pool = resource_pool

    clonespec = vim.vm.CloneSpec()
    clonespec.location = relospec
    clonespec.powerOn = power_on

    print("cloning VM...")
    task = template.Clone(folder=destfolder, name=vm_name, spec=clonespec)
    wait_for_task(task)
    print("VM cloned.")


if __name__=='__main__':
    # 这是我们的模板,即镜像
    VMObj = getVmbyName('image_test')
    # 获取vm实例,供克隆用
    conn = Si().RetrieveContent()
    # 获取文件目录
    vm_folder=getFloder()
    # 开始克隆
    clone_vm(content=conn, template=VMObj, vm_name='newVM', datacenter_name='Datacenter', vm_folder=vm_folder, datastore_name='xx-LUN_SHARE01',cluster_name='xx_Cluster_test1', resource_pool=False, power_on=True, datastorecluster_name=None)

开始克隆

克隆完成

虚机登录

总结

以上就是 pyVmomi 的简单使用,虽然功能比较多,但是文档不完善,后续还有很大的进步空间。更多内容大家可以查看 VMware 的官方文档和 pyVmomisamples

代码中用到的 pchelper 就是从下面的 github 仓库/tools/中下载的。

参考:https://github.com/vmware/pyvmomi-community-samples/tree/master/samples

3

评论区