Skip to content

Backports for UPD-1009 / CP-50580 #5935

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

Merged
merged 8 commits into from
Aug 14, 2024
1 change: 1 addition & 0 deletions ocaml/xapi-cli-server/record_util.ml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ let vm_operation_table =
; (`changing_NVRAM, "changing_NVRAM")
; (`start, "start")
; (`start_on, "start_on")
; (`shutdown, "shutdown")
; (`suspend, "suspend")
; (`unpause, "unpause")
; (`update_allowed_operations, "update_allowed_operations")
Expand Down
1 change: 1 addition & 0 deletions ocaml/xapi/message_forwarding.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1858,6 +1858,7 @@ functor
; `hard_reboot
; `pool_migrate
; `call_plugin
; `shutdown
; `suspend
] ;
(* If VM is actually suspended and we ask to hard_shutdown, we need to
Expand Down
58 changes: 37 additions & 21 deletions ocaml/xapi/rrdd_proxy.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ let fail_req_with (s : Unix.file_descr) msg (http_err : unit -> string list) =
*)
let get_vm_rrd_forwarder (req : Http.Request.t) (s : Unix.file_descr) _ =
debug "put_rrd_forwarder: start" ;
let __FUNCTION__ = "get_vm_rrd_forwarder" in
let query = req.Http.Request.query in
req.Http.Request.close <- true ;
let vm_uuid = List.assoc "uuid" query in
Expand All @@ -65,49 +66,64 @@ let get_vm_rrd_forwarder (req : Http.Request.t) (s : Unix.file_descr) _ =
Xapi_http.with_context ~dummy:true "Get VM RRD." req s (fun __context ->
let open Http.Request in
(* List of possible actions. *)
let read_at_owner owner =
let address = Db.Host.get_address ~__context ~self:owner in
let read_at address =
let url = make_url ~address ~req in
Http_svr.headers s (Http.http_302_redirect url)
in
let unarchive_at_master () =
let address = Pool_role.get_master_address () in
let unarchive_at address =
let query = (Constants.rrd_unarchive, "") :: query in
let url = make_url_from_query ~address ~uri:req.uri ~query in
Http_svr.headers s (Http.http_302_redirect url)
in
let unarchive () =
let req = {req with uri= Constants.rrd_unarchive_uri} in
let req = {req with m= Post; uri= Constants.rrd_unarchive_uri} in
ignore
(Xapi_services.hand_over_connection req s
!Rrd_interface.forwarded_path
)
in
let unavailable () =
Http_svr.headers s (Http.http_503_service_unavailable ())
in
(* List of conditions involved. *)
let is_unarchive_request =
List.mem_assoc Constants.rrd_unarchive query
in
let is_master = Pool_role.is_master () in
let is_owner_online owner = Db.is_valid_ref __context owner in
let is_xapi_initialising = List.mem_assoc "dbsync" query in
let metrics_at () =
let ( let* ) = Option.bind in
let owner_of vm =
let owner = Db.VM.get_resident_on ~__context ~self:vm in
let is_xapi_initialising = List.mem_assoc "dbsync" query in
let is_available = not is_xapi_initialising in
if Db.is_valid_ref __context owner && is_available then
Some owner
else
None
in
let* owner = owner_of (Db.VM.get_by_uuid ~__context ~uuid:vm_uuid) in
let owner_uuid = Db.Host.get_uuid ~__context ~self:owner in
if owner_uuid = Helpers.get_localhost_uuid () then
(* VM is local but metrics aren't available *)
None
else
let address = Db.Host.get_address ~__context ~self:owner in
Some address
in
(* The logic. *)
if is_unarchive_request then
unarchive ()
else
let localhost_uuid = Helpers.get_localhost_uuid () in
let vm_ref = Db.VM.get_by_uuid ~__context ~uuid:vm_uuid in
let owner = Db.VM.get_resident_on ~__context ~self:vm_ref in
let owner_uuid = Ref.string_of owner in
let is_owner_localhost = owner_uuid = localhost_uuid in
if is_owner_localhost then
if is_master then
match (Pool_role.get_role (), metrics_at ()) with
| (Master | Slave _), Some owner ->
read_at owner
| Master, None ->
unarchive ()
else
unarchive_at_master ()
else if is_owner_online owner && not is_xapi_initialising then
read_at_owner owner
else
unarchive_at_master ()
| Slave coordinator, None ->
unarchive_at coordinator
| Broken, _ ->
info "%s: host is broken, VM's metrics are not available"
__FUNCTION__ ;
unavailable ()
)

(* Forward the request for host RRD data to the RRDD HTTP handler. If the host
Expand Down
30 changes: 17 additions & 13 deletions ocaml/xapi/taskHelper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ let rbac_assert_permission_fn = ref None

(* required to break dep-cycle with rbac.ml *)

let are_auth_user_ids_of_sessions_equal ~__context s1 s2 =
let s1_auth_user_sid =
Db_actions.DB_Action.Session.get_auth_user_sid ~__context ~self:s1
in
let s2_auth_user_sid =
Db_actions.DB_Action.Session.get_auth_user_sid ~__context ~self:s2
in
s1_auth_user_sid = s2_auth_user_sid

let assert_op_valid ?(ok_if_no_session_in_context = false) ~__context task_id =
let assert_permission_task_op_any () =
match !rbac_assert_permission_fn with
Expand All @@ -80,19 +89,14 @@ let assert_op_valid ?(ok_if_no_session_in_context = false) ~__context task_id =
| Some context_session ->
let is_own_task =
try
let task_session =
Db_actions.DB_Action.Task.get_session ~__context ~self:task_id
in
let task_auth_user_sid =
Db_actions.DB_Action.Session.get_auth_user_sid ~__context
~self:task_session
in
let context_auth_user_sid =
Db_actions.DB_Action.Session.get_auth_user_sid ~__context
~self:context_session
in
(*debug "task_auth_user_sid=%s,context_auth_user_sid=%s" task_auth_user_sid context_auth_user_sid;*)
task_auth_user_sid = context_auth_user_sid
(* If the task id is the same as the context's task id, we don't need
to go theough their respective sessions.*)
match Context.get_task_id __context = task_id with
| true ->
true
| false ->
are_auth_user_ids_of_sessions_equal ~__context context_session
(Db_actions.DB_Action.Task.get_session ~__context ~self:task_id)
with e ->
debug "assert_op_valid: %s" (ExnHelper.string_of_exn e) ;
false
Expand Down