-
Notifications
You must be signed in to change notification settings - Fork 41
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-26098: Port v6d interface from Camlp4 to PPX #186
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
69ed867
CP:26098: Wrap errors and types, define ppx-based RPC functor
d5562ba
CP-26098: Update jbuild file
2860342
CP-26098: Update V6 client error handling for PPX 2
5376b10
CP-26098: ocp-indent and refactor errors and records
745c2fe
CP-26098: Suggested changes to V6 interface
47160fe
CP-26098: Autogen CLI for dev/debugging
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
(* Licensing CLI *) | ||
|
||
module Cmds =V6_interface.RPC_API(Cmdlinergen.Gen ()) | ||
|
||
let version_str description = | ||
let maj,min,mic = description.Idl.Interface.version in | ||
Printf.sprintf "%d.%d.%d" maj min mic | ||
|
||
let default_cmd = | ||
let doc = String.concat "" [ | ||
"A CLI for the V6d API. This allows scripting of the licensing daemon "; | ||
"for testing and debugging. This tool is not intended to be used as an "; | ||
"end user tool"] in | ||
Cmdliner.Term.(ret (const (fun _ -> `Help (`Pager, None)) $ const ())), | ||
Cmdliner.Term.info "licensing_cli" ~version:(version_str Cmds.description) ~doc | ||
|
||
let cli () = | ||
let rpc = V6_client.rpc in | ||
Cmdliner.Term.eval_choice default_cmd (List.map (fun t -> t rpc) (Cmds.implementation ())) | ||
|
||
let _ = cli () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,33 +12,137 @@ | |
* GNU Lesser General Public License for more details. | ||
*) | ||
|
||
(** | ||
@group Licensing | ||
*) | ||
open Rpc | ||
open Idl | ||
|
||
let service_name = "v6d" | ||
let queue_name = ref (Xcp_service.common_prefix ^ service_name) | ||
let default_sockets_dir = "/var/lib/xcp" | ||
let default_path = ref (Filename.concat default_sockets_dir service_name) | ||
let uri () = "file:" ^ !default_path | ||
let json_path = "/var/xapi/v6.json" | ||
let xml_path = "/var/xapi/v6" | ||
|
||
(** Uninterpreted/sanitised string associated with operation *) | ||
type debug_info = string | ||
[@@deriving rpcty] | ||
|
||
(** Record representing software edition *) | ||
type edition = | ||
{ | ||
title : string ; | ||
(** Name of edition, this will be passed to apply_edition *) | ||
official_title : string ; | ||
(** Marketing title used to advertise edition *) | ||
code : string ; | ||
(** Abbreviated form of name, used to show up in logs and on command line *) | ||
order : int ; | ||
(** Number indicating ordering among other editions; | ||
low numbers correspond to fewer features, and vice versa *) | ||
} | ||
[@@deriving rpcty] | ||
|
||
type edition_info = { | ||
edition: string; | ||
(** List of edition records *) | ||
type edition_list = edition list | ||
[@@deriving rpcty] | ||
|
||
(** Record of edition info, including xapi parameters and features *) | ||
type edition_info = | ||
{ | ||
edition_name: string; | ||
(** Name of edition *) | ||
xapi_params: (string * string) list; | ||
(** List of parameters used by Xapi *) | ||
additional_params: (string * string) list; | ||
(** Addition parameters supplied *) | ||
experimental_features: (string * bool) list; | ||
} | ||
(** List of experimental features and whether they're available in this edition *) | ||
} | ||
[@@deriving rpcty] | ||
|
||
(** [string * string] list *) | ||
type string_pair_lst = (string * string) list | ||
[@@deriving rpcty] | ||
|
||
(** Wrapper for specific errors in managing features *) | ||
type errors = | ||
| Invalid_edition of string | ||
(** Thrown by apply_edition on receiving unfamiliar edition. | ||
* Note: get_editions returns list of all valid editions *) | ||
| License_expired | ||
(** Thrown by license_check when expiry date matches or precedes current date *) | ||
| License_processing_error | ||
(** License could not be processed *) | ||
| License_checkout_error of string | ||
(** License could not be checked out *) | ||
| Missing_connection_details | ||
(** Thrown if connection port or address parameter not supplied to check_license *) | ||
| V6d_failure | ||
(** Daemon failed to enable features *) | ||
[@@default V6d_failure] | ||
[@@deriving rpcty] | ||
|
||
(** Pass error variant as exn for error handler *) | ||
exception V6_error of errors | ||
[@@deriving rpcty] | ||
|
||
(** handle exception generation and raising *) | ||
let err = Error.{ | ||
def = errors; | ||
raiser = (function | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Either both, |
||
| e -> raise (V6_error e)); | ||
matcher = (function | ||
| V6_error e -> Some e | ||
| _ -> None) | ||
} | ||
|
||
|
||
(** functor to autogenerate code using PPX *) | ||
module RPC_API(R : RPC) = struct | ||
open R | ||
|
||
(* description of V6d interface module *) | ||
let description = Interface.{ | ||
name = "Licensing"; | ||
namespace = None; | ||
description = | ||
[ | ||
"This interface is used by Xapi and V6d to manage " | ||
; "enabling and disabling features." | ||
]; | ||
version=(1,0,0); } | ||
|
||
(* define implementation *) | ||
let implementation = implement description | ||
|
||
(* define general parameters for API calls *) | ||
let debug_info_p = Param.mk ~description:[ | ||
"An uninterpreted string to associate with the operation." | ||
] debug_info | ||
|
||
(* ---- API call definitions ---- *) | ||
|
||
exception Invalid_edition of string | ||
exception V6d_failure | ||
exception License_expired | ||
exception License_processing_error | ||
exception Missing_connection_details | ||
exception License_checkout_error of string | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we not need |
||
let apply_edition = | ||
let edition_p = Param.mk ~description:["Edition title"] Types.string in | ||
let edition_info_p = Param.mk ~description:["Edition info"] edition_info in | ||
let current_params_p = Param.mk ~description:["Xapi parameters"] string_pair_lst in | ||
declare "apply_edition" | ||
["Checks license info to ensures enabled features are compatible."] | ||
( debug_info_p @-> edition_p @-> current_params_p @-> returning edition_info_p err ) | ||
|
||
(* dbg_str -> requested edition -> current params -> edition_info *) | ||
external apply_edition : debug_info -> string -> (string * string) list -> edition_info = "" | ||
let get_editions = | ||
let edition_list_p = Param.mk ~description:["List of editions"] edition_list in | ||
declare "get_editions" | ||
["Gets list of accepted editions."] | ||
( debug_info_p @-> returning edition_list_p err ) | ||
|
||
(* dbg_str -> list of editions *) | ||
external get_editions : debug_info -> (string * (string * string * int)) list = "" | ||
let get_version = | ||
let result_p = Param.mk ~description:["String of version."] Types.string in | ||
declare "get_version" | ||
["Returns version"] | ||
( debug_info_p @-> returning result_p err ) | ||
|
||
(* dbg_str -> result *) | ||
external get_version : debug_info -> string = "" | ||
end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 believe a file URL needs to start with
file://
, see https://en.wikipedia.org/wiki/File_URI_schemeThere 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.
Happy to change it, but I'm curious: I've had a look at how other daemon interfaces define the json_url/json_path function, and it seems like they all follow this pattern, which would presumably result in something like this:
file:/var/path/to/file.extension
Given that there haven't been any issues so far (that I know of) with this format, is the change just a matter of following conventions? Also, is it worth changing for all interfaces?
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 might have raised this in the past. It's wrong but it works. So let's keep it.
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 can leave this for now and change it for all interfaces in a separate PR, would that work?
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.
Sure. Let's stick with it for the moment