[Engine-devel] Hot-plug of disks and nics

On the subject of activate/deactivate disks and nics ("hot-plug"), I'd like to hear opinions about the correct modelling. I see two possible options (I will use disks as an example, but the chosen modelling should be the same for nics and disks). Option 1 - update: ================= PUT .../api/vms/{vm:id}/disks/{disk:id} <disk> <activated>true</activated> </disk> Pros: ----- * RESTful, no need for new action Cons: ----- * Inconsistent with other flows. We do not normally update status fields to perform actions. For example to run a VM, we do not update it's status to 'activated', we run an action (start). * Enables user to update disk properties AND activate/deactivate in the same operation. Updating certain disk properties is forbidden while the VM is up, but activating/deactivating the disk is allowed always. This requires business-logic in REST-API: if the user activates the disk and changes properties on it - REST-API must first change the properties and then activate the disk (if disk is activated first, update properties will fail). If, on the other hand, the user *deactivates* the disk and changes properties on it - REST-API must first deactivate the disk and then change the properties (changing properties while disk is still active will fail). This bug-prone logic is only necessary because when activate/deactivate is merged with update. Option 2 - action ================= .../api/vms/{vm:id}/disks/{disk:id}/attach Pros: ---- * Less RESTful Cons: ----- * Consistent with other flows * Does not have the drawback of the additional business-logic described above Opinions? Thanks, Ori.

----- Original Message ----- From: "Ori Liel" <oliel@redhat.com> To: engine-devel@ovirt.org Cc: meyering@redhat.com, eglynn@redhat.com, gjansen@redhat.com, jhernand@redhat.com, "Einav Cohen" <ecohen@redhat.com>, "Roy Golan" <rgolan@redhat.com>, "Michael Kublin" <mkublin@redhat.com> Sent: Wednesday, April 11, 2012 11:32:51 AM Subject: Hot-plug of disks and nics
On the subject of activate/deactivate disks and nics ("hot-plug"), I'd like to hear opinions about the correct modelling. I see two possible options (I will use disks as an example, but the chosen modelling should be the same for nics and disks).
Option 1 - update: ================= PUT .../api/vms/{vm:id}/disks/{disk:id} <disk> <activated>true</activated> </disk>
Pros: ----- * RESTful, no need for new action
Cons: ----- * Inconsistent with other flows. We do not normally update status fields to perform actions. For example to run a VM, we do not update it's status to 'activated', we run an action (start). * Enables user to update disk properties AND activate/deactivate in the same operation. Updating certain disk properties is forbidden while the VM is up, but activating/deactivating the disk is allowed always. This requires business-logic in REST-API: if the user activates the disk and changes properties on it - REST-API must first change the properties and then activate the disk (if disk is activated first, update properties will fail). If, on the other hand, the user *deactivates* the disk and changes properties on it - REST-API must first deactivate the disk and then change the properties (changing properties while disk is still active will fail). This bug-prone logic is only necessary because when activate/deactivate is merged with update.
Option 2 - action =================
.../api/vms/{vm:id}/disks/{disk:id}/attach
Minor correction, I meant .../api/vms/{vm:id}/disks/{disk:id}/activate (not .../attach)
Pros: ---- * Less RESTful
Cons: ----- * Consistent with other flows * Does not have the drawback of the additional business-logic described above
Opinions?
Thanks,
Ori.

* Inconsistent with other flows. We do not normally update status fields to perform actions. For example to run a VM, we do not update it's status to 'activated', we run an action (start).
I think this point is the crux of the matter. IMO the consistency between activation implemented as direct state manipulation versus the state change occurring as a side-effect of an action, would be a deal-breaker. IIRC one of the reasons we avoided that kind of direct state manipulation first time round is that it doesn't lend itself to multi-state transitions, e.g. activation that traversed multiple intermediate states, say: quiescent->pending->activating->activated That example is a bit contrived and unrealistic, but in any case the principal is that the client-visible state machine for a resource may not necessarily transition directly from the initial to the terminal state. Also an action as opposed to a direct state manipulation makes it more natural to express side-effects of the activation, and to implement in-progress status querying or cancelation. For those reasons, I'm thinking that using actions consistently accross the board is better than exposing an action in one case while allowing a direct state manipulation in another. So my vote would be for option #2. Cheers, Eoghan

