前言
VMware
,一个优秀的虚拟化平台。其拥有优秀的 Api
和稳定的性能,其也拥有完善的 SDK
,但是官方的 SDK
并不好用,今天我们就用简单的例子来认识一款简单好用的 VMware
的 Python
库,它就是 pyVmomi
。
环境准备
pyVmomi
支持 Python3
,我们在 Python3
的环境上直接安装 pyVmomi
即可。
pip install pyvmomi
我们还需要准备 VMware
的环境信息,主要就是 vSphere
的登录 ip
,端口,用户名和密码。
呆猫
连接 vSphere 获取所有虚机
代码语言:javascript复制这个例子可以让我们了解如何通过
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)
创建虚机
代码语言:javascript复制
pyVmomi
创建虚机接口不支持定义启动盘和网卡等信息,所以需要创建完后单独进行挂载。pyVmomi
创建虚机支持定义CPU
、内存、name
、DataCenter
、DataStore
、host
信息。这个例子我们将创建一个不含启动盘和网络信息的虚机。
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全栈开发')
根据名称获取虚机对象
代码语言: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
去获取虚机对象的属性即可。
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
的官方文档和 pyVmomi
的 samples
。
代码中用到的
pchelper
就是从下面的github
仓库/tools/
中下载的。
参考:https://github.com/vmware/pyvmomi-community-samples/tree/master/samples