python3 pyVmomi 克隆虚拟机

克隆虚拟机是依赖于虚拟机模板,在虚拟机模板正常的情况下,以上代码能够完成克隆虚拟机并指定IP的操作的,那么先来说一说克隆虚拟机的坑。
  • 现象1:虚拟机克隆成功,虚拟机自动正常开机,但没有指定上网络IP。
    现象产生的原因:
    克隆使用的模板没有网络适配器
  • 现象2:虚拟机克隆成功,但是没有自动开机,并且指定网络IP也失败了,在 vSphere上还报了ident.hostName.name异常。
    现象产生的原因:
    ①虚拟机主机名:不可以用下划线等特殊字符
    ②虚拟机主机名为空
  • 现象3:虚拟机克隆成功,虚拟机自动正常开机,网络指定成功,但虚拟机网络不通,无法正常使用网络。
    现象产生的原因:
    指定的虚拟机IP和虚拟机所在的网络适配器的网络段不匹配,导致网络不通。

补充:当克隆虚拟机,没有集群,层级:数据中心–>文件夹–>主机
参考文档:https://blog.csdn.net/qq_4263...

image.png

vim 飘红可以忽略

code

# -*- coding: utf-8 -*-
import time
import traceback
import logging

from pyVim.connect import SmartConnectNoSSL, Disconnect
from pyVmomi import vim


