Friday, April 11, 2014

pysphere deploy VMs from vm template with customization specification


Background:
    I created a vm template in vcenter through vsphere web client. But when I deployed this vm template to a VM, then the hostname is still the old VM name, which I used it to create vm template, and the IP address is not configued. For my case, I can create and use a customized specification file in my vcenter to fix the hostname, but DHCP is not configured in my working environment, and I have to manually set static IP address for my VMs. I do not like this.

Questions:
  1. What if I want to clone and deploy vm template in an automation way?
  2. How to fix the hostname and IP address issues?
Investigation:
   To make vm template automation, I searched and found some python client libraries:
  • psphere
  • pyvisdk
  • pysphere
  • vijava
    There is a very good blog to compare above four python  ibraries, http://dunniganp.wordpress.com/2012/09/10/comparison-of-python-vmware-vsphere-client-libraries/. I truly recommend to read this.

My Solution:
    For my case, I just picked pysphere to get a solution, and I am lucky to made it.
  1. create vm template based on an existing virtual machine, vm.create_template(args).
  2. deploy vm template to VMs, vm.clone(<target vm name>,<vm resource pool>).
  3. customize hostname and assign IP address, VI.CustomizeVM_TaskRequestMsg().
Examples:
#connect with vmware server:
server=VIServer()
server.connect(<remote host>, <user>, <password>)
# Get vm object
vm_obj = server.get_vm_by_name(target_vm)
# Customize hostname and IP address
        request = VI.CustomizeVM_TaskRequestMsg()
        _this = request.new__this(vm_obj._mor)
        _this.set_attribute_type(vm_obj._mor.get_attribute_type())
        request.set_element__this(_this)
        spec = request.new_spec()
        globalIPSettings = spec.new_globalIPSettings()
        spec.set_element_globalIPSettings(globalIPSettings)
        # NIC settings, I used static ip, but it is able to set DHCP here, but I did not test it.
        nicSetting = spec.new_nicSettingMap()
        adapter = nicSetting.new_adapter()
        fixedip = VI.ns0.CustomizationFixedIp_Def("ipAddress").pyclass()
        fixedip.set_element_ipAddress(ip_address)
        adapter.set_element_ip(fixedip)
        adapter.set_element_subnetMask(netmask)
        nicSetting.set_element_adapter(adapter)
        spec.set_element_nicSettingMap([nicSetting,])
        identity = VI.ns0.CustomizationLinuxPrep_Def("identity").pyclass()
        identity.set_element_domain("domain name")
        hostName = VI.ns0.CustomizationFixedName_Def("hostName").pyclass()
        hostName.set_element_name(target_vm.replace("_", ""))
        identity.set_element_hostName(hostName)
        spec.set_element_identity(identity)
        request.set_element_spec(spec)
        task = server._proxy.CustomizeVM_Task(request)._returnval
        vi_task = VITask(task, server)
        status = vi_task.wait_for_state([vi_task.STATE_SUCCESS, vi_task.STATE_ERROR], <timeout setting>)

Hopefully, this can help people, who have the same problems.

1 comment:

  1. hi..how did you manage to set the gateway of the interface?

    ReplyDelete