-
Notifications
You must be signed in to change notification settings - Fork 292
CA-268511: Make PIF.disallow_unplug RO when clustering is enabled #3485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CA-268511: Make PIF.disallow_unplug RO when clustering is enabled #3485
Conversation
ocaml/idl/datamodel.ml
Outdated
Api_errors.pif_has_fcoe_sr_in_use] | ||
() | ||
|
||
let pif_set_disallow_unplug = call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to prefix this with pif_
as it's in already the PIF module - this seems to be the convention in this module.
4c6f400
to
c7cec95
Compare
; Bool, "value", "New value to set" ] | ||
~allowed_roles:_R_POOL_OP | ||
() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this allowed role is fine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that was the original role than yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've looked at the definitions of let create_obj
and let field
, and it seems that the field setter role will default to ~messages_default_allowed_roles
, if I'm not mistaken, which is this, so this is perfect.
0c98292
to
fb18629
Compare
ocaml/tests/test_clustering.ml
Outdated
let make_host_network_pif ~__context = | ||
let host = Test_common.make_host ~__context () in | ||
let network = Test_common.make_network ~__context () in | ||
let pif = Test_common.make_pif ~__context ~network ~host () in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We prefer not to align things because then we may have to change all the lines every time we add a new one.
This is one of the reasons we start list items with the semicolon: this way we only have to change one line when remove an item: http://elm-lang.org/docs/style-guide (and this also makes the diffs cleaner)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be a good addition to https://github.com/lindig/ocaml-style
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, what do you think @lindig ? I think it'd be good to mention that we shouldn't worry too much about aligning things but should keep it simple and practical, to minimise the effort when viewing diffs or changing code or rebasing.
ocaml/xapi/xapi_pif.ml
Outdated
failwith (Printf.sprintf "Could not find network of PIF: %s" (Ref.string_of self)) | ||
in | ||
info "Got network: %s" (Ref.string_of network_of_pif); | ||
(Db.Cluster.get_records_where ~__context |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use get_refs_where
here - we don't need to obtain the whole record.
ocaml/xapi/message_forwarding.ml
Outdated
info "PIF.set_disallow_unplug: PIF: %s; value = %s" (Ref.string_of self) (string_of_bool value); | ||
let host = Db.PIF.get_host ~__context ~self in | ||
let local_fn = Local.PIF.set_disallow_unplug ~self ~value in | ||
do_op_on ~local_fn ~__context ~host (fun session_id rpc -> Client.PIF.set_disallow_unplug rpc session_id self value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should not forward it but just do it locally on the master which has the DB, since we only do DB queries. (Like for vdi_set_cbt_enabled
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, if the function acts on the xapi DB only, than we should just call Local...
directly.
ocaml/xapi/xapi_pif.ml
Outdated
|
||
let set_disallow_unplug ~__context ~self ~value = | ||
assert_no_clustering_enabled ~__context ~self; | ||
if Db.PIF.get_disallow_unplug ~__context ~self <> value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this idempotency is not necessary here, as there is nothing in the other if
branch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed you don't save very much by this if-statement. In fact, the common case would be that the function takes 2 DB calls rather than just one. However, this is not such a big deal if this only runs on the master.
ocaml/xapi/xapi_pif.ml
Outdated
|
||
let assert_no_clustering_enabled ~__context ~self = | ||
if pif_has_clusters ~__context self | ||
then raise Api_errors.(Server_error(Api_errors.cannot_change_pif_properties, [Ref.string_of self])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One issue with this exception is that its description currently talks about bonded PIFs (in datamodel.ml
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's introduce a new API error that is specific to clustering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: you can remove the second mention of Api_errors.
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, well-tested - left some minor comments.
We'll have to decide about the API error we raise, that'll require another reviewer.
ocaml/xapi/xapi_pif.ml
Outdated
assert_no_clustering_enabled ~__context ~self; | ||
if Db.PIF.get_disallow_unplug ~__context ~self <> value | ||
then begin | ||
info "PIF.set_disallow_unplug: PIF: %s, value: %s" (Ref.string_of self) (string_of_bool value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove this debug line, since it's almost the same as the one in message_forwarding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also when you add a debug message it would be nice if it printed UUIDs instead of OpaqueRefs, it makes debugging easier with xe
. I've fixed that in a few places in the clustering code.
Don't fix it on this one since you're dropping it anyway, but in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's not a huge problem if we have the database dump, because then we can match UUIDs to opaquerefs. Also, in some debug messages both the UUID and ref are shown, for VDIs at least.
ocaml/xapi/xapi_pif.ml
Outdated
let pif_has_clusters ~__context (self : API.ref_PIF) = | ||
debug "Looking up clusters for PIF: %s" (Ref.string_of self); | ||
let network_of_pif = | ||
try Db.PIF.get_network ~__context ~self with _ -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If PIF has a network by construction, and will be GC'ed if the network is deleted. So this is a little overly defensive.
ocaml/xapi/xapi_pif.ml
Outdated
try Db.PIF.get_network ~__context ~self with _ -> | ||
failwith (Printf.sprintf "Could not find network of PIF: %s" (Ref.string_of self)) | ||
in | ||
info "Got network: %s" (Ref.string_of network_of_pif); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove the logging in this function. We are logging far too much already...
ocaml/xapi/xapi_pif.ml
Outdated
in | ||
info "Got network: %s" (Ref.string_of network_of_pif); | ||
(Db.Cluster.get_records_where ~__context | ||
~expr:Db_filter_types.(Eq(Literal (Ref.string_of network_of_pif),Field "network"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually works? I always see Field
first and then Literal
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments inline.
79c6aae
to
787b1a8
Compare
ocaml/xapi/message_forwarding.ml
Outdated
|
||
let set_disallow_unplug ~__context ~self ~value = | ||
let pif_uuid = Db.PIF.get_uuid ~__context ~self in | ||
info "PIF.set_disallow_unplug: PIF uuid = %s; value = %s" (pif_uuid) (string_of_bool value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use the existing pif_uuid
helper: https://github.com/xapi-project/xen-api/pull/3485/files#diff-9a639b670fb7e2432894cc91df8b27fbR3101
ocaml/xapi/xapi_pif.ml
Outdated
|
||
let set_disallow_unplug ~__context ~self ~value = | ||
if pif_has_clustering_enabled ~__context self | ||
then raise Api_errors.(Server_error(cannot_change_pif_properties, [Ref.string_of self])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we Rob said, we should introduce a new API error that is specific to clustering.
ocaml/xapi/xapi_pif.ml
Outdated
let pif_has_clustering_enabled ~__context (self : API.ref_PIF) = | ||
let network_ref = Db.PIF.get_network ~__context ~self |> Ref.string_of in | ||
(Db.Cluster.get_refs_where ~__context | ||
~expr:Db_filter_types.(Eq(Literal network_ref,Field "network"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, maybe it's safer to put Field
first and then Literal
to follow the existing conventions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I personally really like the new XenAPI error, as it's general and therefore reusable, but it's best if others also review it.
I think all the review comments have been addressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One minor comment on checking 'set disallow unplug' with false
in the tests too since that is what we actually want to prevent.
Before merging don't forget to squash the commits.
@robhoes are there further changes needed?
ocaml/tests/test_clustering.ml
Outdated
Alcotest.check_raises | ||
"check_disallow_unplug called by test_disallow_unplug_with_clustering after attaching cluster and cluster_host to network" | ||
(Api_errors.(Server_error(clustering_enabled_on_network, [Ref.string_of network]))) | ||
(fun () -> Xapi_pif.set_disallow_unplug ~__context ~self:pif ~value:true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might want to add a second check that setting disallow_unplug
to false raises as well. In the current implementation it is obvious it will, but the real goal is that we reject setting it to false.
ocaml/xapi/xapi_pif.ml
Outdated
let set_disallow_unplug ~__context ~self ~value = | ||
if pif_has_clustering_enabled ~__context self | ||
then | ||
let network_ref = Db.PIF.get_network ~__context ~self |> Ref.string_of in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already got this from the DB in the function above, so this could be optimised a little. Not a big deal though.
Just added a minor comment, but generally LGTM. |
I would like to see commits to include the CA unless the history is cleaned. |
I think all the commits could be squashed into one, it is logically one set of self-consistent changes. |
64caeac
to
18b976a
Compare
- define set_disallow_unplug as dynamicRO in datamodel - add new error for toggling disallow_unplug with clustering enabled - add assertion and manual setter - add unit tests for set_disallow_unplug with and without clustering enabled CA-268511: Declare new API error clustering_enabled_on_network CA-268511: Implement PIF.set_disallow_unplug CA-268511: Add logging to function message wrapper CA-268511: Test PIF.set_disallow_unplug for idempotency and exceptions Signed-off-by: Akanksha Mathur <akanksha.mathur@citrix.com>
18b976a
to
5252972
Compare
This PR makes the following changes:
cannot_change_pif_properties
when a cluster object is attached to the networkPIF.set_disallow_unplug
with and without clusteringQuestions for reviewers about possible changes:
PIF.network
info
ordebug
?