Skip to content

Commit 2da29e2

Browse files
committed
CP-53478: Implement SSH enabeld timeout API for Dom0 SSH control
Implemented XAPI API: - `set_ssh_enabled_timeout` This API allow XAPI to configure timeouts for the SSH service. Signed-off-by: Lunfan Zhang <[email protected]>
1 parent 387355a commit 2da29e2

File tree

4 files changed

+121
-14
lines changed

4 files changed

+121
-14
lines changed

ocaml/idl/datamodel_errors.ml

+3
Original file line numberDiff line numberDiff line change
@@ -2040,6 +2040,9 @@ let _ =
20402040
error Api_errors.disable_ssh_partially_failed ["hosts"]
20412041
~doc:"Some of hosts failed to disable SSH access." () ;
20422042

2043+
error Api_errors.set_ssh_timeout_partially_failed ["hosts"]
2044+
~doc:"Some hosts failed to set SSH timeout." () ;
2045+
20432046
error Api_errors.set_console_timeout_partially_failed ["hosts"]
20442047
~doc:"Some hosts failed to set console timeout." () ;
20452048

ocaml/xapi-consts/api_errors.ml

+3
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,9 @@ let enable_ssh_partially_failed = add_error "ENABLE_SSH_PARTIALLY_FAILED"
14201420

14211421
let disable_ssh_partially_failed = add_error "DISABLE_SSH_PARTIALLY_FAILED"
14221422

1423+
let set_ssh_timeout_partially_failed =
1424+
add_error "SET_SSH_TIMEOUT_PARTIALLY_FAILED"
1425+
14231426
let set_console_timeout_partially_failed =
14241427
add_error "SET_CONSOLE_TIMEOUT_PARTIALLY_FAILED"
14251428

ocaml/xapi/xapi_host.ml

+107-13
Original file line numberDiff line numberDiff line change
@@ -3114,27 +3114,121 @@ let emergency_clear_mandatory_guidance ~__context =
31143114
) ;
31153115
Db.Host.set_pending_guidances ~__context ~self ~value:[]
31163116

3117+
let remove_disable_ssh_job ~__context ~self =
3118+
let host_uuid = Db.Host.get_uuid ~__context ~self in
3119+
let task_name = Printf.sprintf "disable_ssh_for_host_%s" host_uuid in
3120+
Xapi_stdext_threads_scheduler.Scheduler.remove_from_queue task_name
3121+
3122+
let schedule_disable_ssh_job ~__context ~self ~timeout =
3123+
let host_uuid = Db.Host.get_uuid ~__context ~self in
3124+
let task_name = Printf.sprintf "disable_ssh_for_host_%s" host_uuid in
3125+
3126+
let expiry_time =
3127+
match
3128+
Ptime.add_span (Ptime_clock.now ())
3129+
(Ptime.Span.of_int_s (Int64.to_int timeout))
3130+
with
3131+
| None ->
3132+
error "Invalid SSH timeout: %Ld" timeout ;
3133+
raise
3134+
(Api_errors.Server_error
3135+
(Api_errors.invalid_value, ["timeout"; Int64.to_string timeout])
3136+
)
3137+
| Some t ->
3138+
Ptime.to_float_s t |> Date.of_unix_time
3139+
in
3140+
3141+
debug "Scheduling SSH disable job for host %s with timeout %Ld" host_uuid
3142+
timeout ;
3143+
3144+
(* Remove any existing job first *)
3145+
remove_disable_ssh_job ~__context ~self ;
3146+
3147+
Xapi_stdext_threads_scheduler.Scheduler.add_to_queue task_name
3148+
Xapi_stdext_threads_scheduler.Scheduler.OneShot (Int64.to_float timeout)
3149+
(fun () ->
3150+
try
3151+
Xapi_systemctl.disable ~wait_until_success:false "sshd" ;
3152+
Xapi_systemctl.stop ~wait_until_success:false "sshd" ;
3153+
Db.Host.set_ssh_enabled ~__context ~self ~value:false ;
3154+
debug "Successfully disabled SSH for host %s" host_uuid
3155+
with e ->
3156+
error "Failed to disable SSH for host %s: %s" host_uuid
3157+
(Printexc.to_string e)
3158+
) ;
3159+
3160+
Db.Host.set_ssh_expiry ~__context ~self ~value:expiry_time
3161+
31173162
let enable_ssh ~__context ~self =
31183163
try
3164+
debug "Enabling SSH for host %s" (Db.Host.get_uuid ~__context ~self) ;
3165+
31193166
Xapi_systemctl.enable ~wait_until_success:false "sshd" ;
3120-
Xapi_systemctl.start ~wait_until_success:false "sshd"
3121-
with _ ->
3122-
raise
3123-
(Api_errors.Server_error
3124-
(Api_errors.enable_ssh_failed, [Ref.string_of self])
3125-
)
3167+
Xapi_systemctl.start ~wait_until_success:false "sshd" ;
3168+
3169+
let timeout = Db.Host.get_ssh_enabled_timeout ~__context ~self in
3170+
( match timeout with
3171+
| 0L ->
3172+
remove_disable_ssh_job ~__context ~self
3173+
| t ->
3174+
schedule_disable_ssh_job ~__context ~self ~timeout:t
3175+
) ;
3176+
3177+
Db.Host.set_ssh_enabled ~__context ~self ~value:true
3178+
with e ->
3179+
error "Failed to enable SSH on host %s: %s" (Ref.string_of self)
3180+
(Printexc.to_string e) ;
3181+
Helpers.internal_error "Failed to enable SSH: %s" (Printexc.to_string e)
31263182

