Skip to content

Commit 0922ece

Browse files
authored
CP-54471 Configure Dom0 NTP via XAPI (#6689)
New filed: `host.ntp_mode`, `host.ntp_custom_servers` New API: `host.set_ntp_mode`, `host.set_ntp_custom_servers`, `host.get_ntp_mode`, `host.get_ntp_custom_servers`, `host.get_ntp_servers_status`. **ntp_mode_dhcp**: In this mode, ntp uses the dhcp assigned ntp servers as sources. In Dom0, dhclient triggers `chrony.sh` to update the ntp servers when network event happens. It writes ntp servers to `/run/chrony-dhcp/$interface.sources` and the dir `/run/chrony-dhcp` is included in `chrony.conf`. The dhclient also stores dhcp lease in `/var/lib/xcp/dhclient-$interface.leases`, see https://github.com/xapi-project/xen-api/blob/v25.31.0/ocaml/networkd/lib/network_utils.ml#L925. When switch ntp mode to dhcp, XAPI checks the lease file and finds ntp server then fills chrony-dhcp file. The exec permission of `chrony.sh` is added. When swith ntp mode from dhcp to others, XAPI removes the chrony-dhcp files and the exec permission of `chrony.sh`. The operation is same with xsconsole https://github.com/xapi-project/xsconsole/blob/v11.1.1/XSConsoleData.py#L593. In this feature, xsconsole will change to use XenAPI to manage ntp later to avoid conflict. **ntp_mode_custom**: In this mode, ntp uses `host.ntp_custom_servers` as sources. This is implemented by changing `chrony.conf` and restart chronyd. `host.ntp_custom_servers` is set by the user. **ntp_mode_default**: In this mode, ntp uses default-ntp-servers in XAPI config file.
2 parents b149cba + 469ef69 commit 0922ece

File tree

15 files changed

+520
-3
lines changed

15 files changed

+520
-3
lines changed

ocaml/idl/datamodel_errors.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,6 +2062,9 @@ let _ =
20622062
error Api_errors.sysprep ["vm"; "message"]
20632063
~doc:"VM.sysprep error with details in the message" () ;
20642064

2065+
error Api_errors.invalid_ntp_config ["reason"]
2066+
~doc:"The NTP configuration is invalid." () ;
2067+
20652068
message
20662069
(fst Api_messages.ha_pool_overcommitted)
20672070
~doc:

ocaml/idl/datamodel_host.ml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2544,6 +2544,58 @@ let set_max_cstate =
25442544
]
25452545
~allowed_roles:_R_POOL_OP ()
25462546

2547+
let host_ntp_mode =
2548+
Enum
2549+
( "host_ntp_mode"
2550+
, [
2551+
("ntp_mode_dhcp", "Using NTP servers assigned by DHCP to sync time")
2552+
; ( "ntp_mode_custom"
2553+
, "Using custom NTP servers configured by user to sync time"
2554+
)
2555+
; ("ntp_mode_default", "Using default NTP servers to sync time")
2556+
]
2557+
)
2558+
2559+
let set_ntp_mode =
2560+
call ~name:"set_ntp_mode" ~lifecycle:[] ~doc:"Set the NTP mode for the host"
2561+
~params:
2562+
[
2563+
(Ref _host, "self", "The host")
2564+
; (host_ntp_mode, "value", "The NTP mode to set")
2565+
]
2566+
~allowed_roles:_R_POOL_OP ()
2567+
2568+
let set_ntp_custom_servers =
2569+
call ~name:"set_ntp_custom_servers" ~lifecycle:[]
2570+
~doc:"Set the custom NTP servers for the host"
2571+
~params:
2572+
[
2573+
(Ref _host, "self", "The host")
2574+
; (Set String, "value", "The set of custom NTP servers to configure")
2575+
]
2576+
~allowed_roles:_R_POOL_OP ()
2577+
2578+
let disable_ntp =
2579+
call ~name:"disable_ntp" ~lifecycle:[] ~doc:"Disable NTP on the host"
2580+
~params:[(Ref _host, "self", "The host")]
2581+
~allowed_roles:_R_POOL_OP ()
2582+
2583+
let enable_ntp =
2584+
call ~name:"enable_ntp" ~lifecycle:[] ~doc:"Enable NTP on the host"
2585+
~params:[(Ref _host, "self", "The host")]
2586+
~allowed_roles:_R_POOL_OP ()
2587+
2588+
let get_ntp_servers_status =
2589+
call ~name:"get_ntp_servers_status" ~lifecycle:[]
2590+
~doc:"Get the NTP servers status on the host"
2591+
~params:[(Ref _host, "self", "The host")]
2592+
~result:
2593+
( Map (String, String)
2594+
, "The map of NTP server to its status, status may be \
2595+
synced/combined/uncombined/error/variable/unreachable/unknown"
2596+
)
2597+
~allowed_roles:_R_READ_ONLY ()
2598+
25472599
(** Hosts *)
25482600
let t =
25492601
create_obj ~in_db:true
@@ -2689,6 +2741,11 @@ let t =
26892741
; set_console_idle_timeout
26902742
; set_ssh_auto_mode
26912743
; set_max_cstate
2744+
; set_ntp_mode
2745+
; set_ntp_custom_servers
2746+
; disable_ntp
2747+
; enable_ntp
2748+
; get_ntp_servers_status
26922749
]
26932750
~contents:
26942751
([
@@ -3156,6 +3213,16 @@ let t =
31563213
; field ~qualifier:DynamicRO ~lifecycle:[] ~ty:Bool
31573214
~default_value:(Some (VBool false)) "secure_boot"
31583215
"Whether the host has booted in secure boot mode"
3216+
; field ~qualifier:DynamicRO ~lifecycle:[] ~ty:host_ntp_mode
3217+
~default_value:(Some (VEnum "ntp_mode_dhcp")) "ntp_mode"
3218+
"Indicates NTP servers are assigned by DHCP, or configured by \
3219+
user, or the default servers"
3220+
; field ~qualifier:DynamicRO ~lifecycle:[] ~ty:(Set String)
3221+
~default_value:(Some (VSet [])) "ntp_custom_servers"
3222+
"The set of NTP servers configured for the host"
3223+
; field ~qualifier:DynamicRO ~lifecycle:[] ~ty:Bool
3224+
~default_value:(Some (VBool false)) "ntp_enabled"
3225+
"Reflects whether NTP is enabled on the host"
31593226
]
31603227
)
31613228
()

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 = "6fa9e85157804e2753dee31972b52b61"
6+
let last_known_schema_hash = "34c69ac52c1e6c1d46bc35f610562a58"
77

