Bug 1218528 - Update vm cluster via JAVA/Python SDK raise exception
Summary: Update vm cluster via JAVA/Python SDK raise exception
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: ovirt-engine
Classification: oVirt
Component: RestAPI
Version: ---
Hardware: x86_64
OS: Linux
unspecified
medium vote
Target Milestone: ovirt-4.0.1
: ---
Assignee: Doron Fediuck
QA Contact: Artyom
URL:
Whiteboard:
: 1158458 (view as bug list)
Depends On:
Blocks: rhev35rcblocker rhev35gablocker
TreeView+ depends on / blocked
 
Reported: 2015-05-05 08:08 UTC by Artyom
Modified: 2016-07-19 06:23 UTC (History)
15 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2016-07-19 06:23:38 UTC
oVirt Team: SLA
rule-engine: ovirt-4.0.z+
rule-engine: planning_ack+
rule-engine: devel_ack+
rule-engine: testing_ack+


Attachments (Terms of Use)

Description Artyom 2015-05-05 08:08:59 UTC
Description of problem:
Update vm cluster via JAVA SDK raise exception:
Exception in thread "main" 
code  : 400
reason: Bad Request
detail: Cannot edit VM. CPU Profile doesn't match provided Cluster.
	at org.ovirt.engine.sdk.web.HttpProxy.execute(HttpProxy.java:120)
	at org.ovirt.engine.sdk.web.HttpProxyBroker.update(HttpProxyBroker.java:104)
	at org.ovirt.engine.sdk.decorators.VM.update(VM.java:423)
	at Main.main(Main.java:20)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)


Version-Release number of selected component (if applicable):
rhevm-sdk-java-3.5.2.1-1.el6ev.noarch
rhevm-3.5.1-0.4.el6ev.noarch

How reproducible:
Always

Steps to Reproduce:
1. Create new cluster
2. Change vm cluster from old one to new one:
public static void main(String[] args) throws Exception {
        Api api = new Api(URL, "admin@internal", "1", true);
        List<VM> vms = api.getVMs().list();
        VM vm = api.getVMs().get("test");
        vm.setCluster(api.getClusters().get("cl_test"));
        vm.update();
3.

Actual results:
Vm cluster updated but show exception:
Exception in thread "main" 
code  : 400
reason: Bad Request
detail: Cannot edit VM. CPU Profile doesn't match provided Cluster.
	at org.ovirt.engine.sdk.web.HttpProxy.execute(HttpProxy.java:120)
	at org.ovirt.engine.sdk.web.HttpProxyBroker.update(HttpProxyBroker.java:104)
	at org.ovirt.engine.sdk.decorators.VM.update(VM.java:423)
	at Main.main(Main.java:20)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)


Expected results:
Vm cluster updated without any exception

Additional info:
It happen only via java_sdk, via other api no exception appear

Comment 1 Juan Hernández 2015-05-05 09:12:21 UTC
This is an error on the server, not on the SDK, it happens with the Python SDK as well, for example with the following script:

---8<---
#!/usr/bin/python

from ovirtsdk import api
from ovirtsdk.xml import params

api = api.API(
    url="https://engine.example.com/ovirt-engine/api",
    username="admin@internal",
    password="******",
    insecure=True

)

vm = api.vms.get(name="myvm")
cluster = api.clusters.get(name="mycluster")
vm.set_cluster(cluster)
vm.update()

api.disconnect()
--->8---

When the SDK does this the result is that the complete VM representation will be sent to the server, including all its details not just the modified ones. In particular the SDK will send the reference to the new cluster and the reference to the old CPU profile:

  PUT /ovirt-engine/api/vms/{vm:id}
  <vm>
    <cluster id="the_id_of_the_new_cluster"/>
    <cpu_profile id="the_id_of_the_old_profile"/>
    <!-- All the other attributes of the VM. -->
  </vm>

When this arrives to the server the RESTAPI performs the update in two steps. First it checks if the given cluster reference is different to the old one, and in that case it uses the "ChangeVMCluster" command to update it. Then tries to update the rest of the attributes of the VM using the "UpdateVm" command. This command will check for validity of the update, and will see that the current cluster of the VM (previously updated) doesn't match the CPU profile, thus it will fail.

Note that even if the operation seems to fail completely it will actually succeed, because the update of the cluster has already been performed.

To fix this issue the RESTAPI should be changed so that it only uses one command to perform the update, the "UpdateVm" command. That command should receive the cluster identifier and should perform the update correctly.

Meanwhile, the issue can be avoided by clearing the "cpu_profile" field of the VM before sending the update:

  VM vm = api.getVMs().get("myvm");
  vm.setCluster(cluster);
  vm.setCpuProfile(null);
  vm.update();

