前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pyVmomi操作VMware

pyVmomi操作VMware

作者头像
Python研究所
发布2022-06-17 08:20:41
1.7K0
发布2022-06-17 08:20:41
举报
文章被收录于专栏:大飞的部落阁大飞的部落阁

前言

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

环境准备

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

代码语言:javascript
复制
pip install pyvmomi

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

呆猫

连接 vSphere 获取所有虚机

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

代码语言:javascript
复制
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和电源状态
获取虚机的name和电源状态

创建虚机

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

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

代码语言:javascript
复制
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上创建成功
vSphere上创建成功

根据名称获取虚机对象

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

代码语言:javascript
复制
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 去获取虚机对象的属性即可。

代码语言:javascript
复制
VMObj = getVmbyName('Python全栈开发')
print(dir(VMObj))
常用的虚机操作
常用的虚机操作

克隆虚机

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

代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 环境准备
  • 呆猫
    • 连接 vSphere 获取所有虚机
      • 创建虚机
        • 根据名称获取虚机对象
          • 操作虚机
            • 克隆虚机
            • 总结
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档