Skip to content

Commit

Permalink
CP-18172: Check the license key on VM start
Browse files Browse the repository at this point in the history
Add tests for it too.

Signed-off-by: Jon Ludlam <jonathan.ludlam@citrix.com>
  • Loading branch information
jonludlam committed Jul 19, 2016
1 parent 3a341f2 commit b9b2c7e
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 2 deletions.
1 change: 1 addition & 0 deletions ocaml/test/OMakefile
Expand Up @@ -61,6 +61,7 @@ OCAML_OBJS = \
../license/daily_license_check \
test_daily_license_check \
test_dbsync_master \
test_xapi_xenops \

OCamlProgram(suite, suite $(OCAML_OBJS) )

Expand Down
1 change: 1 addition & 0 deletions ocaml/test/suite.ml
Expand Up @@ -51,6 +51,7 @@ let base_suite =
(* Test_ca121350.test; *)
Test_daily_license_check.test;
Test_dbsync_master.test;
Test_xapi_xenops.test;
]

let handlers = [
Expand Down
92 changes: 92 additions & 0 deletions ocaml/test/test_xapi_xenops.ml
@@ -0,0 +1,92 @@
open OUnit
open Test_common
open Test_vgpu_common

let test_enabled_in_xenguest () =
let should_raise = ["foo";"";"banana";"2"] in
let should_be_true = ["TRUE";"tRuE";"1";"true"] in
let should_be_false = ["FALSE";"fAlSe";"0";"false"] in

let err k =
failwith (Printf.sprintf "Failed to parse '%s' correctly" k)
in

let k = "test_key" in
let p v = [k,v] in
let val_fn p = Xapi_xenops.Platform.is_true ~key:k ~platformdata:p ~default:false in
let valid_fn p = Xapi_xenops.Platform.is_valid ~key:k ~platformdata:p in

(* Empty list should be valid *)
if not (valid_fn []) then err "[]";

List.iter (fun x -> if valid_fn (p x) then err x) should_raise;

List.iter (fun x ->
let e = val_fn (p x) in
if not e then err x) should_be_true;

List.iter (fun x ->
let e = val_fn (p x) in
if e then err x) should_be_false


let test_nested_virt_licensing () =
let __context = make_test_database () in
(* Nested_virt is restricted in the default test database *)

(* List of plaform keys and whether they should be restricted when 'Nested_virt' is restricted.
true -> definitely should be restricted
false -> definitely should be unrestricted
*)

let nested_virt_checks =
[[], false;
["foo","bar";"baz","moo";
"nested-virt","true"], true;
["nested-virt","TRUE"], true;
["nested-virt","false"], false;
["nested-virt","1"], true;
["nested-virt","0"], false;
["nested-virt","true"], true;
] in

let string_of_platform p =
Printf.sprintf "[%s]"
(String.concat ";" (List.map (fun (k,v) -> Printf.sprintf "'%s','%s'" k v) p))
in

let pool = Db.Pool.get_all ~__context |> List.hd in

let check_one (platform,should_raise) =
begin
try
Db.Pool.set_restrictions ~__context ~self:pool ~value:["restrict_nested_virt","true"];
Xapi_xenops.Platform.check_restricted_flags ~__context platform;
if should_raise
then
failwith
(Printf.sprintf "Failed to raise an exception for platform map: '[%s]'"
(string_of_platform platform));
with Api_errors.Server_error(e,l) when e=Api_errors.license_restriction ->
if not should_raise
then
failwith
(Printf.sprintf "Raise an exception unexpectedly for platform map: '[%s]'"
(string_of_platform platform));
end;

(* If the feature is unrestricted, nothing should raise an exception *)
Db.Pool.set_restrictions ~__context ~self:pool ~value:["restrict_nested_virt","false"];
Xapi_xenops.Platform.check_restricted_flags ~__context platform
in

List.iter check_one nested_virt_checks



let test =
"test_vm_helpers" >:::
[
"test_nested_virt_licensing" >:: test_nested_virt_licensing;
"test_enabled_in_xenguest" >:: test_enabled_in_xenguest;
]
3 changes: 3 additions & 0 deletions ocaml/xapi/xapi_vm.ml
Expand Up @@ -195,6 +195,9 @@ let start ~__context ~vm ~start_paused ~force =
debug "Setting ha_always_run on vm=%s as true during VM.start" (Ref.string_of vm)
end;

(* Check to see if we're using any restricted platform kvs. This raises
an exception if so *)
Xapi_xenops.Platform.check_restricted_flags ~__context vmr.API.vM_platform;

(* Clear out any VM guest metrics record. Guest metrics will be updated by
* the running VM and for now they might be wrong, especially network
Expand Down
26 changes: 24 additions & 2 deletions ocaml/xapi/xapi_xenops.ml
Expand Up @@ -109,6 +109,7 @@ module Platform = struct
let vgpu_config = Xapi_globs.vgpu_config_key
let igd_passthru_key = Xapi_globs.igd_passthru_key
let featureset = "featureset"
let nested_virt = "nested-virt"

(* This is only used to block the 'present multiple physical cores as one big hyperthreaded core' feature *)
let filtered_flags = [
Expand Down Expand Up @@ -136,19 +137,29 @@ module Platform = struct
vgpu_pci_id;
vgpu_config;
featureset;
nested_virt;
]

(* Other keys we might want to write to the platform map. *)
let timeoffset = "timeoffset"
let generation_id = "generation-id"

(* Helper functions. *)
(* [is_valid key platformdata] returns true if:
1. The key is _not_ in platformdata (absence of key is valid) or
2. The key is in platformdata, associated with a booleanish value *)
let is_valid ~key ~platformdata =
(not (List.mem_assoc key platformdata)) ||
(match List.assoc key platformdata |> String.lowercase with
| "true" | "1" | "false" | "0" -> true
| v -> false)

let is_true ~key ~platformdata ~default =
try
match List.assoc key platformdata with
match List.assoc key platformdata |> String.lowercase with
| "true" | "1" -> true
| "false" | "0" -> false
| _ -> default
| _ -> default (* Check for validity using is_valid if required *)
with Not_found ->
default

Expand Down Expand Up @@ -208,6 +219,17 @@ module Platform = struct
platformdata
in
platformdata


let check_restricted_flags ~__context platform =
if not (is_valid nested_virt platform) then
raise (Api_errors.Server_error
(Api_errors.invalid_value,
[Printf.sprintf "platform:%s" nested_virt;
List.assoc nested_virt platform]));

if is_true nested_virt platform false
then Pool_features.assert_enabled ~__context ~f:Features.Nested_virt
end

let xenops_vdi_locator_of_strings sr_uuid vdi_location =
Expand Down

0 comments on commit b9b2c7e

Please sign in to comment.