Skip to content

Commit a3bc84d

Browse files
committed
CP-53478: Implement SSH enabeld timeout API for Dom0 SSH control
Implemented XAPI APIs: - `host.set_ssh_enabled_timeout` - `pool.set_ssh_enabled_timeout` These APIs allow XAPI to configure timeout for SSH service. `host.enable_ssh` now also supports enabling the SSH service with a ssh_enabled_timeout Signed-off-by: Lunfan Zhang <[email protected]>
1 parent f67dcf7 commit a3bc84d

File tree

5 files changed

+111
-18
lines changed

5 files changed

+111
-18
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_globs.ml

+4
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,10 @@ let reboot_required_hfxs = ref "/run/reboot-required.hfxs"
12891289

12901290
let console_timeout_profile_path = ref "/etc/profile.d/console_timeout.sh"
12911291

1292+
let job_for_disable_ssh = ref "Disable SSH"
1293+
1294+
let ssh_service = ref "sshd"
1295+
12921296
(* Fingerprint of default patch key *)
12931297
let citrix_patch_key =
12941298
"NERDNTUzMDMwRUMwNDFFNDI4N0M4OEVCRUFEMzlGOTJEOEE5REUyNg=="

ocaml/xapi/xapi_host.ml

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

3117-
let enable_ssh ~__context ~self =
3117+
let disable_ssh_internal ~__context ~self =
31183118
try
3119-
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-
)
3119+
debug "Disabling SSH for host %s" (Helpers.get_localhost_uuid ()) ;
3120+
Xapi_systemctl.disable ~wait_until_success:false !Xapi_globs.ssh_service ;
3121+
Xapi_systemctl.stop ~wait_until_success:false !Xapi_globs.ssh_service ;
3122+
Db.Host.set_ssh_enabled ~__context ~self ~value:false
3123+
with e ->
3124+
error "Failed to disable SSH for host %s: %s" (Ref.string_of self)
3125+
(Printexc.to_string e) ;
3126+
Helpers.internal_error "Failed to disable SSH: %s" (Printexc.to_string e)
3127+
3128+
let schedule_disable_ssh_job ~__context ~self ~timeout =
3129+
let host_uuid = Helpers.get_localhost_uuid () in
3130+
let expiry_time =
3131+
match
3132+
Ptime.add_span (Ptime_clock.now ())
3133+
(Ptime.Span.of_int_s (Int64.to_int timeout))
3134+
with
3135+
| None ->
3136+
error "Invalid SSH timeout: %Ld" timeout ;
3137+
raise
3138+
(Api_errors.Server_error
3139+
( Api_errors.invalid_value
3140+
, ["ssh_enabled_timeout"; Int64.to_string timeout]
3141+
)
3142+
)
3143+
| Some t ->
3144+
Ptime.to_float_s t |> Date.of_unix_time
3145+
in
31263146

3127-
let disable_ssh ~__context ~self =
3147+
debug "Scheduling SSH disable job for host %s with timeout %Ld seconds"
3148+
host_uuid timeout ;
3149+
3150+
(* Remove any existing job first *)
3151+
Xapi_stdext_threads_scheduler.Scheduler.remove_from_queue
3152+
!Xapi_globs.job_for_disable_ssh ;
3153+
3154+
Xapi_stdext_threads_scheduler.Scheduler.add_to_queue
3155+
!Xapi_globs.job_for_disable_ssh
3156+
Xapi_stdext_threads_scheduler.Scheduler.OneShot (Int64.to_float timeout)
3157+
(fun () -> disable_ssh_internal ~__context ~self
3158+
) ;
3159+
3160+
Db.Host.set_ssh_expiry ~__context ~self ~value:expiry_time
3161+
3162+
let enable_ssh ~__context ~self =
31283163
try
3129-
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-
)
3164+
debug "Enabling SSH for host %s" (Helpers.get_localhost_uuid ()) ;
3165+
3166+
Xapi_systemctl.enable ~wait_until_success:false !Xapi_globs.ssh_service ;
3167+
Xapi_systemctl.start ~wait_until_success:false !Xapi_globs.ssh_service ;
3168+
3169+
let timeout = Db.Host.get_ssh_enabled_timeout ~__context ~self in
3170+
( match timeout with
3171+
| 0L ->
3172+
Xapi_stdext_threads_scheduler.Scheduler.remove_from_queue
3173+
!Xapi_globs.job_for_disable_ssh
3174+
| t ->
3175+
schedule_disable_ssh_job ~__context ~self ~timeout:t
3176+
) ;
31363177

3137-
let set_ssh_enabled_timeout ~__context ~self:_ ~value:_ = ()
3178+
Db.Host.set_ssh_enabled ~__context ~self ~value:true
3179+
with e ->
3180+
error "Failed to enable SSH on host %s: %s" (Ref.string_of self)
3181+
(Printexc.to_string e) ;
3182+
Helpers.internal_error "Failed to enable SSH: %s" (Printexc.to_string e)
3183+
3184+
let disable_ssh ~__context ~self =
3185+
Xapi_stdext_threads_scheduler.Scheduler.remove_from_queue
3186+
!Xapi_globs.job_for_disable_ssh ;
3187+
disable_ssh_internal ~__context ~self ;
3188+
Db.Host.set_ssh_expiry ~__context ~self ~value:(Date.now ())
3189+
3190+
let set_ssh_enabled_timeout ~__context ~self ~value =
3191+
let validate_timeout value =
3192+
(* the max timeout is two days: 172800L = 2*24*60*60 *)
3193+
if value < 0L || value > 172800L then
3194+
raise
3195+
(Api_errors.Server_error
3196+
( Api_errors.invalid_value
3197+
, ["ssh_enabled_timeout"; Int64.to_string value]
3198+
)
3199+
)
3200+
in
3201+
validate_timeout value ;
3202+
debug "Setting SSH timeout for host %s to %Ld seconds"
3203+
(Db.Host.get_uuid ~__context ~self)
3204+
value ;
3205+
Db.Host.set_ssh_enabled_timeout ~__context ~self ~value ;
3206+
if Db.Host.get_ssh_enabled ~__context ~self then
3207+
match value with
3208+
| 0L ->
3209+
Xapi_stdext_threads_scheduler.Scheduler.remove_from_queue
3210+
!Xapi_globs.job_for_disable_ssh ;
3211+
Db.Host.set_ssh_expiry ~__context ~self ~value:Date.epoch
3212+
| t ->
3213+
schedule_disable_ssh_job ~__context ~self ~timeout:t
31383214

31393215
let set_console_idle_timeout ~__context ~self ~value =
31403216
let assert_timeout_valid timeout =

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)