如何使用Python脚本在ESXi环境中克隆VM?

时间:2019-05-02 18:24:56

标签: python vmware vmware-workstation esxi

我有一个python脚本,可将选定的VM克隆到模板。

当我在Git Bash中运行脚本时:

python clone_vm.py -s my-ip -u root -p my-password -v clonedVM --template VM1

我没有收到任何错误,它仅输出有关克隆VM的消息。

正在克隆VM ...

模板:VM1

新VM名称:clonedVM

完成。

但实际上它不会在ESXi服务器中克隆VM。

有帮助吗?

import atexit
import argparse
import getpass
from pyVmomi import vim
from pyVim.connect import SmartConnect, SmartConnectNoSSL, Disconnect

def get_args():
    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', '--vm-name',
                required=True,
                action='store',
                help='Name of the VM you wish to make')

    parser.add_argument('--template',
                required=True,
                action='store',
                help='Name of the template/VM \
                    you are cloning from')

    parser.add_argument('--datacenter-name',
                required=False,
                action='store',
                default=None,
                help='Name of the Datacenter you\
                    wish to use. If omitted, the first\
                    datacenter will be used.')

    parser.add_argument('--vm-folder',
                required=False,
                action='store',
                default=None,
                help='Name of the VMFolder you wish\
                    the VM to be dumped in. If left blank\
                    The datacenter VM folder will be used')

    parser.add_argument('--datastore-name',
                required=False,
                action='store',
                default=None,
                help='Datastore you wish the VM to end up on\
                    If left blank, VM will be put on the same \
                    datastore as the template')

    parser.add_argument('--cluster-name',
                required=False,
                action='store',
                default=None,
                help='Name of the cluster you wish the VM to\
                    end up on. If left blank the first cluster found\
                    will be used')

    parser.add_argument('--resource-pool',
                required=False,
                action='store',
                default=None,
                help='Resource Pool to use. If left blank the first\
                    resource pool found will be used')

    parser.add_argument('--power-on',
                dest='power_on',
                required=False,
                action='store_true',
                help='power on the VM after creation')

    parser.add_argument('--no-power-on',
                dest='power_on',
                required=False,
                action='store_false',
                help='do not power on the VM after creation')

    parser.set_defaults(power_on=True)

    args = parser.parse_args()

    if not args.password:
        args.password = getpass.getpass(
            prompt='Enter password')
    return args

def wait_for_task(task):
    task_done = False
    while not task_done:
        if task.info.state == 'success':
            task_done = True
            return task.info.result
        if task.info.state == 'error':
            print ("there was an error")

def get_obj(content, vimtype, name):
    """
    Return an object by name, if name is None the
    first found object is returned
    """
    obj = None
    container = content.viewManager.CreateContainerView(
        content.rootFolder, vimtype, True)
    for c in container.view:
        if name:
            if c.name == name:
                obj = c
                break
        else:
            obj = c
            break

    return obj

def clone_vm(
        content, template, vm_name, si,
        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 = get_obj(content, [vim.Datacenter], datacenter_name)
    if vm_folder:
        destfolder = get_obj(content, [vim.Folder], vm_folder)
    else:
        destfolder = datacenter.vmFolder
    if datastore_name:
        datastore = get_obj(content, [vim.Datastore], datastore_name)
    else:
        datastore = get_obj(
            content, [vim.Datastore], template.datastore[0].info.name)
    cluster = get_obj(content, [vim.ClusterComputeResource], cluster_name)
    if resource_pool:
        resource_pool = get_obj(content, [vim.ResourcePool], resource_pool)
    else:
        resource_pool = cluster.resourcePool

    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)

def main():
    args = get_args()

# connect this thing
si = None

if args.no_ssl:
si = SmartConnectNoSSL(
host=args.host,
user=args.user,
pwd=args.password,
port=args.port)
else:
si = SmartConnect(
host=args.host,
user=args.user,
pwd=args.password,
port=args.port)
# disconnect this thing
atexit.register(Disconnect, si)

content = si.RetrieveContent()
template = None

template = get_obj(content, [vim.VirtualMachine], args.template)

if template:
clone_vm(
content, template, args.vm_name, si,
args.datacenter_name, args.vm_folder,
args.datastore_name, args.cluster_name,
args.resource_pool, args.power_on, args.datastorecluster_name)

if args.opaque_network:
vm = get_obj(content, [vim.VirtualMachine], args.vm_name)
add_nic(si, vm, args.opaque_network)
else:
print("template not found")

# start this thing
if __name__ == "__main__":
main()

0 个答案:

没有答案