@@ -3114,26 +3114,181 @@ 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 _ ->
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) ;
31223181 raise
31233182 (Api_errors. Server_error
3124- (Api_errors. enable_ssh_failed, [Ref. string_of self])
3183+ ( Api_errors. enable_ssh_failed
3184+ , [Ref. string_of self; Printexc. to_string e]
3185+ )
31253186 )
31263187
31273188let disable_ssh ~__context ~self =
31283189 try
3190+ debug " Disabling SSH for host %s" (Db.Host. get_uuid ~__context ~self ) ;
3191+
3192+ remove_disable_ssh_job ~__context ~self ;
3193+
31293194 Xapi_systemctl. disable ~wait_until_success: false " sshd" ;
3130- Xapi_systemctl. stop ~wait_until_success: false " sshd"
3131- with _ ->
3195+ Xapi_systemctl. stop ~wait_until_success: false " sshd" ;
3196+ Db.Host. set_ssh_enabled ~__context ~self ~value: false ;
3197+
3198+ let expiry_time =
3199+ Ptime_clock. now () |> Ptime. to_float_s |> Date. of_unix_time
3200+ in
3201+ Db.Host. set_ssh_expiry ~__context ~self ~value: expiry_time
3202+ with e ->
3203+ error " Failed to disable SSH on host %s: %s" (Ref. string_of self)
3204+ (Printexc. to_string e) ;
31323205 raise
31333206 (Api_errors. Server_error
31343207 (Api_errors. disable_ssh_failed, [Ref. string_of self])
31353208 )
31363209
3137- let set_ssh_enabled_timeout ~__context ~self :_ ~value :_ = ()
3210+ let set_ssh_enabled_timeout ~__context ~self ~value =
3211+ let validate_timeout value =
3212+ if value < 0L || value > 172800L then
3213+ raise
3214+ (Api_errors. Server_error
3215+ ( Api_errors. invalid_value
3216+ , [
3217+ " timeout"
3218+ ; Int64. to_string value
3219+ ; " must be between 0 and 2*24*60*60 seconds"
3220+ ]
3221+ )
3222+ )
3223+ else
3224+ value
3225+ in
3226+ let timeout = validate_timeout value in
3227+ debug " Setting SSH timeout for host %s to %Ld seconds"
3228+ (Db.Host. get_uuid ~__context ~self )
3229+ timeout ;
3230+ Db.Host. set_ssh_enabled_timeout ~__context ~self ~value: timeout ;
3231+ match Db.Host. get_ssh_enabled ~__context ~self with
3232+ | false ->
3233+ ()
3234+ | true -> (
3235+ match timeout with
3236+ | 0L ->
3237+ remove_disable_ssh_job ~__context ~self ;
3238+ Db.Host. set_ssh_expiry ~__context ~self ~value: Date. epoch
3239+ | t ->
3240+ schedule_disable_ssh_job ~__context ~self ~timeout: t ;
3241+ Db.Host. set_ssh_enabled_timeout ~__context ~self ~value: timeout
3242+ )
3243+
3244+ let set_console_idle_timeout ~__context ~self ~value =
3245+ let validate_timeout = function
3246+ | timeout when timeout > = 0L ->
3247+ timeout
3248+ | timeout ->
3249+ raise
3250+ (Api_errors. Server_error
3251+ ( Api_errors. invalid_value
3252+ , [
3253+ " console_timeout"
3254+ ; Int64. to_string timeout
3255+ ; " must be a positive integer"
3256+ ]
3257+ )
3258+ )
3259+ in
3260+
3261+ let console_timeout = validate_timeout value in
3262+ let bashrc = " /root/.bashrc" in
31383263
3139- let set_console_idle_timeout ~__context ~self :_ ~value :_ = ()
3264+ try
3265+ let lines = Unixext. read_lines ~path: bashrc in
3266+ let filtered =
3267+ List. filter
3268+ (fun line -> not (String. starts_with ~prefix: " export TMOUT=" line))
3269+ lines
3270+ in
3271+
3272+ let new_lines =
3273+ match console_timeout with
3274+ | 0L ->
3275+ filtered
3276+ | timeout ->
3277+ filtered @ [Printf. sprintf " export TMOUT=%Ld" timeout]
3278+ in
3279+ let content = String. concat " \n " new_lines ^ " \n " in
3280+
3281+ Unixext. atomic_write_to_file bashrc 0o0644 (fun fd ->
3282+ Unix. write fd (Bytes. of_string content) 0 (String. length content)
3283+ |> ignore
3284+ ) ;
3285+
3286+ Db.Host. set_console_idle_timeout ~__context ~self ~value: console_timeout
3287+ with e ->
3288+ error " Failed to configure console timeout: %s" (Printexc. to_string e) ;
3289+ raise
3290+ (Api_errors. Server_error
3291+ ( Api_errors. set_console_idle_timeout_failed
3292+ , [" Failed to configure console timeout" ; Printexc. to_string e]
3293+ )
3294+ )
0 commit comments