From badbeaa2ecf53131a96e541a061ab29e30285ba4 Mon Sep 17 00:00:00 2001 From: Bengang Yuan Date: Thu, 2 Jan 2025 17:05:06 +0800 Subject: [PATCH] CP-52074: Add start and stop ssh API on pool Signed-off-by: Bengang Yuan --- ocaml/idl/datamodel_errors.ml | 6 ++++++ ocaml/idl/datamodel_pool.ml | 20 ++++++++++++++++++ ocaml/sdk-gen/go/gen_go_helper.ml | 1 + ocaml/xapi-cli-server/cli_frontend.ml | 22 +++++++++++++++++++ ocaml/xapi-cli-server/cli_operations.ml | 8 +++++++ ocaml/xapi-consts/api_errors.ml | 4 ++++ ocaml/xapi/message_forwarding.ml | 8 +++++++ ocaml/xapi/xapi_pool.ml | 28 +++++++++++++++++++++++++ ocaml/xapi/xapi_pool.mli | 4 ++++ 9 files changed, 101 insertions(+) diff --git a/ocaml/idl/datamodel_errors.ml b/ocaml/idl/datamodel_errors.ml index 33c0cd2e39e..aeaad60dd30 100644 --- a/ocaml/idl/datamodel_errors.ml +++ b/ocaml/idl/datamodel_errors.ml @@ -2016,6 +2016,12 @@ let _ = error Api_errors.ssh_stop_failed ["host"] ~doc:"Failed to stop ssh service." () ; + error Api_errors.ssh_start_partially_failed ["hosts"] + ~doc:"Some of hosts failed to start ssh service." () ; + + error Api_errors.ssh_stop_partially_failed ["hosts"] + ~doc:"Some of hosts failed to stop ssh service." () ; + message (fst Api_messages.ha_pool_overcommitted) ~doc: diff --git a/ocaml/idl/datamodel_pool.ml b/ocaml/idl/datamodel_pool.ml index ab0d1669788..669d3e57722 100644 --- a/ocaml/idl/datamodel_pool.ml +++ b/ocaml/idl/datamodel_pool.ml @@ -1539,6 +1539,24 @@ let get_guest_secureboot_readiness = ~result:(pool_guest_secureboot_readiness, "The readiness of the pool") ~allowed_roles:_R_POOL_OP () +let ssh_start = + call ~name:"ssh_start" + ~doc: + "Start and enable ssh service on all hosts in the pool. It's a helper \ + which calls host.ssh_start for all the hosts in the pool." + ~lifecycle:[] + ~params:[(Ref _pool, "self", "The pool")] + ~allowed_roles:_R_POOL_ADMIN () + +let ssh_stop = + call ~name:"ssh_stop" + ~doc: + "Stop and disable ssh service on all hosts in the pool. It's a helper \ + which calls host.ssh_stop for all the hosts in the pool." + ~lifecycle:[] + ~params:[(Ref _pool, "self", "The pool")] + ~allowed_roles:_R_POOL_ADMIN () + (** A pool class *) let t = create_obj ~in_db:true @@ -1633,6 +1651,8 @@ let t = ; set_ext_auth_cache_size ; set_ext_auth_cache_expiry ; get_guest_secureboot_readiness + ; ssh_start + ; ssh_stop ] ~contents: ([ diff --git a/ocaml/sdk-gen/go/gen_go_helper.ml b/ocaml/sdk-gen/go/gen_go_helper.ml index 47540f55ef7..84b91260ae2 100644 --- a/ocaml/sdk-gen/go/gen_go_helper.ml +++ b/ocaml/sdk-gen/go/gen_go_helper.ml @@ -38,6 +38,7 @@ let acronyms = ; "db" ; "xml" ; "eof" + ; "ssh" ] |> StringSet.of_list diff --git a/ocaml/xapi-cli-server/cli_frontend.ml b/ocaml/xapi-cli-server/cli_frontend.ml index 4ad8f9adb59..c40ba0cd237 100644 --- a/ocaml/xapi-cli-server/cli_frontend.ml +++ b/ocaml/xapi-cli-server/cli_frontend.ml @@ -3133,6 +3133,28 @@ let rec cmdtable_data : (string * cmd_spec) list = ; flags= [] } ) + ; ( "pool-ssh-start" + , { + reqd= [] + ; optn= [] + ; help= + "Start and enable ssh service on all hosts in the pool. It's a \ + helper which calls host.ssh_start for all the hosts in the pool." + ; implementation= No_fd Cli_operations.pool_ssh_start + ; flags= [] + } + ) + ; ( "pool-ssh-stop" + , { + reqd= [] + ; optn= [] + ; help= + "Stop and disable ssh service on all hosts in the pool. It's a \ + helper which calls host.ssh_stop for all the hosts in the pool." + ; implementation= No_fd Cli_operations.pool_ssh_stop + ; flags= [] + } + ) ; ( "host-ha-xapi-healthcheck" , { reqd= [] diff --git a/ocaml/xapi-cli-server/cli_operations.ml b/ocaml/xapi-cli-server/cli_operations.ml index 49192361f5f..d63e658464c 100644 --- a/ocaml/xapi-cli-server/cli_operations.ml +++ b/ocaml/xapi-cli-server/cli_operations.ml @@ -6779,6 +6779,14 @@ let pool_sync_bundle fd _printer rpc session_id params = | None -> failwith "Required parameter not found: filename" +let pool_ssh_start _printer rpc session_id params = + let pool = get_pool_with_default rpc session_id params "uuid" in + Client.Pool.ssh_start ~rpc ~session_id ~self:pool + +let pool_ssh_stop _printer rpc session_id params = + let pool = get_pool_with_default rpc session_id params "uuid" in + Client.Pool.ssh_stop ~rpc ~session_id ~self:pool + let host_restore fd _printer rpc session_id params = let filename = List.assoc "file-name" params in let op _ host = diff --git a/ocaml/xapi-consts/api_errors.ml b/ocaml/xapi-consts/api_errors.ml index d2518bdcb95..2ac642f6302 100644 --- a/ocaml/xapi-consts/api_errors.ml +++ b/ocaml/xapi-consts/api_errors.ml @@ -1407,3 +1407,7 @@ let too_many_groups = add_error "TOO_MANY_GROUPS" let ssh_start_failed = add_error "SSH_START_FAILED" let ssh_stop_failed = add_error "SSH_STOP_FAILED" + +let ssh_start_partially_failed = add_error "SSH_START_PARTIALLY_FAILED" + +let ssh_stop_partially_failed = add_error "SSH_STOP_PARTIALLY_FAILED" diff --git a/ocaml/xapi/message_forwarding.ml b/ocaml/xapi/message_forwarding.ml index 4771a8af6b3..5d73cff65dc 100644 --- a/ocaml/xapi/message_forwarding.ml +++ b/ocaml/xapi/message_forwarding.ml @@ -1185,6 +1185,14 @@ functor let get_guest_secureboot_readiness ~__context ~self = info "%s: pool='%s'" __FUNCTION__ (pool_uuid ~__context self) ; Local.Pool.get_guest_secureboot_readiness ~__context ~self + + let ssh_start ~__context ~self = + info "%s: pool = '%s'" __FUNCTION__ (pool_uuid ~__context self) ; + Local.Pool.ssh_start ~__context ~self + + let ssh_stop ~__context ~self = + info "%s: pool = '%s'" __FUNCTION__ (pool_uuid ~__context self) ; + Local.Pool.ssh_stop ~__context ~self end module VM = struct diff --git a/ocaml/xapi/xapi_pool.ml b/ocaml/xapi/xapi_pool.ml index 2f471932c14..3e5ed76d7c3 100644 --- a/ocaml/xapi/xapi_pool.ml +++ b/ocaml/xapi/xapi_pool.ml @@ -3952,3 +3952,31 @@ let put_bundle_handler (req : Request.t) s _ = | None -> () ) + +let ssh_helper ~__context ~action ~error = + let hosts = Db.Host.get_all ~__context in + Helpers.call_api_functions ~__context (fun rpc session_id -> + let failed_hosts = + List.fold_left + (fun failed_hosts host -> + try + action ~rpc ~session_id ~self:host ; + failed_hosts + with _ -> Ref.string_of host :: failed_hosts + ) + [] hosts + in + match failed_hosts with + | [] -> + () + | _ -> + raise (Api_errors.Server_error (error, failed_hosts)) + ) + +let ssh_start ~__context ~self:_ = + ssh_helper ~__context ~action:Client.Host.ssh_start + ~error:Api_errors.ssh_start_partially_failed + +let ssh_stop ~__context ~self:_ = + ssh_helper ~__context ~action:Client.Host.ssh_stop + ~error:Api_errors.ssh_stop_partially_failed diff --git a/ocaml/xapi/xapi_pool.mli b/ocaml/xapi/xapi_pool.mli index 835a356f782..b5b27f07784 100644 --- a/ocaml/xapi/xapi_pool.mli +++ b/ocaml/xapi/xapi_pool.mli @@ -434,3 +434,7 @@ val get_guest_secureboot_readiness : -> API.pool_guest_secureboot_readiness val put_bundle_handler : Http.Request.t -> Unix.file_descr -> 'a -> unit + +val ssh_start : __context:Context.t -> self:API.ref_pool -> unit + +val ssh_stop : __context:Context.t -> self:API.ref_pool -> unit