class VmManage(object):
    def __init__(self, host, user, password, port, ssl):
        self.config = None
        self.host = host
        self.user = user
        self.pwd = password
        self.port = port
        self.sslContext = ssl
        try:
            self.client = SmartConnectNoSSL(host=host,
                                            user=user,
                                            pwd=password,
                                            port=443
                                            )
            self.content = self.client.RetrieveContent()
            self.result = True
        except Exception as e:
            self.result = e

    def _get_all_objs(self, obj_type, folder=None):
        """
        根据对象类型获取这一类型的所有对象
        """
        if folder is None:
            container = self.content.viewManager.CreateContainerView(self.content.rootFolder, obj_type, True)
        else:
            container = self.content.viewManager.CreateContainerView(folder, obj_type, True)
        return container.view

    def _get_obj(self, obj_type, name):
        obj = None
        content = self.client.RetrieveContent()
        container = content.viewManager.CreateContainerView(content.rootFolder, obj_type, True)
        for c in container.view:
            if c.name == name:
                obj = c
                break
        return obj

    def get_datacenters(self):
        """
           获取数据中心列表
        """
        return self._get_all_objs([vim.Datacenter])

    # vcenter执行动作等待
    def wait_for_task(self, task):
        """ wait for a vCenter task to finish """
        task_done = False

        while not task_done:
            print("task.....%s " % task.info.state)
            if task.info.state == 'success':
                return {'message': u'执行成功', 'status': True}

            if task.info.state == 'error':
                print("there was an error")
                return {'message': task.info.error.msg, 'status': True}

    def handleTask(self, tasks=None):
        if tasks is None:
            return False
        else:
            from pyVim.task import WaitForTasks
            try:
                WaitForTasks(tasks=tasks, si=self.client)
            except Exception as e:
                traceback.print_exc()
                print(str(e))
                return False

    def get_cluster_by_name(self, name=None, datacenter=None):
        if datacenter:
            folder = datacenter.hostFolder
        else:
            folder = self.content.rootFolder

        container = self.content.viewManager.CreateContainerView(folder, [vim.ClusterComputeResource], True)
        clusters = container.view
        for cluster in clusters:
            if cluster.name == name:
                return cluster
        return None

    def get_datastore_by_name(self, name, datacenter):
        datastores = datacenter.datastore
        for datastore in datastores:
            if datastore.name == name:
                return datastore
        return None

    def get_host_by_name(self, name, datastore):
        hosts = datastore.host
        for host in hosts:
            print("##get_host_by_name host:", host.key.summary.config.name)
            if host.key.summary.config.name == name:
                return host.key
        return None

    def get_vms_by_cluster(self, vmFolder):
        content = self.client.content
        objView = content.viewManager.CreateContainerView(vmFolder, [vim.VirtualMachine], True)
        vmList = objView.view
        objView.Destroy()
        return vmList

    def get_customspec(self, template, vm_ip=None, vm_subnetmask=None, vm_gateway=None, vm_dns=None,
                       vm_domain=None, vm_hostname=None, vm_password=None):
        """
        IP等信息的配置函数
        :param template: 模板对象
        :param vm_ip:
        :param vm_subnetmask:
        :param vm_gateway:
        :param vm_dns:
        :param vm_domain:
        :param vm_hostname:
        :return:
        """
        adaptermaps = []
        guest_map = vim.vm.customization.AdapterMapping()
        guest_map.adapter = vim.vm.customization.IPSettings()
        guest_map.adapter.ip = vim.vm.customization.FixedIp()
        guest_map.adapter.ip.ipAddress = vm_ip
        guest_map.adapter.subnetMask = vm_subnetmask
        guest_map.adapter.gateway = vm_gateway
        if vm_domain:
            guest_map.adapter.dnsDomain = vm_domain
        adaptermaps.append(guest_map)

        # DNS settings
        globalip = vim.vm.customization.GlobalIPSettings()
        if vm_dns:
            if vm_dns.find(',') > -1:
                globalip.dnsServerList = vm_dns.split(',')
            else:
                globalip.dnsServerList = [vm_dns]
            globalip.dnsSuffixList = vm_domain

        # Hostname settings
        # 如果模板是windows
        print("###check system template.config.guestId:  ", template.config.guestId)
        if 'windows' in template.config.guestId:
            print("###temp system is window")
            ident = vim.vm.customization.Sysprep()
            ident.userData = vim.vm.customization.UserData()
            ident.userData.computerName = vim.vm.customization.FixedName()
            if vm_hostname:
                ident.userData.computerName.name = vm_hostname
                ident.userData.fullName = 'Administrator'
                ident.userData.orgName = 'Administrators'

            ident.guiUnattended = vim.vm.customization.GuiUnattended()
            ident.identification = vim.vm.customization.Identification()
            password = vim.vm.customization.Password()
            password.value = vm_password if vm_password else 'root'
            # 设置密码不经过加密验证
            password.plainText = True
            ident.guiUnattended.password = password
            if vm_domain:
                ident.identification.domainAdmin = vm_domain

        else:
            print("###temp system is Linux")
            # 如果模板不是windows
            ident = vim.vm.customization.LinuxPrep()
            if vm_domain:
                ident.domain = vm_domain
            ident.hostName = vim.vm.customization.FixedName()
            if vm_hostname:
                ident.hostName.name = vm_hostname

        customspec = vim.vm.customization.Specification()
        customspec.nicSettingMap = adaptermaps
        customspec.globalIPSettings = globalip
        customspec.identity = ident
        return customspec

    def get_customspec_only_linux(self, vm_ip=None, vm_subnetmask=None, vm_gateway=None, vm_dns=None,
                                  vm_domain=None, vm_hostname=None):
        # guest NIC settings  有关dns和域名的配置错误 更改了
        adaptermaps = []

        guest_map = vim.vm.customization.AdapterMapping()
        guest_map.adapter = vim.vm.customization.IPSettings()
        guest_map.adapter.ip = vim.vm.customization.FixedIp()
        guest_map.adapter.ip.ipAddress = vm_ip
        guest_map.adapter.subnetMask = vm_subnetmask
        guest_map.adapter.gateway = vm_gateway
        if vm_domain:
            guest_map.adapter.dnsDomain = vm_domain
        adaptermaps.append(guest_map)

        # DNS settings
        globalip = vim.vm.customization.GlobalIPSettings()
        if vm_dns:
            globalip.dnsServerList = [vm_dns]
            globalip.dnsSuffixList = vm_domain

        # Hostname settings
        ident = vim.vm.customization.LinuxPrep()
        if vm_domain:
            ident.domain = vm_domain
        ident.hostName = vim.vm.customization.FixedName()
        if vm_hostname:
            ident.hostName.name = vm_hostname
        customspec = vim.vm.customization.Specification()
        customspec.nicSettingMap = adaptermaps
        customspec.globalIPSettings = globalip
        customspec.identity = ident
        return customspec

    def change_disk_size(self, vm_obj, vm_disk):
        """
        :param vm_obj:  虚拟机对象(模板对象也适用)
        :param vm_disk: 硬盘大小(单位:G)
        :return: disk_change 配置列表
        """
        virtual_disk_devices = []
        virtual_disk_device = None
        virtual_scsi_controller = None

        # Find the disk device
        for dev in vm_obj.config.hardware.device:
            if isinstance(dev, vim.vm.device.VirtualSCSIController):
                virtual_scsi_controller = dev
            if isinstance(dev, vim.vm.device.VirtualDisk):
                virtual_disk_devices.append(dev)

        for dev in virtual_disk_devices:
            if dev.controllerKey == virtual_scsi_controller.key:
                virtual_disk_device = dev

        new_disk_kb = int(vm_disk) * 1024 * 1024

        virtual_disk_spec = vim.vm.device.VirtualDeviceSpec()
        virtual_disk_spec.operation = \
            vim.vm.device.VirtualDeviceSpec.Operation.edit
        virtual_disk_spec.device = virtual_disk_device
        virtual_disk_spec.device.capacityInKB = new_disk_kb
        disk_changes = []
        disk_changes.append(virtual_disk_spec)
        return disk_changes

    def change_disk_size_to_vm(self, vm_name, disk_number, vm_disk):
        """
        :param vm_obj:  虚拟机对象(模板对象也适用)
        :param vm_disk: 硬盘大小(单位:G)
        :disk_number: 举个栗子:"Hard disk 1"
        """
        vm_obj = self._get_obj([vim.VirtualMachine], vm_name)
        disk_prefix_label = 'Hard disk '
        disk_label = disk_prefix_label + str(disk_number)
        new_disk_kb = int(vm_disk) * 1024 * 1024

        virtual_disk_devices = []
        virtual_disk_device = None
        virtual_scsi_controller = None

        # Find the disk device
        for dev in vm_obj.config.hardware.device:
            if isinstance(dev, vim.vm.device.VirtualDisk) and dev.deviceInfo.label == disk_label:
                virtual_disk_device = dev
        if not virtual_disk_device:
            raise RuntimeError('Virtual {} could not be found.'.format(disk_label))

        virtual_disk_spec = vim.vm.device.VirtualDeviceSpec()
        virtual_disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
        virtual_disk_spec.device = virtual_disk_device
        virtual_disk_spec.device.capacityInKB = new_disk_kb
        virtual_disk_spec.device.backing.diskMode = 'persistent'
        disk_changes = []
        disk_changes.append(virtual_disk_spec)
        spec = vim.vm.ConfigSpec()

        spec.deviceChange = disk_changes
        task = vm_obj.ReconfigVM_Task(spec=spec)
        result1 = self.wait_for_task(task)
        if result1['status']:
            data = {'message': u'硬盘扩容成功', 'result': True}
        else:
            data = {'message': u'硬盘扩容失败: %s' % result1['message'], 'result': False}
        return data



    def add_disk(self, vm_obj, capacity):
        spec = vim.vm.ConfigSpec()
        dev_changes = []
        # capacity 为 存储盘容量将单位改为 G
        new_disk_kb = capacity * 1024 * 1024
        unit_number = 0
        # 遍历所有的硬件设备,找合适的位置添加
        for dev in vm_obj.config.hardware.device:
            if hasattr(dev.backing, 'fileName'):
                unit_number = int(dev.unitNumber) + 1
                # unit_number 7 reserved for scsi controller
                if unit_number == 7:
                    unit_number += 1
                if unit_number >= 16:
                    logging.error('we don\'t support this many disks')
            if isinstance(dev, vim.vm.device.VirtualSCSIController):
                controller = dev

        disk_spec = vim.vm.device.VirtualDeviceSpec()
        disk_spec.fileOperation = "create"
        disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
        disk_spec.device = vim.vm.device.VirtualDisk()
        disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
        disk_spec.device.backing.thinProvisioned = True
        disk_spec.device.backing.diskMode = 'persistent'

        disk_spec.device.unitNumber = unit_number
        disk_spec.device.capacityInKB = new_disk_kb
        disk_spec.device.controllerKey = controller.key
        dev_changes.append(disk_spec)

        return dev_changes

    def add_disk_to_vm(self, vm_name, capacity):
        vm_obj = self._get_obj([vim.VirtualMachine], vm_name)
        spec = vim.vm.ConfigSpec()
        dev_changes = []
        # capacity 为 存储盘容量将单位改为 G
        new_disk_kb = capacity * 1024 * 1024
        unit_number = 0
        # 遍历所有的硬件设备,找合适的位置添加
        for dev in vm_obj.config.hardware.device:
            if hasattr(dev.backing, 'fileName'):
                unit_number = int(dev.unitNumber) + 1
                # unit_number 7 reserved for scsi controller
                if unit_number == 7:
                    unit_number += 1
                if unit_number >= 16:
                    logging.error('we don\'t support this many disks')
            if isinstance(dev, vim.vm.device.VirtualSCSIController):
                controller = dev

        disk_spec = vim.vm.device.VirtualDeviceSpec()
        disk_spec.fileOperation = "create"
        disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
        disk_spec.device = vim.vm.device.VirtualDisk()
        disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
        disk_spec.device.backing.thinProvisioned = True
        disk_spec.device.backing.diskMode = 'persistent'

        disk_spec.device.unitNumber = unit_number
        disk_spec.device.capacityInKB = new_disk_kb
        disk_spec.device.controllerKey = controller.key
        dev_changes.append(disk_spec)
        spec.deviceChange = dev_changes
        task = vm_obj.ReconfigVM_Task(spec=spec)
        result1 = self.wait_for_task(task)
        if result1['status']:
            data = {'message': u'硬盘添加成功', 'result': True}
        else:
            data = {'message': u'硬盘添加失败: %s' % result1['message'], 'result': False}
        return data

    def edit_nic(self, vm, network_name, is_vss):
        device_change = []
        data = {'message': None, 'result': False, 'code': 1}
        for device in vm.config.hardware.device:
            if isinstance(device, vim.vm.device.VirtualEthernetCard):
                nicspec = vim.vm.device.VirtualDeviceSpec()
                nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
                nicspec.device = device
                nicspec.device.wakeOnLanEnabled = True
                if is_vss:
                    nicspec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()
                    nicspec.device.backing.network = self._get_obj([vim.Network], network_name)
                    nicspec.device.backing.deviceName = network_name
                else:
                    network = self._get_obj([vim.dvs.DistributedVirtualPortgroup], network_name)
                    dvs_port_connection = vim.dvs.PortConnection()
                    dvs_port_connection.portgroupKey = network.key
                    dvs_port_connection.switchUuid = network.config.distributedVirtualSwitch.uuid
                    nicspec.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
                    nicspec.device.backing.port = dvs_port_connection
                nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
                nicspec.device.connectable.startConnected = True
                nicspec.device.connectable.allowGuestControl = True
                device_change.append(nicspec)
                nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
                nicspec.device.connectable.startConnected = True
                nicspec.device.connectable.allowGuestControl = True
                device_change.append(nicspec)
                break
        if device_change:
            config_spec = vim.vm.ConfigSpec(deviceChange=device_change)
            task = vm.ReconfigVM_Task(config_spec)
            result = self.wait_for_task(task)
            if result['status']:
                power_state = vm.runtime.powerState
                if power_state == 'poweredOn':
                    stop_task = vm.PowerOff()
                    stop_result = self.wait_for_task(stop_task)
                #     if stop_result['status']:
                #         start_task = vm.PowerOn()
                #         self.wait_for_task(start_task)
                # else:
                start_task = vm.PowerOn()
                self.wait_for_task(start_task)
                data["message"] = u'更改网络成功'
                data["result"] = True
                data["code"] = 0
            else:
                data["message"] = u'更改网络失败'
        else:
            data["message"] = u'网络适配器不存在,无法修改网络'
        return data

    def device_nic(self, vm, network_name, switch_type):
        """
        :param vm: 虚拟机模板对象
        :param network_name: 要修改的网络段名称
        :param switch_type: 网络段类型
        :return:
        """
        device_change = []
        no_vlan = False
        for device in vm.config.hardware.device:
            # 判断是否存在网络适配器
            if isinstance(device, vim.vm.device.VirtualEthernetCard):
                nicspec = vim.vm.device.VirtualDeviceSpec()
                # 一定要是vim.vm.device.VirtualDeviceSpec.Operation.edit  代表编辑
                nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit
                nicspec.device = device
                nicspec.device.wakeOnLanEnabled = True
                if switch_type == 1:
                    # 标准交换机设置
                    nicspec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()
                    nicspec.device.backing.network = self._get_obj([vim.Network], network_name)
                    nicspec.device.backing.deviceName = network_name
                else:
                    # 判断网络段是否在分组交换机网络范围
                    network = self._get_obj([vim.dvs.DistributedVirtualPortgroup], network_name)
                    if network is None:
                        logging.error(u'分组交换机没有{0}网段'.format(network_name))
                        no_vlan = True
                        break
                    # 分布式交换机设置
                    dvs_port_connection = vim.dvs.PortConnection()
                    dvs_port_connection.portgroupKey = network.key
                    dvs_port_connection.switchUuid = network.config.distributedVirtualSwitch.uuid
                    nicspec.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo()
                    nicspec.device.backing.port = dvs_port_connection
                # 网络段配置设置
                nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
                nicspec.device.connectable.startConnected = True
                nicspec.device.connectable.allowGuestControl = True
                device_change.append(nicspec)
                logging.info('网络适配器设置')
                break
        if device_change:
            return device_change
        else:
            if not no_vlan:
                logging.error(u'网络适配器不存在,无法修改网络')
        return device_change

    def get_vm_ip(self, vm_obj):
        """ 获取 VM 所有 IP 地址 """
        ips = []
        for i in vm_obj.guest.net:
            if i.network:
                for b in range(6):
                    if i.ipAddress:
                        ips.extend(i.ipAddress)
                        return ips
                    else:
                        print("VM 没有获取到IP地址等待10秒")
                        time.sleep(10)
            else:
                print('VM 未配置网卡')
        return 'VM 未获取到IP地址,请检测网络状态或者 DHCP 服务器'

    def clone_cluster(self, template_name, vm_name, datacenter_name,
                      datastore_name, cluster_name, host_name=None,
                      cup_num=None, memory=None, vm_ip=None, vm_subnetmask=None,
                      vm_gateway=None, vm_dns=None, vm_domain=None,
                      vm_hostname=None, vm_password=None):
        # 获取模版
        template = self._get_obj([vim.VirtualMachine], template_name)
        # 模版不存在
        if template is None:
            return {'message': u'克隆失败: 模版不存在', 'result': False}
        else:
            print(template.name, "模版存在hehe")
        # 选择克隆的虚拟机存放位置,通过数据中心获取对象
        datacenter = self._get_obj([vim.Datacenter], datacenter_name)
        # 数据中心不存在
        if datacenter is None:
            return {'message': u'克隆失败: 数据中心不存在', 'result': False}
        vmfolder = datacenter.vmFolder

        # 获取存储
        if datastore_name:
            datastore = self.get_datastore_by_name(datastore_name, datacenter)
            if datastore is None:
                return {'message': u'克隆失败: 该数据中心下%s存储不存在' % datastore_name, 'result': False}
            else:
                print(datastore.name, "数据中心存储存在")
        else:
            # 此处感觉需要修改
            datastore = self.get_datastore_by_name(template.datastore[0].info.name, datacenter)
            if datastore is None:
                return {'message': u'克隆失败: 该数据中心下%s模版不存在' % template_name, 'result': False}
            else:
                print(template.name, datastore, "模版存在hehe")

        # 获取集群
        cluster = self.get_cluster_by_name(cluster_name, datacenter)
        print("##cluster:", cluster)
        if cluster is None:
            print(self.get_host_by_name(host_name, datastore))
            return {'message': u'克隆失败: cluster %s no存在' % cluster, 'result': False}
        else:
            vms = self.get_vms_by_cluster(cluster)
            vms_name = [i.name for i in vms]
            if vm_name in vms_name:
                return {'message': u'克隆失败: 虚拟机%s已经存在' % vm_name, 'result': False}
            resource_pool = cluster.resourcePool
            relospec = vim.vm.RelocateSpec()
            relospec.datastore = datastore
            relospec.pool = resource_pool

            # 获取主机
            if host_name:
                host = self.get_host_by_name(host_name, datastore)
                if host is None:
                    return {'message': u'克隆失败: 该存储下%s主机不存在' % host_name, 'result': False}
                else:
                    relospec.host = host

            clonespec = vim.vm.CloneSpec()
            clonespec.location = relospec
            clonespec.powerOn = True
            # 设置cpu和内存
            if all([vm_ip, vm_subnetmask, vm_gateway, vm_domain]):
                clonespec.customization = self.get_customspec(template=template, vm_ip=vm_ip,
                                                              vm_subnetmask=vm_subnetmask, vm_gateway=vm_gateway,
                                                              vm_domain=vm_domain, vm_dns=vm_dns,
                                                              vm_hostname=vm_hostname, vm_password=vm_password)
            vmconf = vim.vm.ConfigSpec()
            if cup_num:
                vmconf.numCPUs = cup_num
            if memory:
                vmconf.memoryMB = memory
            if vmconf is not None:
                clonespec.config = vmconf
            print("cloning VM...")

            task = template.Clone(folder=vmfolder, name=vm_name, spec=clonespec)
            result = self.wait_for_task(task)
            if result['status']:
                data = {'message': u'克隆成功', 'result': True}
            else:
                data = {'message': u'克隆失败: %s' % result['message'], 'result': False}
            return data

    def clone_host(self, template_name, vm_name, datacenter_name,
                   datastore_name, vm_exi_ip, vm_vlan=None, switch_type=None, vm_folder=None,
                   cup_num=None, memory=None, vm_disk=None, vm_add_disk=None, vm_ip=None,
                   vm_subnetmask=None, vm_gateway=None, vm_dns=None,
                   vm_domain=None, vm_hostname=None, vm_password=None):
        # 获取模版
        template = self._get_obj([vim.VirtualMachine], template_name)
        # 模版不存在
        if template is None:
            return {'message': u'克隆失败: 模版不存在', 'result': False}
        # 选择克隆的虚拟机存放位置,通过数据中心获取对象
        datacenter = self._get_obj([vim.Datacenter], datacenter_name)
        # 数据中心不存在
        if datacenter is None:
            return {'message': u'克隆失败: 数据中心不存在', 'result': False}
        # vm创建路径
        if vm_folder:
            vmfolder = self._get_obj([vim.Folder], vm_folder)
        else:
            vmfolder = datacenter.vmFolder

        # 获取存储
        if datastore_name:
            datastore = self.get_datastore_by_name(datastore_name, datacenter)
            if datastore is None:
                return {'message': u'克隆失败: 该数据中心下%s存储不存在' % datastore_name, 'result': False}
        else:
            datastore = self.get_datastore_by_name(template.datastore[0].info.name, datacenter)
            if datastore is None:
                return {'message': u'克隆失败: 该数据中心下%s模版不存在' % template_name, 'result': False}
        # 获取宿主机
        host = self.get_host_by_name(vm_exi_ip, datastore)
        if host is None:
            return {'message': u'克隆失败: 该存储下%s主机不存在' % vm_exi_ip, 'result': False}
        # 获取宿主机下的vm
        vms = host.vm
        for vm in vms:
            print("##host vm:", vm)
            config = vm.summary.config
            if vm_name == config.name:
                return {'message': u'克隆失败: 虚拟机%s已经存在' % vm_name, 'result': False}
        # 获取资源池
        resourcepool = host.parent.resourcePool
        relospec = vim.vm.RelocateSpec()
        relospec.datastore = datastore
        relospec.pool = resourcepool
        relospec.host = host
        # 配置Clone属性
        clonespec = vim.vm.CloneSpec()
        clonespec.location = relospec
        clonespec.powerOn = True
        device_change = []
        # # 设置网卡
        # if len(template.network) == 0:
        #     logging.info(u'设置网卡')
        #     nic_change = self.add_nic('VM Network')
        #     device_change.extend(nic_change)
        # 指定网络段配置
        if vm_vlan:
            device_nic_change = self.device_nic(
                vm=template,
                network_name=vm_vlan,
                switch_type=switch_type
            )
            device_change.extend(device_nic_change)

        # 修改硬盘大小
        # vm_disk 必须比原来值大哦
        if vm_disk:
            logging.info(u'扩容硬盘')
            disk_change = self.change_disk_size(template, vm_disk)
            if type(disk_change) is list:
                device_change.extend(disk_change)
            else:
                return {'message': disk_change, 'result': False}

        # add_disk
        if vm_add_disk:
            logging.info(u'扩容硬盘')
            add_disk_change = self.add_disk(template, vm_add_disk)
            if type(add_disk_change) is list:
                device_change.extend(add_disk_change)
            else:
                return {'message': add_disk_change, 'result': False}

        # 更新配置
        vmconf = vim.vm.ConfigSpec(deviceChange=device_change)
        logging.info(u'更新网卡网卡的配置')
        # 设置IP
        if all([vm_ip, vm_subnetmask, vm_gateway]):
            clonespec.customization = self.get_customspec(template=template, vm_ip=vm_ip,
                                                              vm_subnetmask=vm_subnetmask, vm_gateway=vm_gateway,
                                                              vm_domain=vm_domain, vm_dns=vm_dns,
                                                              vm_hostname=vm_hostname, vm_password=vm_password)
            logging.info(u'设置IP')
        # 更改cpu和内存
        if cup_num:
            vmconf.numCPUs = cup_num
        if memory:
            vmconf.memoryMB = memory * 1024
        if vmconf is not None:
            clonespec.config = vmconf
        # 开始克隆
        task = template.Clone(folder=vmfolder, name=vm_name, spec=clonespec)

        vm_task = {
            'task': task,
            'vm_name': vm_name,
            'vm_ip': vm_ip,
            'vm_exi_ip': vm_exi_ip
        }
        data = {'message': u'任务下发成功', 'result': True, 'data': vm_task}
        return data


