diff --git a/ocaml/xapi/import_raw_vdi.ml b/ocaml/xapi/import_raw_vdi.ml index b186618ca0f..27dcfb9b1ed 100755 --- a/ocaml/xapi/import_raw_vdi.ml +++ b/ocaml/xapi/import_raw_vdi.ml @@ -96,37 +96,32 @@ let localhost_handler rpc session_id vdi_opt (req: Request.t) (s: Unix.file_desc raise e ) -let import vdi (req: Request.t) (s: Unix.file_descr) _ = - Xapi_http.assert_credentials_ok "VDI.import" ~http_action:"put_import_raw_vdi" req s; - +let import vdi (req: Request.t) (s: Unix.file_descr) _ rpc session_id = (* Perform the SR reachability check using a fresh context/task because we don't want to complete the task in the forwarding case *) - Server_helpers.exec_with_new_task "VDI.import" (fun __context -> try - Helpers.call_api_functions ~__context - (fun rpc session_id -> - let sr_opt = match vdi, sr_of_req ~__context req with - | Some vdi, _ -> Some (Db.VDI.get_SR ~__context ~self:vdi) - | None, Some sr -> Some sr - | None, None -> None - in - match sr_opt with - | Some sr -> - debug "Checking whether localhost can see SR: %s" (Ref.string_of sr); - if (Importexport.check_sr_availability ~__context sr) - then localhost_handler rpc session_id vdi req s - else - let host = Importexport.find_host_for_sr ~__context sr in - let address = Db.Host.get_address ~__context ~self:host in - return_302_redirect req s address; - None - | None -> - error "Require an SR or VDI to import"; - fail_task_in_request req s Api_errors.(Server_error(vdi_missing,[])); - None - ) + let sr_opt = match vdi, sr_of_req ~__context req with + | Some vdi, _ -> Some (Db.VDI.get_SR ~__context ~self:vdi) + | None, Some sr -> Some sr + | None, None -> None + in + match sr_opt with + | Some sr -> + debug "Checking whether localhost can see SR: %s" (Ref.string_of sr); + if (Importexport.check_sr_availability ~__context sr) + then localhost_handler rpc session_id vdi req s + else + let host = Importexport.find_host_for_sr ~__context sr in + let address = Db.Host.get_address ~__context ~self:host in + return_302_redirect req s address; + None + | None -> + error "Require an SR or VDI to import"; + fail_task_in_request req s Api_errors.(Server_error(vdi_missing,[])); + None + with e -> error "Caught exception in import handler: %s" (ExnHelper.string_of_exn e); fail_task_in_request req s e; @@ -134,13 +129,21 @@ let import vdi (req: Request.t) (s: Unix.file_descr) _ = ) +let import_without_credentials __context vdi (req: Request.t) (s: Unix.file_descr) _ = + Helpers.call_api_functions ~__context + (fun rpc session_id -> + let rpc_introduce = rpc in + let sessin_id_introduce = session_id in + import vdi req s () rpc_introduce sessin_id_introduce + ) let handler (req: Request.t) (s: Unix.file_descr) _ = + Xapi_http.assert_credentials_ok "VDI.import" ~http_action:"put_import_raw_vdi" req s; (* Using a fresh context/task because we don't want to complete the task in the forwarding case *) Server_helpers.exec_with_new_task "VDI.import" (fun __context -> - ignore(import (vdi_of_req ~__context req) req s ()) + ignore(import_without_credentials __context (vdi_of_req ~__context req) req s ()) ) diff --git a/ocaml/xapi/suite.ml b/ocaml/xapi/suite.ml index 3dd64c2aadc..7ea40d67232 100644 --- a/ocaml/xapi/suite.ml +++ b/ocaml/xapi/suite.ml @@ -65,6 +65,7 @@ let base_suite = Test_guest_agent.test; Test_vlan.test; Test_xapi_vbd_helpers.test; + Test_import_raw_vdi.test; ] let handlers = [ diff --git a/ocaml/xapi/test_import_raw_vdi.ml b/ocaml/xapi/test_import_raw_vdi.ml new file mode 100755 index 00000000000..a5cda3114b9 --- /dev/null +++ b/ocaml/xapi/test_import_raw_vdi.ml @@ -0,0 +1,56 @@ +(* + * Copyright (C) 2013 Citrix Systems Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *) + +open OUnit +open Test_common +open Stdext +open Unixext +open Client + + +let test_xe_update_upload_ca226886 () = + let __context = Test_common.make_test_database () in + let arg str x = Opt.default [] (Opt.map (fun x -> [ str, x ]) x) in + let session_id = Ref.make () in + let uuid = Uuid.to_string (Uuid.make_uuid ()) in + Db.Session.create ~__context ~ref:session_id ~uuid + ~this_user:Ref.null ~this_host:(Helpers.get_localhost ~__context) ~pool:false + ~last_active:(Stdext.Date.of_float (Unix.time ())) ~other_config:[] + ~subject:(Ref.null) ~is_local_superuser:true + ~auth_user_sid:"" ~validation_time:(Stdext.Date.of_float (Unix.time ())) + ~auth_user_name:"root" ~rbac_permissions:[] ~parent:Ref.null ~originator:"test"; + let request_origin = Xmlrpc_client.xmlrpc ~version:"1.1" "/" in + let rpc = Api_server.Server.dispatch_call request_origin Unix.stdout in + let task_id = Client.Task.create ~rpc:rpc ~session_id + ~label:"test import raw vdi" + ~description:"" in + let cookie = Some "fake_sr" |> arg "sr_id" in + let query = Some (Ref.string_of task_id) |> arg "task_id" in + let request = Xmlrpc_client.xmlrpc ~version:"1.1" ~cookie ~query "/" in + let fd = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in + let pool = Helpers.get_pool ~__context in + Db.Pool.set_default_SR ~__context ~self:pool ~value:Ref.null; + Db.Task.set_status ~__context ~self:task_id ~value:`pending; + try begin + let _ = Import_raw_vdi.import None request fd () rpc session_id in + () + end + with e -> + let status = Db.Task.get_status ~__context ~self:task_id in + OUnit.assert_equal `failure status; + () + + +let test = + "test_xe_update_upload_ca226886" >:: test_xe_update_upload_ca226886 \ No newline at end of file diff --git a/ocaml/xapi/xapi_services.ml b/ocaml/xapi/xapi_services.ml index 0bb6f83dbb2..2d618a870b7 100644 --- a/ocaml/xapi/xapi_services.ml +++ b/ocaml/xapi/xapi_services.ml @@ -169,7 +169,7 @@ let put_handler (req: Http.Request.t) s _ = http_proxy_to_plugin req s name | [ ""; services; "SM"; "data"; sr; vdi ] when services = _services -> let vdi, _ = Storage_access.find_vdi ~__context sr vdi in - ignore(Import_raw_vdi.import (Some vdi) req s ()) + ignore(Import_raw_vdi.import_without_credentials __context (Some vdi) req s ()) | [ ""; services; "SM"; "nbd"; sr; vdi; dp ] when services = _services -> Storage_migrate.nbd_handler req s sr vdi dp | _ ->