[ovirt-users] Unexpected behaviour during creating VM using oVirt API

Juan Hernández jhernand at redhat.com
Sun Nov 20 15:25:47 UTC 2016


On 10/07/2016 08:59 PM, Roman Chukov wrote:
> Hello, 
> 
> I am trying to create a virtual machine from a template using oVirt
> API. Somehow like this:
> 
> ---
> def createVM(connection, cluster, vmname, vmtemplate):
>         try:
>                  param = params.VM( name=vmname, \
>                  cluster=connection.clusters.get(name=cluster), \
>                  template=connection.templates.get(name=vmtemplate), \
>                  use_latest_template_version = True ) 
>         except: 
> 		print "Could not construct a request to oVirtapi,please check parameters which were being sent to" 
> 		return None
> 
>         try:
>                 connection.vms.add(param)
>         except:
>                 print "I was not able to commit my request into oVirt api."
>                 return None
>         return "OK"
> ---
> 
> Everything is fine when I have only ONE version of a template. But I am 
> used to create several number of versions for one template because it
> is quite flexible. In this case, when I run my script, I receive an
> "AmbiguousQueryError" error even if an option
> "use_latest_template_version = True" is used.
> 
> I revised
> file  /usr/lib/python2.7/site-packages/ovirtsdk/utils/filterhelper.py
> and found near line 30 that this error is raised unquestionably:
> 
> --
> if len(result) > 1:
> 	raise AmbiguousQueryError(query)
> return result[0] if result else None
> --
> 
> It seems quite strange. Either I do not understand the meaning of
> option "use_latest_template_version" or using of this option does not
> make sense, I mean query constructed in params.VM() function will not
> be passed by filterhelper.py in current implementation.
> I made a small patch that allows me to use the latest
> version of the template during VM creation:
> 
> --
> if len(result) > 1 :
> 	result = result[len(result) - 1]
> 	return result
> 	#raise AmbiguousQueryError(query)
> return result[0] if result else Nonepython-2.7.5-34.el7.x86_64
> --
> But I am still not sure that original behaviour of filehelper.py is
> unexpectable. I would be very pleasant if you explain me this issue.
> 
> My OS is CentOS 7. I use Python python-2.7.5-34.el7.x86_64. Version of
> ovirt-engine-sdk is ovirt-engine-sdk-python-3.6.8.0-1.el7.centos.noarch
> 

The reason for this is that you are searching all the templates that
have a given name, and when a template has multiple versions each
version appears, in the API, as a separate template. So you actually
have multiple templates with the same name.

To avoid that, instead using "connection.templates.get(name=...)" you
can use "connection.templates.list(query="name=%s" % ...)". That will
give you all the versions of the template. You can just get the firs,
or, if you need a specific version, then you can look for it explicitly:

  template = None
  for candidate in connection.templates.list(query="name=mytemplate"):
    if candidate.get_version().get_template_name() == 'myversion':
      template = candidate
      break

Then you can explicitly use that template:

  connection.vms.add(
    params.VM(
      name="newvm",
      cluster=params.Cluster(
        id="mycluster",
      ),
      template=params.Template(
        id=template.get_id(),
      ),
      use_latest_template_version=True,
    )
  )

Note that it is good practice to always create a new instance of
params.Cluster and params.Template when sending a request like this,
that way you make sure that you are only sending to the server the
required data, in this case the cluster name and the template id. The
way you are doing it now is sending the complete representation of the
cluster and template, which is bad for performance.

However, in your case, as you already know the name and the cluster and
the name of the VM, it is easier to send the request like this, without
searching the cluster or template before:

  connect.vms.add(
    params.VM(
      name="myvm",
      cluster=params.Cluster(
        name="mycluster",
      ),
      template=params.Template(
        name="mytemplate",
      ),
      use_latest_template_version=True,
    ),
  )

I take the opportunity to remind you that you are using version 3 of the
API and version 3 of the API. Those will be retired staring with versoin
4.2 of oVirt. If you are already using version 4.0 or newer of oVirt
consider using versoin 4 of the API and version 4 of the SDK. You have
documentation and examples here:

  https://github.com/oVirt/ovirt-engine-sdk/tree/master/sdk
  https://github.com/oVirt/ovirt-engine-sdk/tree/master/sdk/examples

-- 
Dirección Comercial: C/Jose Bardasano Baos, 9, Edif. Gorbea 3, planta
3ºD, 28016 Madrid, Spain
Inscrita en el Reg. Mercantil de Madrid – C.I.F. B82657941 - Red Hat S.L.



More information about the Users mailing list