Open abhi29 opened 9 years ago
This is a popular request. I've had limited bandwidth to write this sample and would appreciate someone picking this up. Reply here for any takers, otherwise I'll put this on my back log.
Hi Shawn,
Can you please provide some sample script which can load ova image stored in datacenter and deploy ovf template , I'm working on this but unable to do.
thanks, Abhishek
On Thu, Jan 29, 2015 at 7:37 PM, Shawn Hartsock notifications@github.com wrote:
This is a popular request. I've had limited bandwidth to write this sample and would appreciate someone picking this up. Reply here for any takers, otherwise I'll put this on my back log.
— Reply to this email directly or view it on GitHub https://github.com/vmware/pyvmomi-community-samples/issues/151#issuecomment-72029914 .
Hi, Has this been completed? Is there some way to do it using vim.OvfManager.CreateImportSpecParams?
@rashrag we've not had someone contribute a version of this OVF deployment tutorial for this project. Considering that a blog post with detailed instructions exists, this should be one of the easier samples for someone to write.
I'll attempt it :)
@pathcl cool! :-)
Hi @pathcl, were you able to complete this by any chance ?
@pathcl & @prashasthip the bar on samples is "can Shawn make it work?" ... so just be sure to submit it with sufficient comments that by reading the python script we get an idea of how to do things. Thanks.
So finally anybody did it @hartsock ?
@hartsock - I'll take this up too.
@hartsock - how do I use CreateImportSpecParams to specify the destination folder where I want the deployed ovf to be placed ?
@prashasthip you need to specify folder location in import api,
resource_pool.ImportVApp(import_spec.importSpec, folder=datacenter.vmFolder, host=host)
Thanks @asonar !
I would like to deploy OVA file on ESXI too ... need this urgently. Option is to go with powercli - which is a windows only option that does not really work for me. If anyone has a solution, please post it. Thanks.
@hartsock can you share source code or link how you did deploy ovf template using pyvomi?
@vaghani unfortunately that's part of a package that hasn't been open sourced yet. I do intend on taking that code through the fling process for official release someday but it's been years.
A quick non-working clipping of the code that I hopefully won't get into trouble for sharing looks like this:
class VirtualMachineDeployer(object):
def deploy_ova(self, ova_file, vm_name=None, datastore_name=None, accept_all=True):
# deal with archive data format here, then call down to actual deployment method
out = False
ova_tar = tarfile.open(ova_file, 'r')
if ova_tar is not None:
ovf = None
members = []
total_size = 0
for member in ova_tar.getmembers():
logging.debug("Reading OVA member {}".format(member.name))
total_size += member.size
if str(member.name).endswith('.ovf'):
f = ova_tar.extractfile(member)
content = f.read()
# TODO: by convention OVF files are encoded in utf-8 ... this might not always be true
ovf = ovf_transcoder(content)
f.close()
else:
f = ova_tar.extractfile(member)
members.append(TarFileMemberReader(member, f, "uploading "))
out = self._deploy(TarEnvelope(ovf, members), vm_name, datastore_name, accept_all, total_size)
ova_tar.close()
return out
def _deploy(self, env, vm_name, datastore_name, accept_all=True, total_size=None):
self._read_bits = 0
if datastore_name is not None:
self.datastore = datastore_name
else:
raise ValueError("A datastore must be specified!")
lease = None
with self.connection as si:
manager = si.content.ovfManager
datastore = si.datastore(datastore_name)
data_center = si.data_center(self.data_center)
resource_pools = si.find_all_by_type(vim.ResourcePool)
if len(resource_pools) == 0:
raise EnvironmentError("Could not find a default resource pool!")
resource_pool = resource_pools[0]
host_systems = si.find_all_by_type(vim.HostSystem)
if len(host_systems) == 0:
raise EnvironmentError("Could not find a host system on host!")
host_system = host_systems[0]
if si.virtual_machine(vm_name):
logging.error("Virtual Machine named {} already exists!".format(vm_name))
return False
disk_provisioning = vim.OvfManager.CreateImportSpecParams.DiskProvisioningType.thin
spec_params = vim.OvfManager.CreateImportSpecParams(entityName=vm_name,
diskProvisioning=disk_provisioning,
hostSystem=host_system)
ovf_str = env.ovf
if six.PY2:
ovf_str = _pyvmomi_translate(env.ovf.decode('utf-8'))
result = manager.CreateImportSpec(ovf_str, resource_pool, datastore, spec_params)
# build first layer of lookup tables for file transfers
self._import_file_mapping(result)
lease = resource_pool.ImportVApp(result.importSpec,
data_center.vmFolder,
host_system)
# build second layer of lookup tables for file transfers
self.wait_on_lease(lease)
self._lease_device_mapping(lease)
self._read_bits = 0
for member_reader in env.members:
if lease.error:
logging.error(lease.error)
url = self._nfc_url(member_reader.name)
if url is not None:
if str(url).startswith('https://*/'):
path = str(url)[len('https://*/'):]
url = 'https://{host}/{path}'.format(
host=self.connection.host, path=path)
logging.debug("Cleaned URL is: {}".format(url))
member_reader.start(
call_back=lambda: lease.HttpNfcLeaseProgress(
member_reader.percentage()
)
)
content_type = None
if str(member_reader.name).endswith('.vmdk'):
content_type = 'application/x-vnd.vmware-streamVmdk'
logging.info("Starting upload {url} host time is {time} ...".format(
time=si.CurrentTime(), url=url))
lease.HttpNfcLeaseProgress(0)
self.file_manager.upload_nfc(url, member_reader, False, content_type)
lease.HttpNfcLeaseProgress(100)
logging.info("Finished upload {url} host time is {time} ...".format(
time=si.CurrentTime(), url=url))
member_reader.finish()
else:
logging.debug("No upload URL for OVA file member {} skipping file!".format(member_reader.name))
if lease.error:
logging.error(lease.error)
if lease is not None:
lease.HttpNfcLeaseComplete()
# presume things worked if we get this far TODO: actual troubleshooting logic
return True
... there's some problematic transcoding happening in there in these helpers ...
def _pyvmomi_translate(contents):
"""translates out the problematic unicode EULA quotes found in VMware EULA
only a problem for Python 2.x, you don't need this for Python 3.x"""
# This is a hacky work-around for a pyvmomi on python 2.7 problem that does
# not happen on python 3.x becuase python 3 handles internationalization much
# better than python 2.x does due to string data encoding improvements.
return contents.replace(
u'\u2018', '\''
).replace(
u'\u2019', '\''
).replace(
u'\u201c', "\""
).replace(
u'\u201d', "\""
)
# noinspection PyCompatibility
def ovf_transcoder(content, codec='utf-8'):
# unfortunately, this is one of those places where a weaker type system
# causes big problems. The content object may be of multiple data types
# which we will need to detect and handle differently in different
# python runtimes. This is made harder by trying to maintain such a
# wide spread in runtime-compatibilities.
if isinstance(content, str):
return str(content)
if six.PY3:
return str(content.decode(codec))
if six.PY2:
temp = _pyvmomi_translate(content.decode(codec))
return temp.encode('ascii', 'ignore')
... note that there's use of unreleased python enhancements for example si.virtual_machine(vm_name)
is an enhancement to normal pyVmomi I wrote in pyvmomi-tools which adds a "find VM by name" feature to pyVmomi's normal si
But, if you keep in mind there's a lot of helpers you should be able to read that and get the general idea how to not only deploy a VM but also update the vCenter task progress bar as you do it.
How to deploy ovf template using pyvmomi..