Skip to content

Conversation

minishrink
Copy link
Contributor

@minishrink minishrink commented Mar 5, 2018

This PR makes the following changes:

  • PIF.disallow_unplug is now dynamic RO
  • PIF.set_disallow_unplug throws cannot_change_pif_properties when a cluster object is attached to the network
  • adds two tests to test_clustering to check the behaviour of PIF.set_disallow_unplug with and without clustering

Questions for reviewers about possible changes:

  • should it raise a different exception if clustering is enabled?
  • is the try-with unnecessary for getting PIF.network
  • should the logging use info or debug?

@gaborigloi gaborigloi self-requested a review March 5, 2018 10:45
Api_errors.pif_has_fcoe_sr_in_use]
()

let pif_set_disallow_unplug = call
Copy link
Contributor

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.

@minishrink minishrink force-pushed the feature/REQ477/CA-268511 branch from 4c6f400 to c7cec95 Compare March 5, 2018 10:50
; Bool, "value", "New value to set" ]
~allowed_roles:_R_POOL_OP
()

Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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.

@minishrink minishrink force-pushed the feature/REQ477/CA-268511 branch from 0c98292 to fb18629 Compare March 5, 2018 11:19
@coveralls
Copy link

coveralls commented Mar 5, 2018

Coverage Status

Coverage increased (+0.04%) to 18.66% when pulling 5252972 on minishrink:feature/REQ477/CA-268511 into 7927595 on xapi-project:feature/REQ477/master.

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
Copy link
Contributor

@gaborigloi gaborigloi Mar 5, 2018

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)

Copy link
Contributor

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

Copy link
Contributor

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.

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
Copy link
Contributor

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.

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)
Copy link
Contributor

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)

Copy link
Member

@robhoes robhoes Mar 5, 2018

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.


let set_disallow_unplug ~__context ~self ~value =
assert_no_clustering_enabled ~__context ~self;
if Db.PIF.get_disallow_unplug ~__context ~self <> value
Copy link
Contributor

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

Copy link
Member

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.


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]))
Copy link
Contributor

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)

Copy link
Member

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.

Copy link
Member

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..

Copy link
Contributor

@gaborigloi gaborigloi left a 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.

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);
Copy link
Member

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.

Copy link
Contributor

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.

Copy link
Contributor

@gaborigloi gaborigloi Mar 6, 2018

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.

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 _ ->
Copy link
Member

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.

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);
Copy link
Member

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...

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")))
Copy link
Member

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...

Copy link
Member

@robhoes robhoes left a 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.

@minishrink minishrink force-pushed the feature/REQ477/CA-268511 branch from 79c6aae to 787b1a8 Compare March 5, 2018 20:16

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


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]))
Copy link
Contributor

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.

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")))
Copy link
Contributor

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.

Copy link
Contributor

@gaborigloi gaborigloi left a 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.

Copy link
Contributor

@edwintorok edwintorok left a 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?

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)
Copy link
Contributor

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.

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
Copy link
Member

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.

@robhoes
Copy link
Member

robhoes commented Mar 7, 2018

Just added a minor comment, but generally LGTM.

@lindig
Copy link
Contributor

lindig commented Mar 7, 2018

I would like to see commits to include the CA unless the history is cleaned.

@lindig lindig closed this Mar 7, 2018
@lindig lindig reopened this Mar 7, 2018
@edwintorok
Copy link
Contributor

I think all the commits could be squashed into one, it is logically one set of self-consistent changes.

@minishrink minishrink force-pushed the feature/REQ477/CA-268511 branch 3 times, most recently from 64caeac to 18b976a Compare March 7, 2018 17:47
- 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>
@minishrink minishrink force-pushed the feature/REQ477/CA-268511 branch from 18b976a to 5252972 Compare March 8, 2018 10:59
@edwintorok edwintorok merged commit db790e6 into xapi-project:feature/REQ477/master Mar 8, 2018
@minishrink minishrink deleted the feature/REQ477/CA-268511 branch March 8, 2018 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants