@@ -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+
31173162let 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
31273183let 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
31393233let set_console_idle_timeout ~__context ~self ~value =
31403234 let validate_timeout = function
0 commit comments