On 04/11/2012 11:02 AM, Eoghan Glynn wrote:
* Inconsistent with other flows. We do not normally update status fields to perform actions. For example to run a VM, we do not update it's status to 'activated', we run an action (start).
I think this point is the crux of the matter.
IMO the consistency between activation implemented as direct state manipulation versus the state change occurring as a side-effect of an action, would be a deal-breaker.
IIRC one of the reasons we avoided that kind of direct state manipulation first time round is that it doesn't lend itself to multi-state transitions, e.g. activation that traversed multiple intermediate states, say:
quiescent->pending->activating->activated
That example is a bit contrived and unrealistic, but in any case the principal is that the client-visible state machine for a resource may not necessarily transition directly from the initial to the terminal state.
Exactly. The target state is not always indicative of the exact state transition path. A simpler example is "power off" vs "shutdown". Both end up with a VM in the "down" state, but the two are actually quite different.
Also an action as opposed to a direct state manipulation makes it more natural to express side-effects of the activation, and to implement in-progress status querying or cancelation.
For those reasons, I'm thinking that using actions consistently accross the board is better than exposing an action in one case while allowing a direct state manipulation in another.
So my vote would be for option #2.
One question though (probably to Ori): from the API that you propose, i assume that disk hotplug is implemented as a two stage process in the backend? - add the disk to a VM - activate it Because if it's just a one stage process then that would change things. Then you'd probably want to activate it directly as part of the POST call that adds the disk. As an action name i think "hotplug" and "unplug" are slightly more descriptive of what you actually mean. So my vote would go for those names instead. Regards, Geert

Ori Liel wrote:
On the subject of activate/deactivate disks and nics ("hot-plug"), I'd like to hear opinions about the correct modelling. I see two possible options (I will use disks as an example, but the chosen modelling should be the same for nics and disks).
Option 1 - update: ================= PUT .../api/vms/{vm:id}/disks/{disk:id} <disk> <activated>true</activated> </disk>
Pros: ----- * RESTful, no need for new action
Cons: ----- * Inconsistent with other flows. We do not normally update status fields to perform actions. For example to run a VM, we do not update it's status to 'activated', we run an action (start). * Enables user to update disk properties AND activate/deactivate in the same operation. Updating certain disk properties is forbidden while the VM is up, but activating/deactivating the disk is allowed always. This requires business-logic in REST-API: if the user activates the disk and changes properties on it - REST-API must first change the properties and then activate the disk (if disk is activated first, update properties will fail). If, on the other hand, the user *deactivates* the disk and changes properties on it - REST-API must first deactivate the disk and then change the properties (changing properties while disk is still active will fail). This bug-prone logic is only necessary because when activate/deactivate is merged with update.
Option 2 - action =================
.../api/vms/{vm:id}/disks/{disk:id}/[activate]
[Con]: ---- * Less RESTful
[Pros]: ----- * Consistent with other flows * Does not have the drawback of the additional business-logic described above
I too prefer #2. IMHO, we need not be slaves to consistency or RESTfulness, but here, consistency wins hands down when strict conformance to REST guidelines evokes a paragraph worth of "Cons".

----- Original Message ----- From: "Jim Meyering" <meyering@redhat.com> To: "Ori Liel" <oliel@redhat.com> Cc: engine-devel@ovirt.org, eglynn@redhat.com, gjansen@redhat.com, jhernand@redhat.com, "Einav Cohen" <ecohen@redhat.com>, "Roy Golan" <rgolan@redhat.com>, "Michael Kublin" <mkublin@redhat.com> Sent: Wednesday, April 11, 2012 1:00:47 PM Subject: Re: Hot-plug of disks and nics
Ori Liel wrote:
On the subject of activate/deactivate disks and nics ("hot-plug"), I'd like to hear opinions about the correct modelling. I see two possible options (I will use disks as an example, but the chosen modelling should be the same for nics and disks).
Option 1 - update: ================= PUT .../api/vms/{vm:id}/disks/{disk:id} <disk> <activated>true</activated> </disk>
Pros: ----- * RESTful, no need for new action
Cons: ----- * Inconsistent with other flows. We do not normally update status fields to perform actions. For example to run a VM, we do not update it's status to 'activated', we run an action (start). * Enables user to update disk properties AND activate/deactivate in the same operation. Updating certain disk properties is forbidden while the VM is up, but activating/deactivating the disk is allowed always. This requires business-logic in REST-API: if the user activates the disk and changes properties on it - REST-API must first change the properties and then activate the disk (if disk is activated first, update properties will fail). If, on the other hand, the user *deactivates* the disk and changes properties on it - REST-API must first deactivate the disk and then change the properties (changing properties while disk is still active will fail). This bug-prone logic is only necessary because when activate/deactivate is merged with update.
Option 2 - action =================
.../api/vms/{vm:id}/disks/{disk:id}/[activate]
[Con]: ---- * Less RESTful
[Pros]: ----- * Consistent with other flows * Does not have the drawback of the additional business-logic described above
I too prefer #2. IMHO, we need not be slaves to consistency or RESTfulness, but here, consistency wins hands down when strict conformance to REST guidelines evokes a paragraph worth of "Cons".
#2 it is then. Thanks Jim, Eoghan
participants (4)
-
Eoghan Glynn
-
Geert Jansen
-
Jim Meyering
-
Ori Liel