31273183
let disable_ssh ~__context ~self =
31283184
try
3185+
debug "Disabling SSH for host %s" (Db.Host.get_uuid ~__context ~self) ;
3186+
3187+
remove_disable_ssh_job ~__context ~self ;
3188+
31293189
Xapi_systemctl.disable ~wait_until_success:false "sshd" ;
3130-
Xapi_systemctl.stop ~wait_until_success:false "sshd"
3131-
with _ ->
3132-
raise
3133-
(Api_errors.Server_error
3134-
(Api_errors.disable_ssh_failed, [Ref.string_of self])
3135-
)
3190+
Xapi_systemctl.stop ~wait_until_success:false "sshd" ;
3191+
Db.Host.set_ssh_enabled ~__context ~self ~value:false ;
31363192

3137-
let set_ssh_enabled_timeout ~__context ~self:_ ~value:_ = ()
3193+
let expiry_time =
3194+
Ptime_clock.now () |> Ptime.to_float_s |> Date.of_unix_time
3195+
in
3196+
Db.Host.set_ssh_expiry ~__context ~self ~value:expiry_time
3197+
with e ->
3198+
error "Failed to disable SSH on host %s: %s" (Ref.string_of self)
3199+
(Printexc.to_string e) ;
3200+
Helpers.internal_error "Failed to disable SSH: %s" (Printexc.to_string e)
3201+
3202+
let set_ssh_enabled_timeout ~__context ~self ~value =
3203+
let validate_timeout value =
3204+
if value < 0L || value > 172800L then
3205+
raise
3206+
(Api_errors.Server_error
3207+
( Api_errors.invalid_value
3208+
, [
3209+
"timeout"
3210+
; Int64.to_string value
3211+
; "must be between 0 and 2*24*60*60 seconds"
3212+
]
3213+
)
3214+
)
3215+
in
3216+
validate_timeout value ;
3217+
debug "Setting SSH timeout for host %s to %Ld seconds"
3218+
(Db.Host.get_uuid ~__context ~self)
3219+
value ;
3220+
Db.Host.set_ssh_enabled_timeout ~__context ~self ~value ;
3221+
match Db.Host.get_ssh_enabled ~__context ~self with
3222+
| false ->
3223+
()
3224+
| true -> (
3225+
match value with
3226+
| 0L ->
3227+
remove_disable_ssh_job ~__context ~self ;
3228+
Db.Host.set_ssh_expiry ~__context ~self ~value:Date.epoch
3229+
| t ->
3230+
schedule_disable_ssh_job ~__context ~self ~timeout:t
3231+
)
31383232

31393233
let set_console_idle_timeout ~__context ~self ~value =
31403234
let validate_timeout = function

ocaml/xapi/xapi_pool.ml

+8-1
Original file line numberDiff line numberDiff line change
@@ -4004,6 +4004,13 @@ module Ssh = struct
40044004
operate ~__context ~action:Client.Host.disable_ssh
40054005
~error:Api_errors.disable_ssh_partially_failed
40064006

4007+
let set_enabled_timeout ~__context ~self:_ ~value =
4008+
operate ~__context
4009+
~action:(fun ~rpc ~session_id ~self ->
4010+
Client.Host.set_ssh_enabled_timeout ~rpc ~session_id ~self ~value
4011+
)
4012+
~error:Api_errors.set_ssh_timeout_partially_failed
4013+
40074014
let set_console_timeout ~__context ~self:_ ~value =
40084015
operate ~__context
40094016
~action:(fun ~rpc ~session_id ~self ->
@@ -4016,6 +4023,6 @@ let enable_ssh = Ssh.enable
40164023

40174024
let disable_ssh = Ssh.disable
40184025

4019-
let set_ssh_enabled_timeout ~__context ~self:_ ~value:_ = ()
4026+
let set_ssh_enabled_timeout = Ssh.set_enabled_timeout
40204027

40214028
let set_console_idle_timeout = Ssh.set_console_timeout

0 commit comments

Comments
 (0)