Comment 3 Roy Golan 2015-05-11 10:53:23 UTC

*** This bug has been marked as a duplicate of bug 1158458 ***

Comment 4 Artyom 2015-05-11 12:07:54 UTC
By my opinion here a little different story, because action "update vm cluster" success, but anyway it show 400 error(and write that Cannot edit VM), again I think it must drop cpu profile to default one(for cluster), without any errors.

Comment 5 Ilanit Stein 2015-05-18 14:34:23 UTC
Scott,

What's your view please, on cluster specific setting which will be lost, when moving to another cluster?

Comment 6 Scott Herold 2015-06-02 14:51:02 UTC
Roy,

Is there a way to provide a default value of null to the setCpuProfile value, while still maintaining backwards compatibility in the SDK so users don't have to know to code around this when not using REST?

Comment 7 Roy Golan 2015-06-04 08:54:36 UTC
If you have only 1 profile then passing null will choose that for you.

If you got more, what will we choose, better QoS or lower. 

All cluster specific details have similar limitation (pin to hosts etc.)


buttom line we didn't supply backward compatibility and we  force the user to pick a profile. we don't want profile-less users, no?


I think the way to achieve backward compatibility is to deduce the default profile by our own:
1. either we calculate which profile has the lowest (for cpu the lowerst percentage)
2. or an admin could "label" a profile as default - a new checkbox 

Thoughts?

Comment 8 Doron Fediuck 2015-06-22 14:25:01 UTC
(In reply to Roy Golan from comment #7)
> 
> I think the way to achieve backward compatibility is to deduce the default
> profile by our own:
> 1. either we calculate which profile has the lowest (for cpu the lowerst
> percentage)
> 2. or an admin could "label" a profile as default - a new checkbox 
> 

The 2nd option seems to be more reasonable, although it requires modification
in profile management- the ability to tag a profile as a default one using the
UI and REST API.
A default profile should be created during fresh install or upgrade (if not exists), and the admin can change the default profile later on.

Comment 9 Roy Golan 2015-08-18 09:40:17 UTC
*** Bug 1158458 has been marked as a duplicate of this bug. ***

Comment 10 Sandro Bonazzola 2015-10-26 12:42:39 UTC
this is an automated message. oVirt 3.6.0 RC3 has been released and GA is targeted to next week, Nov 4th 2015.
Please review this bug and if not a blocker, please postpone to a later release.
All bugs not postponed on GA release will be automatically re-targeted to

- 3.6.1 if severity >= high
- 4.0 if severity < high

Comment 11 Sandro Bonazzola 2016-05-02 10:00:10 UTC
Moving from 4.0 alpha to 4.0 beta since 4.0 alpha has been already released and bug is not ON_QA.

Comment 12 Yaniv Lavi 2016-05-23 13:16:30 UTC
oVirt 4.0 beta has been released, moving to RC milestone.

Comment 13 Yaniv Lavi 2016-05-23 13:20:27 UTC
oVirt 4.0 beta has been released, moving to RC milestone.

Comment 14 Roy Golan 2016-06-21 13:47:49 UTC
This was handled already in 3.6 life-cycle by by choosing default profile creation per cluster, Bug 1262293

Comment 15 Artyom 2016-06-21 14:24:45 UTC
Verified on python-ovirt-engine-sdk4-4.0.0-0.0.a3.el7ev.x86_64

1) Create two clusters(cluster_1 and cluster_2)
2) Create VM test_1 on cluster_1
Update VM test_1 cluster to cluster_2 via python SDK
from ovirtsdk.xml import params
from ovirtsdk.api import API

api = API(
    ...
)
vm = api.vms.get(name="test_1")
cluster = api.clusters.get(name="cluster_2")
vm.set_cluster(cluster)
vm.update()
api.disconnect()

no any errors in debug mode
< HTTP/1.1 200 OK
< Date: Tue, 21 Jun 2016 13:38:03 GMT
< Server: Apache/2.4.6 (Red Hat Enterprise Linux) OpenSSL/1.0.1e-fips
< Content-Type: application/xml
< Content-Length: 13332
< Vary: Accept-Encoding

Comment 16 Sandro Bonazzola 2016-07-19 06:23:38 UTC
Since the problem described in this bug report should be
resolved in oVirt 4.0.1 released on July 19th 2016, it has been closed with a
resolution of CURRENT RELEASE.

For information on the release, and how to update to this release, follow the link below.

If the solution does not work for you, open a new bug report.

http://www.ovirt.org/release/4.0.1/


Note You need to log in before you can comment on or make changes to this bug.