Skip to content
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

CP-40357: Parse all lifecycled in the datamodel, avoid loading removed fields into the database #4853

Merged
merged 12 commits into from
Dec 14, 2022

Conversation

psafont
Copy link
Member

@psafont psafont commented Nov 21, 2022

Now all the lifecycles in the datamodel are check by an automaton found in datamodel_types
This allows to enforce lifecycles to all fields and messages and xapi to
know it, especially when loading the database from a file, which will now avoid loading removed fields onto the in-memory database

Marking as draft because I want feedback on the lifecycle automation and the datamodel changes but I haven't tested the database changes

@psafont psafont requested a review from robhoes November 21, 2022 17:26
@psafont psafont force-pushed the private/paus/tears-in-the-rain branch 4 times, most recently from 3b62b81 to 03765e6 Compare November 24, 2022 17:05
@psafont psafont force-pushed the private/paus/tears-in-the-rain branch 4 times, most recently from 3dc9ace to e420f6c Compare December 5, 2022 14:35
@psafont
Copy link
Member Author

psafont commented Dec 5, 2022

Now the database ignores removed fields when loading, the second time there are no messages about ignored fields.

Now testing the json generation code

@psafont
Copy link
Member Author

psafont commented Dec 6, 2022

With the docs fixed, this is ready to be reviewed. I recommend doing it commit by commit, and special attention should be given to CP-40357: Patch invalid lifecycles to make sure the changes there make sense, and the last commit where the datamodel changes force changes into the rest of xapi

@psafont psafont force-pushed the private/paus/tears-in-the-rain branch 3 times, most recently from 1b2767d to 84ea790 Compare December 6, 2022 12:39

let all_lifecycles =
let parse_with ~name lifecycle =
try Lifecycle.from lifecycle
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this use a result type instead, or do you want to preserve the location that raised the invalid message in stacktraces (if it is useful then it should be preserved and using exceptions here is better)

Copy link
Member Author

Choose a reason for hiding this comment

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

This code is replaced when the lifecycle state is integrated into the datamodel, I don't think it's important enough to change it for the few commits it's used

@@ -381,6 +381,32 @@ end = struct
else
cmp

let rec list_dedup cmp =
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 have an implementation of this elsewhere already (somewhere in stdext)?
Although there is List.sort_uniq would that help, or you need more control over which one to keep?

Copy link
Member Author

@psafont psafont Dec 6, 2022

Choose a reason for hiding this comment

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

I want to sort using a criteria then remove duplicates according to another, specific criteria. This means i need sorting and deduplication to be separate functions, which discards sort_uniq. Stdext has setify with is the same as dedup, but it hardcodes the comparison function to = which is not enough here.

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.

This mostly looks really good, and is a much needed update to control the evolution of the API. Before merging, we'll need to ensure that we test the upgrade case very well. We'll also need to assess the impact on the API bindings (SDK), as I suspect that the last commit goes a step too far in removing fields, where clients may need them to connect to older server versions.

@@ -1380,8 +1396,7 @@ let copy_bios_strings =
~allowed_roles:_R_VM_ADMIN ()

let set_protection_policy =
call ~name:"set_protection_policy" ~in_oss_since:None
~in_product_since:rel_orlando
call ~name:"set_protection_policy" ~in_oss_since:None ~lifecycle:vmpp_removed
Copy link
Member

Choose a reason for hiding this comment

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

It said ~in_product_since:rel_orlando, but that wasn't actually true...

@psafont psafont force-pushed the private/paus/tears-in-the-rain branch 2 times, most recently from d851d42 to 9662286 Compare December 9, 2022 11:44
Copy link
Contributor

@lindig lindig left a comment

Choose a reason for hiding this comment

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

Obviously a complex change whose logic I can't review comprehensively. Only a few remarks,

ocaml/idl/json_backend/gen_json.ml Outdated Show resolved Hide resolved
ocaml/idl/json_backend/gen_json.ml Outdated Show resolved Hide resolved
significative one and drop the rest *)
changes
|> List.sort (fun ((_, nam_a, _, _) as a) ((_, nam_b, _, _) as b) ->
let cmp = String.compare nam_a nam_b in
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure I understand this logic: when the names are identical, call compare_changes, which again uses the complete structure. Is the purpose here to compare the two structures by element and controlling the order? I've used the code below in such a situation where I define an order by comparing elements in a particular order.

  let (<?>) a b =
    if a = 0 then b else a

  let compare a b =
        compare a.hour    b.hour
    <?> compare a.minutes b.minutes
    <?> compare a.seconds b.seconds
    <?> 0

Copy link
Member Author

@psafont psafont Dec 12, 2022

Choose a reason for hiding this comment

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

It orders the list of entity changes in a release by the name of the entity and the type of change (removed last, prototyped first). This means all changes regarding a field are all group together and ordered in reverse order, from last to first.

Once that is done it drops items with a name that's the same as the preceding one. This way only the last change per entity is kept. For example if in a release a field got deprecated and removed, only the removed change is kept.

@psafont psafont force-pushed the private/paus/tears-in-the-rain branch from 9662286 to 391baa9 Compare December 12, 2022 12:54
This allows to enforce lifecycles to all fields and messages and xapi to
know it, especially when loading the database from a file.

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
These we all removed without being deprecated. These would be all
rejected by the lifecycle automaton.

Only with the SSL legacy it's clear at which released the message got
deprecated (as soon as it was introduced) For the rest I used an
easily-recognisable message that happens before and at the same release
as the removal.

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
This will block any unsafe transitions from happening in the API

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
This allows the database library to be able to depend on the datamodel
one, while the latter now depends only the schema library

The database library needs to depend on the datamodel one to be able to
know when a field is a prototype one

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
No functional changes, the changes try to reduce the complexity of
reading the code and reuse code for brevity

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
The comment is misleading since it refers to behaviour that has long
been forgotten

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
psafont and others added 6 commits December 14, 2022 14:46
This allows dropping values that were only prototyped, or deprecated
from the database

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
This is the default value and serves no purpose

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
This enables build the state at compile time without ad-hoc processing
as this is done in the datamodel itself. For example to block removed
fields from database constructors when autogenerating their code.

This information is encapsulated in Lifecycle.t which is a private
record. This makes it easy to deconstruct while forces its construction
using the function Lifecycle.from. This prevents inconsistent Lifecycles
from being created.

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
Now the database schema and most of the code generation are filtering
these. In the case where the documentation about removal is still
needed, the old method is used, albeit with a new name for the avoidance
of doubt.

This change means that it's impossible to create objects with removed
fields, introducing quite a bit of churn. The most salient issues here
are: the host metrics drop the free memory, which was still being
maintained and used for estimating evacuation time. This is now done
using total memory consumed by VMs instead; the removal
of metrics in VIFs and VBDs, which makes it impossible to delete these
objects from the database; and the removal of vmpp-related fields.

Signed-off-by: Pau Ruiz Safont <pau.safont@citrix.com>
This change affects the public documentation only.
When a field is published and deprecated on the same release, only the
the deprecation notice is shown. Similarly when a message is deprecated
and removed in the same release, only the removal gets shown.

Signed-off-by: Pau Ruiz Safont <pau.ruizsafont@cloud.com>
@psafont psafont force-pushed the private/paus/tears-in-the-rain branch from 391baa9 to ad1e634 Compare December 14, 2022 14:47
@psafont psafont merged commit 4ec6be9 into xapi-project:master Dec 14, 2022
@psafont psafont deleted the private/paus/tears-in-the-rain branch December 14, 2022 15:35
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.

4 participants