From 1638b14da99a1dfd89e379dd4b457bb27bcb9a9b Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Tue, 14 Jan 2025 12:32:17 -0600 Subject: T7046: T6946: make world fields reference_tree, running_config mutable The world data structure is fixed in the main loop, however, it will need updates for dynamic loading of reference tree in the presence of addons, respectively, the running config at completion of commit. --- src/session.ml | 4 ++-- src/session.mli | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/session.ml b/src/session.ml index a8eccad..567f999 100644 --- a/src/session.ml +++ b/src/session.ml @@ -10,8 +10,8 @@ type cfg_op = | CfgDelete of string list * string option type world = { - running_config: CT.t; - reference_tree: RT.t; + mutable running_config: CT.t; + mutable reference_tree: RT.t; vyconf_config: Vyconf_config.t; dirs: Directories.t } diff --git a/src/session.mli b/src/session.mli index 16d8e35..2166a80 100644 --- a/src/session.mli +++ b/src/session.mli @@ -3,8 +3,8 @@ type cfg_op = | CfgDelete of string list * string option type world = { - running_config: Vyos1x.Config_tree.t; - reference_tree: Vyos1x.Reference_tree.t; + mutable running_config: Vyos1x.Config_tree.t; + mutable reference_tree: Vyos1x.Reference_tree.t; vyconf_config: Vyconf_config.t; dirs: Directories.t } -- cgit v1.2.3 From 41bb56f9a69001100c5a003f3a0abb03afd3bae2 Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Tue, 14 Jan 2025 12:32:46 -0600 Subject: T7046: move reftree.cache to unique directory This will simplify updates of the reference_tree in case of supplemental contributions, say, addon packages. --- data/vyconfd.conf | 3 +++ src/vyconf_config.ml | 3 +++ src/vyconf_config.mli | 1 + src/vyconfd.ml | 2 +- 4 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/data/vyconfd.conf b/data/vyconfd.conf index e0b16d0..bcde860 100644 --- a/data/vyconfd.conf +++ b/data/vyconfd.conf @@ -5,10 +5,13 @@ name = "vyconfd-minimal" data_dir = "/usr/share/vyos/vyconf" program_dir = "/usr/libexec/vyos" config_dir = "/usr/libexec/vyos/vyconf/config" +reftree_dir = "/usr/libexec/vyos/vyconf/reftree" # paths relative to config_dir primary_config = "config.boot" fallback_config = "config.failsafe" + +# paths relative to reftree_dir reference_tree = "reftree.cache" [vyconf] diff --git a/src/vyconf_config.ml b/src/vyconf_config.ml index 2640c9b..bef607f 100644 --- a/src/vyconf_config.ml +++ b/src/vyconf_config.ml @@ -5,6 +5,7 @@ type t = { data_dir: string; program_dir: string; config_dir: string; + reftree_dir: string; primary_config: string; fallback_config: string; reference_tree: string; @@ -22,6 +23,7 @@ let empty_config = { data_dir = ""; program_dir = ""; config_dir = ""; + reftree_dir = ""; primary_config = ""; fallback_config = ""; reference_tree = ""; @@ -60,6 +62,7 @@ let load filename = let conf = {conf with app_name = mandatory_field conf_toml "appliance" "name"} in let conf = {conf with data_dir = mandatory_field conf_toml "appliance" "data_dir"} in let conf = {conf with config_dir = mandatory_field conf_toml "appliance" "config_dir"} in + let conf = {conf with reftree_dir = mandatory_field conf_toml "appliance" "reftree_dir"} in let conf = {conf with program_dir = mandatory_field conf_toml "appliance" "program_dir"} in let conf = {conf with primary_config = mandatory_field conf_toml "appliance" "primary_config"} in let conf = {conf with fallback_config = mandatory_field conf_toml "appliance" "fallback_config"} in diff --git a/src/vyconf_config.mli b/src/vyconf_config.mli index 1cfeffa..dad574c 100644 --- a/src/vyconf_config.mli +++ b/src/vyconf_config.mli @@ -3,6 +3,7 @@ type t = { data_dir: string; program_dir: string; config_dir: string; + reftree_dir: string; primary_config: string; fallback_config: string; reference_tree: string; diff --git a/src/vyconfd.ml b/src/vyconfd.ml index 7c4caeb..4e8708d 100644 --- a/src/vyconfd.ml +++ b/src/vyconfd.ml @@ -220,7 +220,7 @@ let read_reference_tree file = let make_world config dirs = let open Session in (* the reference_tree json file is generated at vyos-1x build time *) - let reftree = read_reference_tree (FP.concat config.config_dir config.reference_tree) in + let reftree = read_reference_tree (FP.concat config.reftree_dir config.reference_tree) in let running_config = CT.make "" in {running_config=running_config; reference_tree=reftree; vyconf_config=config; dirs=dirs} -- cgit v1.2.3 From 5cb1952f52a8a67905a9361364a0c0823d44ed03 Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Tue, 14 Jan 2025 12:33:06 -0600 Subject: T7046: add request reload_reftree --- data/vyconf.proto | 8 ++++++ src/vycli.ml | 3 +++ src/vyconf_client.ml | 9 +++++++ src/vyconf_client.mli | 2 ++ src/vyconf_client_session.ml | 5 ++++ src/vyconf_client_session.mli | 3 +++ src/vyconf_pbt.ml | 57 +++++++++++++++++++++++++++++++++++++++++++ src/vyconf_pbt.mli | 20 +++++++++++++++ src/vyconfd.ml | 12 +++++++++ 9 files changed, 119 insertions(+) (limited to 'src') diff --git a/data/vyconf.proto b/data/vyconf.proto index d989fb3..a09d84a 100644 --- a/data/vyconf.proto +++ b/data/vyconf.proto @@ -117,6 +117,13 @@ message Request { message ExitConfigurationMode { } + message ReloadReftree { + // this is a temporary workaround for a bug with empty messages, and + // will be removed when the issue is resolved + optional int32 OnBehalfOf = 1; + } + + oneof msg { Status status = 1; SetupSession setup_session = 2; @@ -140,6 +147,7 @@ message Request { ExitConfigurationMode exit_configure = 20; Validate validate = 21; Teardown teardown = 22; + ReloadReftree reload_reftree = 23; } } diff --git a/src/vycli.ml b/src/vycli.ml index 1430a5a..f793ae0 100644 --- a/src/vycli.ml +++ b/src/vycli.ml @@ -11,6 +11,7 @@ type op_t = | OpGetValues | OpListChildren | OpValidate + | OpReloadReftree let token : string option ref = ref None let conf_format_opt = ref "curly" @@ -36,6 +37,7 @@ let args = [ ("--show-config", Arg.Unit (fun () -> op := Some OpShowConfig), "Show the configuration at the specified path"); ("--status", Arg.Unit (fun () -> op := Some OpStatus), "Send a status/keepalive message"); ("--validate", Arg.Unit (fun () -> op := Some OpValidate), "Validate path"); + ("--reload-reftree", Arg.Unit (fun () -> op := Some OpReloadReftree), "Reload reference tree"); ] let config_format_of_string s = @@ -77,6 +79,7 @@ let main socket op path out_format config_format = | OpListChildren -> list_children client path | OpShowConfig -> show_config client path | OpValidate -> validate client path + | OpReloadReftree -> reload_reftree client | _ -> Error "Unimplemented" |> Lwt.return end in match result with diff --git a/src/vyconf_client.ml b/src/vyconf_client.ml index 94348b2..5437428 100644 --- a/src/vyconf_client.ml +++ b/src/vyconf_client.ml @@ -117,3 +117,12 @@ let validate client path = | Success -> Lwt.return (Ok "") | Fail -> Error (Option.value resp.error ~default:"") |> Lwt.return | _ -> Error (Option.value resp.error ~default:"") |> Lwt.return + +let reload_reftree ?(on_behalf_of=None) client = + let id = on_behalf_of |> (function None -> None | Some x -> (Some (Int32.of_int x))) in + let req = Reload_reftree {on_behalf_of=id} in + let%lwt resp = do_request client req in + match resp.status with + | Success -> Ok "" |> Lwt.return + | Fail -> Error (Option.value resp.error ~default:"") |> Lwt.return + | _ -> Error (Option.value resp.error ~default:"") |> Lwt.return diff --git a/src/vyconf_client.mli b/src/vyconf_client.mli index 0feb063..6d74412 100644 --- a/src/vyconf_client.mli +++ b/src/vyconf_client.mli @@ -42,3 +42,5 @@ val list_children : t -> string list -> (string, string) result Lwt.t val show_config : t -> string list -> (string, string) result Lwt.t val validate : t -> string list -> (string, string) result Lwt.t + +val reload_reftree : ?on_behalf_of:(int option) -> t -> (string, string) result Lwt.t diff --git a/src/vyconf_client_session.ml b/src/vyconf_client_session.ml index 70a2a13..407aaff 100644 --- a/src/vyconf_client_session.ml +++ b/src/vyconf_client_session.ml @@ -6,6 +6,7 @@ type op_t = | OpTeardownSession | OpShowConfig | OpValidate + | OpReloadReftree let config_format_of_string s = match s with @@ -42,6 +43,7 @@ let call_op ?(out_format="plain") ?(config_format="curly") socket token op path | OpTeardownSession -> Vyconf_client.teardown_session client | OpShowConfig -> Vyconf_client.show_config client path | OpValidate -> Vyconf_client.validate client path + | OpReloadReftree -> Vyconf_client.reload_reftree client end in Lwt.return result @@ -62,3 +64,6 @@ let session_show_config socket token path = let session_path_exists socket token path = call_op socket (Some token) (Some OpExists) path + +let reload_reference_tree socket = + call_op socket None (Some OpReloadReftree) [] diff --git a/src/vyconf_client_session.mli b/src/vyconf_client_session.mli index 98fa3c2..e000da4 100644 --- a/src/vyconf_client_session.mli +++ b/src/vyconf_client_session.mli @@ -4,6 +4,7 @@ type op_t = | OpTeardownSession | OpShowConfig | OpValidate + | OpReloadReftree val session_init : ?out_format:string -> ?config_format:string -> string -> (string, string) result @@ -14,3 +15,5 @@ val session_validate_path : string -> string -> string list -> (string, string) val session_show_config : string -> string -> string list -> (string, string) result val session_path_exists : string -> string -> string list -> (string, string) result + +val reload_reference_tree : string -> (string, string) result diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml index 4c7fcc6..9d2845d 100644 --- a/src/vyconf_pbt.ml +++ b/src/vyconf_pbt.ml @@ -113,6 +113,10 @@ type request_enter_configuration_mode = { type request_exit_configuration_mode = unit +type request_reload_reftree = { + on_behalf_of : int32 option; +} + type request = | Status | Setup_session of request_setup_session @@ -136,6 +140,7 @@ type request = | Exit_configure | Validate of request_validate | Teardown of request_teardown + | Reload_reftree of request_reload_reftree type request_envelope = { token : string option; @@ -328,6 +333,12 @@ let rec default_request_enter_configuration_mode let rec default_request_exit_configuration_mode = () +let rec default_request_reload_reftree + ?on_behalf_of:((on_behalf_of:int32 option) = None) + () : request_reload_reftree = { + on_behalf_of; +} + let rec default_request (): request = Status let rec default_request_envelope @@ -550,6 +561,14 @@ let default_request_enter_configuration_mode_mutable () : request_enter_configur override_exclusive = false; } +type request_reload_reftree_mutable = { + mutable on_behalf_of : int32 option; +} + +let default_request_reload_reftree_mutable () : request_reload_reftree_mutable = { + on_behalf_of = None; +} + type request_envelope_mutable = { mutable token : string option; mutable request : request; @@ -745,6 +764,12 @@ let rec pp_request_exit_configuration_mode fmt (v:request_exit_configuration_mod in Pbrt.Pp.pp_brk pp_i fmt () +let rec pp_request_reload_reftree fmt (v:request_reload_reftree) = + let pp_i fmt () = + Pbrt.Pp.pp_record_field ~first:true "on_behalf_of" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.on_behalf_of; + in + Pbrt.Pp.pp_brk pp_i fmt () + let rec pp_request fmt (v:request) = match v with | Status -> Format.fprintf fmt "Status" @@ -769,6 +794,7 @@ let rec pp_request fmt (v:request) = | Exit_configure -> Format.fprintf fmt "Exit_configure" | Validate x -> Format.fprintf fmt "@[Validate(@,%a)@]" pp_request_validate x | Teardown x -> Format.fprintf fmt "@[Teardown(@,%a)@]" pp_request_teardown x + | Reload_reftree x -> Format.fprintf fmt "@[Reload_reftree(@,%a)@]" pp_request_reload_reftree x let rec pp_request_envelope fmt (v:request_envelope) = let pp_i fmt () = @@ -1047,6 +1073,15 @@ let rec encode_pb_request_enter_configuration_mode (v:request_enter_configuratio let rec encode_pb_request_exit_configuration_mode (v:request_exit_configuration_mode) encoder = () +let rec encode_pb_request_reload_reftree (v:request_reload_reftree) encoder = + begin match v.on_behalf_of with + | Some x -> + Pbrt.Encoder.int32_as_varint x encoder; + Pbrt.Encoder.key 1 Pbrt.Varint encoder; + | None -> (); + end; + () + let rec encode_pb_request (v:request) encoder = begin match v with | Status -> @@ -1115,6 +1150,9 @@ let rec encode_pb_request (v:request) encoder = | Teardown x -> Pbrt.Encoder.nested encode_pb_request_teardown x encoder; Pbrt.Encoder.key 22 Pbrt.Bytes encoder; + | Reload_reftree x -> + Pbrt.Encoder.nested encode_pb_request_reload_reftree x encoder; + Pbrt.Encoder.key 23 Pbrt.Bytes encoder; end let rec encode_pb_request_envelope (v:request_envelope) encoder = @@ -1705,6 +1743,24 @@ let rec decode_pb_request_exit_configuration_mode d = | Some (_, pk) -> Pbrt.Decoder.unexpected_payload "Unexpected fields in empty message(request_exit_configuration_mode)" pk +let rec decode_pb_request_reload_reftree d = + let v = default_request_reload_reftree_mutable () in + let continue__= ref true in + while !continue__ do + match Pbrt.Decoder.key d with + | None -> ( + ); continue__ := false + | Some (1, Pbrt.Varint) -> begin + v.on_behalf_of <- Some (Pbrt.Decoder.int32_as_varint d); + end + | Some (1, pk) -> + Pbrt.Decoder.unexpected_payload "Message(request_reload_reftree), field(1)" pk + | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind + done; + ({ + on_behalf_of = v.on_behalf_of; + } : request_reload_reftree) + let rec decode_pb_request d = let rec loop () = let ret:request = match Pbrt.Decoder.key d with @@ -1740,6 +1796,7 @@ let rec decode_pb_request d = end | Some (21, _) -> (Validate (decode_pb_request_validate (Pbrt.Decoder.nested d)) : request) | Some (22, _) -> (Teardown (decode_pb_request_teardown (Pbrt.Decoder.nested d)) : request) + | Some (23, _) -> (Reload_reftree (decode_pb_request_reload_reftree (Pbrt.Decoder.nested d)) : request) | Some (n, payload_kind) -> ( Pbrt.Decoder.skip d payload_kind; loop () diff --git a/src/vyconf_pbt.mli b/src/vyconf_pbt.mli index da94655..56cf4ea 100644 --- a/src/vyconf_pbt.mli +++ b/src/vyconf_pbt.mli @@ -120,6 +120,10 @@ type request_enter_configuration_mode = { type request_exit_configuration_mode = unit +type request_reload_reftree = { + on_behalf_of : int32 option; +} + type request = | Status | Setup_session of request_setup_session @@ -143,6 +147,7 @@ type request = | Exit_configure | Validate of request_validate | Teardown of request_teardown + | Reload_reftree of request_reload_reftree type request_envelope = { token : string option; @@ -324,6 +329,12 @@ val default_request_enter_configuration_mode : val default_request_exit_configuration_mode : unit (** [default_request_exit_configuration_mode ()] is the default value for type [request_exit_configuration_mode] *) +val default_request_reload_reftree : + ?on_behalf_of:int32 option -> + unit -> + request_reload_reftree +(** [default_request_reload_reftree ()] is the default value for type [request_reload_reftree] *) + val default_request : unit -> request (** [default_request ()] is the default value for type [request] *) @@ -424,6 +435,9 @@ val pp_request_enter_configuration_mode : Format.formatter -> request_enter_conf val pp_request_exit_configuration_mode : Format.formatter -> request_exit_configuration_mode -> unit (** [pp_request_exit_configuration_mode v] formats v *) +val pp_request_reload_reftree : Format.formatter -> request_reload_reftree -> unit +(** [pp_request_reload_reftree v] formats v *) + val pp_request : Format.formatter -> request -> unit (** [pp_request v] formats v *) @@ -514,6 +528,9 @@ val encode_pb_request_enter_configuration_mode : request_enter_configuration_mod val encode_pb_request_exit_configuration_mode : request_exit_configuration_mode -> Pbrt.Encoder.t -> unit (** [encode_pb_request_exit_configuration_mode v encoder] encodes [v] with the given [encoder] *) +val encode_pb_request_reload_reftree : request_reload_reftree -> Pbrt.Encoder.t -> unit +(** [encode_pb_request_reload_reftree v encoder] encodes [v] with the given [encoder] *) + val encode_pb_request : request -> Pbrt.Encoder.t -> unit (** [encode_pb_request v encoder] encodes [v] with the given [encoder] *) @@ -604,6 +621,9 @@ val decode_pb_request_enter_configuration_mode : Pbrt.Decoder.t -> request_enter val decode_pb_request_exit_configuration_mode : Pbrt.Decoder.t -> request_exit_configuration_mode (** [decode_pb_request_exit_configuration_mode decoder] decodes a [request_exit_configuration_mode] binary value from [decoder] *) +val decode_pb_request_reload_reftree : Pbrt.Decoder.t -> request_reload_reftree +(** [decode_pb_request_reload_reftree decoder] decodes a [request_reload_reftree] binary value from [decoder] *) + val decode_pb_request : Pbrt.Decoder.t -> request (** [decode_pb_request decoder] decodes a [request] binary value from [decoder] *) diff --git a/src/vyconfd.ml b/src/vyconfd.ml index 4e8708d..004ed6f 100644 --- a/src/vyconfd.ml +++ b/src/vyconfd.ml @@ -143,6 +143,17 @@ let validate world token (req: request_validate) = response_tmpl with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)} +let reload_reftree world (_req: request_reload_reftree) = + let config = world.Session.vyconf_config in + let reftree = + Startup.read_reference_tree (FP.concat config.reftree_dir config.reference_tree) + in + match reftree with + | Ok reftree -> + world.reference_tree <- reftree; + {response_tmpl with status=Success} + | Error s -> {response_tmpl with status=Fail; error=(Some s)} + let send_response oc resp = let enc = Pbrt.Encoder.create () in let%lwt () = encode_pb_response resp enc |> return in @@ -167,6 +178,7 @@ let rec handle_connection world ic oc () = match req with | _, Status -> response_tmpl | _, Setup_session r -> setup_session world r + | _, Reload_reftree r -> reload_reftree world r | None, _ -> {response_tmpl with status=Fail; output=(Some "Operation requires session token")} | Some t, Teardown _ -> teardown t | Some t, Configure r -> enter_conf_mode r t -- cgit v1.2.3