if __name__ == '__main__':
    ip = '10.31.1xx.4x'
    user = 'axxxxcal'
    password = 'Qxxxxx4'
    port = 443
    template_name = u'centos7temp'
    vm_name = u'centos7test60'
    data_center_name = u'Datacenter'
    datastore_name = u'datastore1'
    cluster_name = "10.31.1xx.x6"
    host_name = "10.31.1x.x6"
    cup_num = 2
    memory = 2
    resource_pool = None
    power_on = True
    vm_ext_disk = 50
    vm_add_disk = 20
    vm_ip = '10.31.1xx.x8'
    vm_subnetmask = '255.255.255.0'
    vm_gateway = '10.31.1xx.1'
    vm_dns = '8.8.8.8'
    vm_vlan = None
    switch_type = None
    vm_domain = 'xiaohxx.com'
    vm_hostname = 'test'
    vm = VmManage(host=ip, user=user, password=password, port=port, ssl=None)

    # #clone linux
    # data = vm.clone_host(template_name=template_name, vm_name=vm_name, datacenter_name=data_center_name,
    #                      datastore_name=datastore_name, vm_exi_ip=host_name, vm_vlan=None, switch_type=None,
    #                      vm_folder=None,
    #                      cup_num=4, memory=2, vm_disk=None, vm_add_disk=None, vm_ip=vm_ip,
    #                      vm_subnetmask=vm_subnetmask, vm_gateway=vm_gateway, vm_dns=vm_dns,
    #                      vm_domain=vm_domain, vm_hostname=vm_hostname, vm_password=None)

    # # win
    # data = vm.clone_host(template_name=win_template_name, vm_name=win_vm_name, datacenter_name=data_center_name,
    #                      datastore_name=datastore_name, vm_exi_ip=host_name, vm_vlan=None, switch_type=None,
    #                      vm_folder=None,
    #                      cup_num=4, memory=2, vm_disk=None, vm_add_disk=None, vm_ip=vm_ip,
    #                      vm_subnetmask=vm_subnetmask, vm_gateway=vm_gateway, vm_dns=vm_dns,
    #                      vm_domain=vm_domain, vm_hostname=vm_hostname, vm_password=win_vm_password)



    # # 给vm add 30G磁盘
    # data1 = vm.add_disk_to_vm(vm_name=vm_name, capacity=10)
    # time.sleep(8)
    # print(data1)
    # 
    # # 按磁盘num扩容
    # data = vm.change_disk_size_to_vm(vm_name=vm_name, disk_number=2, vm_disk=30)

    # # 虚拟机开机,等待x0秒,待虚拟机开机启动获取IP地址
    # vm_obj = vm._get_obj([vim.VirtualMachine], vm_name)
    # task = vm_obj.PowerOn()
    # print("启动 VM 电源")
    # print(vm.wait_for_task(task))
    # time.sleep(50)
    # print("开始获取 VM IP地址")
    # vm_obj_ip = vm.get_vm_ip(vm_obj)

    # # 虚拟机 off
    # vm_obj = vm._get_obj([vim.VirtualMachine], template_name)
    # task = vm_obj.PowerOff()
    # print("PowerOff")
    # print(vm.wait_for_task(task))
    # time.sleep(20)

    # data = vm.clone_cluster(
    #     template_name=template_name,
    #     vm_name=vm_name,
    #     datacenter_name=data_center_name,
    #     cluster_name=cluster_name,
    #     datastore_name=datastore_name,
    #     host_name=host_name,
    #     cup_num=cup_num,
    #     memory=memory,
    #     vm_ip=vm_ip,
    #     vm_subnetmask=vm_subnetmask,
    #     vm_gateway=vm_gateway,
    #     vm_dns=vm_dns,
    #     vm_domain=vm_domain,
    #     vm_hostname=vm_hostname
    # )


image.png

测试添加一块10G盘,然后扩容到30G

我给各位一个忠告,装一下 vmware tools 呦

你可能感兴趣的:(python3.xvmware)