88
let current_schema_hash : string =
99
let open Datamodel_types in

ocaml/tests/common/test_common.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ let make_host2 ~__context ?(ref = Ref.make ()) ?(uuid = make_uuid ())
221221
~pending_guidances_recommended:[] ~pending_guidances_full:[]
222222
~last_update_hash:"" ~ssh_enabled:true ~ssh_enabled_timeout:0L
223223
~ssh_expiry:Date.epoch ~console_idle_timeout:0L ~ssh_auto_mode:false
224-
~max_cstate:"" ~secure_boot:false ;
224+
~max_cstate:"" ~secure_boot:false ~ntp_mode:`ntp_mode_dhcp
225+
~ntp_custom_servers:[] ~ntp_enabled:false ;
225226
ref
226227

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

ocaml/xapi-cli-server/cli_frontend.ml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,24 @@ let rec cmdtable_data : (string * cmd_spec) list =
10981098
; flags= [Neverforward]
10991099
}
11001100
)
1101+
; ( "host-enable-ntp"
1102+
, {
1103+
reqd= []
1104+
; optn= []
1105+
; help= "Enable ntp service on the host."
1106+
; implementation= No_fd Cli_operations.host_enable_ntp
1107+
; flags= [Host_selectors]
1108+
}
1109+
)
1110+
; ( "host-disable-ntp"
1111+
, {
1112+
reqd= []
1113+
; optn= []
1114+
; help= "Disable ntp service on the host."
1115+
; implementation= No_fd Cli_operations.host_disable_ntp
1116+
; flags= [Host_selectors]
1117+
}
1118+
)
11011119
; ( "patch-upload"
11021120
, {
11031121
reqd= ["file-name"]

ocaml/xapi-cli-server/cli_operations.ml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7817,6 +7817,26 @@ let host_disable_ssh _printer rpc session_id params =
78177817
params []
78187818
)
78197819

7820+
let host_enable_ntp _printer rpc session_id params =
7821+
ignore
7822+
(do_host_op rpc session_id
7823+
(fun _ host ->
7824+
let host = host.getref () in
7825+
Client.Host.enable_ntp ~rpc ~session_id ~self:host
7826+
)
7827+
params []
7828+
)
7829+
7830+
let host_disable_ntp _printer rpc session_id params =
7831+
ignore
7832+
(do_host_op rpc session_id
7833+
(fun _ host ->
7834+
let host = host.getref () in
7835+
Client.Host.disable_ntp ~rpc ~session_id ~self:host
7836+
)
7837+
params []
7838+
)
7839+
78207840
module SDN_controller = struct
78217841
let introduce printer rpc session_id params =
78227842
let port =

ocaml/xapi-cli-server/records.ml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3402,6 +3402,30 @@ let host_record rpc session_id host =
34023402
; make_field ~name:"secure-boot"
34033403
~get:(fun () -> string_of_bool (x ()).API.host_secure_boot)
34043404
()
3405+
; make_field ~name:"ntp-mode"
3406+
~get:(fun () ->
3407+
Record_util.host_ntp_mode_to_string (x ()).API.host_ntp_mode
3408+
)
3409+
~set:(fun value ->
3410+
Client.Host.set_ntp_mode ~rpc ~session_id ~self:host
3411+
~value:(Record_util.host_ntp_mode_of_string value)
3412+
)
3413+
()
3414+
; make_field ~name:"ntp-custom-servers"
3415+
~get:(fun () -> concat_with_comma (x ()).API.host_ntp_custom_servers)
3416+
~get_set:(fun () -> (x ()).API.host_ntp_custom_servers)
3417+
~set:(fun value ->
3418+
Client.Host.set_ntp_custom_servers ~rpc ~session_id ~self:host
3419+
~value:
3420+
(String.split_on_char ',' value
3421+
|> List.map String.trim
3422+
|> List.filter (( <> ) "")
3423+
)
3424+
)
3425+
()
3426+
; make_field ~name:"ntp_enabled"
3427+
~get:(fun () -> string_of_bool (x ()).API.host_ntp_enabled)
3428+
()
34053429
]
34063430
}
34073431

ocaml/xapi-consts/api_errors.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,3 +1438,5 @@ let tls_verification_not_enabled_in_pool =
14381438
add_error "TLS_VERIFICATION_NOT_ENABLED_IN_POOL"
14391439

14401440
let sysprep = add_error "SYSPREP"
1441+
1442+
let invalid_ntp_config = add_error "INVALID_NTP_CONFIG"

ocaml/xapi/dbsync_slave.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ let update_env __context sync_keys =
412412
switched_sync Xapi_globs.sync_max_cstate (fun () ->
413413
Xapi_host.sync_max_cstate ~__context ~host:localhost
414414
) ;
415+
switched_sync Xapi_globs.sync_ntp_config (fun () ->
416+
Xapi_host.sync_ntp_config ~__context ~host:localhost
417+
) ;
415418

416419
switched_sync Xapi_globs.sync_secure_boot (fun () ->
417420
let result =

ocaml/xapi/message_forwarding.ml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4122,6 +4122,41 @@ functor
41224122
let local_fn = Local.Host.set_max_cstate ~self ~value in
41234123
let remote_fn = Client.Host.set_max_cstate ~self ~value in
41244124
do_op_on ~local_fn ~__context ~host:self ~remote_fn
4125+
4126+
let set_ntp_mode ~__context ~self ~value =
4127+
info "Host.set_ntp_mode: host='%s' value='%s'"
4128+
(host_uuid ~__context self)
4129+
(Record_util.host_ntp_mode_to_string value) ;
4130+
let local_fn = Local.Host.set_ntp_mode ~self ~value in
4131+
let remote_fn = Client.Host.set_ntp_mode ~self ~value in
4132+
do_op_on ~local_fn ~__context ~host:self ~remote_fn
4133+
4134+
let set_ntp_custom_servers ~__context ~self ~value =
4135+
info "Host.set_ntp_custom_servers: host='%s' value='%s'"
4136+
(host_uuid ~__context self)
4137+
("[" ^ String.concat ", " value ^ "]") ;
4138+
let local_fn = Local.Host.set_ntp_custom_servers ~self ~value in
4139+
let remote_fn = Client.Host.set_ntp_custom_servers ~self ~value in
4140+
do_op_on ~local_fn ~__context ~host:self ~remote_fn
4141+
4142+
let enable_ntp ~__context ~self =
4143+
info "Host.enable_ntp: host='%s'" (host_uuid ~__context self) ;
4144+
let local_fn = Local.Host.enable_ntp ~self in
4145+
let remote_fn = Client.Host.enable_ntp ~self in
4146+
do_op_on ~local_fn ~__context ~host:self ~remote_fn
4147+
4148+
let disable_ntp ~__context ~self =
4149+
info "Host.disable_ntp: host='%s'" (host_uuid ~__context self) ;
4150+
let local_fn = Local.Host.disable_ntp ~self in
4151+
let remote_fn = Client.Host.disable_ntp ~self in
4152+
do_op_on ~local_fn ~__context ~host:self ~remote_fn
4153+
4154+
let get_ntp_servers_status ~__context ~self =
4155+
info "Host.get_ntp_servers_status: host = '%s'"
4156+
(host_uuid ~__context self) ;
4157+
let local_fn = Local.Host.get_ntp_servers_status ~self in
4158+
let remote_fn = Client.Host.get_ntp_servers_status ~self in
4159+
do_op_on ~local_fn ~__context ~host:self ~remote_fn
41254160
end
41264161

41274162
module Host_crashdump = struct

0 commit comments

Comments
 (0)