@@ -3114,26 +3114,181 @@ let emergency_clear_mandatory_guidance ~__context =
3114
3114
) ;
3115
3115
Db.Host. set_pending_guidances ~__context ~self ~value: []
3116
3116
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
+
3117
3162
let enable_ssh ~__context ~self =
3118
3163
try
3164
+ debug " Enabling SSH for host %s" (Db.Host. get_uuid ~__context ~self ) ;
3165
+
3119
3166
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) ;
3122
3181
raise
3123
3182
(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
+ )
3125
3186
)
3126
3187
3127
3188
let disable_ssh ~__context ~self =
3128
3189
try
3190
+ debug " Disabling SSH for host %s" (Db.Host. get_uuid ~__context ~self ) ;
3191
+
3192
+ remove_disable_ssh_job ~__context ~self ;
3193
+
3129
3194
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) ;
3132
3205
raise
3133
3206
(Api_errors. Server_error
3134
3207
(Api_errors. disable_ssh_failed, [Ref. string_of self])
3135
3208
)
3136
3209
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
3138
3263
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