Skip to content

Commit 4a67e13

Browse files
authored
CP-308545 Add host.timezone (#6758)
- New filed: host.timezone - APIs: host.set_timezone, host.get_timezone, host.list_timezones - host.timezone dbsync
2 parents 0d72fdd + f677ea7 commit 4a67e13

File tree

9 files changed

+93
-3
lines changed

9 files changed

+93
-3
lines changed

ocaml/idl/datamodel_host.ml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2627,6 +2627,25 @@ let get_ntp_servers_status =
26272627
)
26282628
~allowed_roles:_R_READ_ONLY ()
26292629

2630+
let set_timezone =
2631+
call ~name:"set_timezone" ~lifecycle:[] ~doc:"Set the host's timezone."
2632+
~params:
2633+
[
2634+
(Ref _host, "self", "The host")
2635+
; ( String
2636+
, "value"
2637+
, "The time zone identifier as defined in the IANA Time Zone Database"
2638+
)
2639+
]
2640+
~allowed_roles:_R_POOL_OP ()
2641+
2642+
let list_timezones =
2643+
call ~name:"list_timezones" ~lifecycle:[]
2644+
~doc:"List all available timezones on the host."
2645+
~params:[(Ref _host, "self", "The host")]
2646+
~result:(Set String, "The set of available timezones on the host")
2647+
~allowed_roles:_R_READ_ONLY ()
2648+
26302649
(** Hosts *)
26312650
let t =
26322651
create_obj ~in_db:true
@@ -2779,6 +2798,8 @@ let t =
27792798
; disable_ntp
27802799
; enable_ntp
27812800
; get_ntp_servers_status
2801+
; set_timezone
2802+
; list_timezones
27822803
]
27832804
~contents:
27842805
([
@@ -3256,6 +3277,9 @@ let t =
32563277
; field ~qualifier:DynamicRO ~lifecycle:[] ~ty:Bool
32573278
~default_value:(Some (VBool false)) "ntp_enabled"
32583279
"Reflects whether NTP is enabled on the host"
3280+
; field ~qualifier:DynamicRO ~lifecycle:[] ~ty:String
3281+
~default_value:(Some (VString "UTC")) "timezone"
3282+
"The time zone identifier as defined in the IANA Time Zone Database"
32593283
]
32603284
)
32613285
()

ocaml/idl/schematest.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ let hash x = Digest.string x |> Digest.to_hex
33
(* BEWARE: if this changes, check that schema has been bumped accordingly in
44
ocaml/idl/datamodel_common.ml, usually schema_minor_vsn *)
55

6-
let last_known_schema_hash = "34c69ac52c1e6c1d46bc35f610562a58"
6+
let last_known_schema_hash = "c72edb27945bceb074de3fa54381ddd4"
77

88
let current_schema_hash : string =
99
let open Datamodel_types in

ocaml/tests/common/test_common.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ let make_host2 ~__context ?(ref = Ref.make ()) ?(uuid = make_uuid ())
225225
~last_update_hash:"" ~ssh_enabled:true ~ssh_enabled_timeout:0L
226226
~ssh_expiry:Date.epoch ~console_idle_timeout:0L ~ssh_auto_mode:false
227227
~max_cstate:"" ~secure_boot:false ~ntp_mode:`ntp_mode_dhcp
228-
~ntp_custom_servers:[] ~ntp_enabled:false ;
228+
~ntp_custom_servers:[] ~ntp_enabled:false ~timezone:"UTC" ;
229229
ref
230230

231231
let make_pif ~__context ~network ~host ?(device = "eth0")

ocaml/xapi-cli-server/records.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3426,6 +3426,12 @@ let host_record rpc session_id host =
34263426
; make_field ~name:"ntp_enabled"
34273427
~get:(fun () -> string_of_bool (x ()).API.host_ntp_enabled)
34283428
()
3429+
; make_field ~name:"timezone"
3430+
~get:(fun () -> (x ()).API.host_timezone)
3431+
~set:(fun value ->
3432+
Client.Host.set_timezone ~rpc ~session_id ~self:host ~value
3433+
)
3434+
()
34293435
]
34303436
}
34313437

ocaml/xapi/dbsync_slave.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,18 @@ let update_env __context sync_keys =
418418
switched_sync Xapi_globs.sync_ntp_config (fun () ->
419419
Xapi_host.sync_ntp_config ~__context ~host:localhost
420420
) ;
421+
switched_sync Xapi_globs.sync_timezone (fun () ->
422+
let timezone =
423+
try
424+
let linkpath = Unix.realpath "/etc/localtime" in
425+
Scanf.sscanf linkpath "/usr/share/zoneinfo/%s" (fun tz -> tz)
426+
with e ->
427+
warn "%s error when sync timezone: %s" __FUNCTION__
428+
(Printexc.to_string e) ;
429+
"UTC"
430+
in
431+
Db.Host.set_timezone ~__context ~self:localhost ~value:timezone
432+
) ;
421433

422434
switched_sync Xapi_globs.sync_secure_boot (fun () ->
423435
let result =

ocaml/xapi/message_forwarding.ml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4170,6 +4170,20 @@ functor
41704170
let local_fn = Local.Host.get_ntp_servers_status ~self in
41714171
let remote_fn = Client.Host.get_ntp_servers_status ~self in
41724172
do_op_on ~local_fn ~__context ~host:self ~remote_fn
4173+
4174+
let set_timezone ~__context ~self ~value =
4175+
info "Host.set_timezone: host = '%s'; value = '%s'"
4176+
(host_uuid ~__context self)
4177+
value ;
4178+
let local_fn = Local.Host.set_timezone ~self ~value in
4179+
let remote_fn = Client.Host.set_timezone ~self ~value in
4180+
do_op_on ~local_fn ~__context ~host:self ~remote_fn
4181+
4182+
let list_timezones ~__context ~self =
4183+
info "Host.list_timezones: host = '%s'" (host_uuid ~__context self) ;
4184+
let local_fn = Local.Host.list_timezones ~self in
4185+
let remote_fn = Client.Host.list_timezones ~self in
4186+
do_op_on ~local_fn ~__context ~host:self ~remote_fn
41734187
end
41744188

41754189
module Host_crashdump = struct

ocaml/xapi/xapi_globs.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,8 @@ let sync_max_cstate = "sync_max_cstate"
383383

384384
let sync_ntp_config = "sync_ntp_config"
385385

386+
let sync_timezone = "sync_timezone"
387+
386388
let sync_secure_boot = "sync_secure_boot"
387389

388390
let sync_pci_devices = "sync_pci_devices"
@@ -812,6 +814,8 @@ let ntp_dhcp_dir = ref "/run/chrony-dhcp"
812814

813815
let ntp_client_path = ref "/usr/bin/chronyc"
814816

817+
let timedatectl = ref "/usr/bin/timedatectl"
818+
815819
let udhcpd_skel = ref (Filename.concat "/etc/xensource" "udhcpd.skel")
816820

817821
let udhcpd_leases_db = ref "/var/lib/xcp/dhcp-leases.db"
@@ -1907,6 +1911,11 @@ let other_options =
19071911
, (fun () -> !ntp_client_path)
19081912
, "Path to the ntp client binary"
19091913
)
1914+
; ( "timedatectl"
1915+
, Arg.Set_string timedatectl
1916+
, (fun () -> !timedatectl)
1917+
, "Path to the timedatectl executable"
1918+
)
19101919
; gen_list_option "legacy-default-ntp-servers"
19111920
"space-separated list of legacy default NTP servers"
19121921
(fun s -> s)

ocaml/xapi/xapi_host.ml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ let create ~__context ~uuid ~name_label ~name_description:_ ~hostname ~address
10951095
~pending_guidances_recommended:[] ~pending_guidances_full:[] ~ssh_enabled
10961096
~ssh_enabled_timeout ~ssh_expiry ~console_idle_timeout ~ssh_auto_mode
10971097
~max_cstate:"" ~secure_boot ~ntp_mode:`ntp_mode_dhcp ~ntp_custom_servers:[]
1098-
~ntp_enabled:false ;
1098+
~ntp_enabled:false ~timezone:"UTC" ;
10991099
(* If the host we're creating is us, make sure its set to live *)
11001100
Db.Host_metrics.set_last_updated ~__context ~self:metrics ~value:(Date.now ()) ;
11011101
Db.Host_metrics.set_live ~__context ~self:metrics ~value:host_is_us ;
@@ -3561,3 +3561,23 @@ let get_ntp_servers_status ~__context ~self:_ =
35613561
Xapi_host_ntp.get_servers_status ()
35623562
else
35633563
[]
3564+
3565+
let set_timezone ~__context ~self ~value =
3566+
try
3567+
let _ =
3568+
Helpers.call_script !Xapi_globs.timedatectl ["set-timezone"; value]
3569+
in
3570+
Db.Host.set_timezone ~__context ~self ~value
3571+
with
3572+
| Forkhelpers.Spawn_internal_error (stderr, _, _)
3573+
when String.starts_with ~prefix:"Failed to set time zone: Invalid" stderr ->
3574+
raise
3575+
(Api_errors.Server_error (Api_errors.invalid_value, ["timezone"; value]))
3576+
| e ->
3577+
Helpers.internal_error "%s" (ExnHelper.string_of_exn e)
3578+
3579+
let list_timezones ~__context ~self:_ =
3580+
try
3581+
Helpers.call_script !Xapi_globs.timedatectl ["list-timezones"]
3582+
|> Astring.String.cuts ~empty:false ~sep:"\n"
3583+
with e -> Helpers.internal_error "%s" (ExnHelper.string_of_exn e)

ocaml/xapi/xapi_host.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,3 +627,8 @@ val sync_ntp_config : __context:Context.t -> host:API.ref_host -> unit
627627

628628
val get_ntp_servers_status :
629629
__context:Context.t -> self:API.ref_host -> (string * string) list
630+
631+
val set_timezone :
632+
__context:Context.t -> self:API.ref_host -> value:string -> unit
633+
634+
val list_timezones : __context:Context.t -> self:API.ref_host -> string list

0 commit comments

Comments
 (0)