summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2025-11-03 13:44:19 +0000
committerGitHub <noreply@github.com>2025-11-03 13:44:19 +0000
commit2482e3f1a073cd9bd3cc260d0cbb4b8b38bd58f7 (patch)
tree8eab6df656276e2ccea49682f5cf402861931583 /src
parent304e4d2a172fe1baf2c1df7f61b7a0a8e40f7d5d (diff)
parentf372408dc6fb5b98d1f0d28bc334d8a5b8016c11 (diff)
downloadvyconf-2482e3f1a073cd9bd3cc260d0cbb4b8b38bd58f7.tar.gz
vyconf-2482e3f1a073cd9bd3cc260d0cbb4b8b38bd58f7.zip
Merge pull request #34 from jestabro/restart-from-cache
T7980: cache running config on commit completion and add option --reload-active-config
Diffstat (limited to 'src')
-rw-r--r--src/session.ml60
-rw-r--r--src/session.mli6
-rw-r--r--src/startup.ml16
-rw-r--r--src/startup.mli2
-rw-r--r--src/vyconfd.ml59
5 files changed, 111 insertions, 32 deletions
diff --git a/src/session.ml b/src/session.ml
index 5f70feb..f5fff2f 100644
--- a/src/session.ml
+++ b/src/session.ml
@@ -251,23 +251,51 @@ let save w s file =
| Error e -> raise (Session_error (Printf.sprintf "Error saving config: %s" e))
| Ok () -> s
-let prepare_commit ?(dry_run=false) w config id pid sudo_user user =
- let at = w.running_config in
- let rt = w.reference_tree in
+let write_running_cache w =
let vc = w.vyconf_config in
- let () =
- try
- IC.write_internal at (FP.concat vc.session_dir vc.running_cache)
- with
- Vyos1x.Internal.Write_error msg -> raise (Session_error msg)
- in
- let () =
- try
- IC.write_internal config (FP.concat vc.session_dir vc.session_cache)
- with
- Vyos1x.Internal.Write_error msg -> raise (Session_error msg)
- in
- CC.make_commit_data ~dry_run:dry_run rt at config id pid sudo_user user
+ try
+ let () =
+ IC.write_internal_atomic
+ w.running_config
+ (FP.concat vc.session_dir vc.running_cache);
+ in Ok ()
+ with
+ Vyos1x.Internal.Write_error msg ->
+ let msg =
+ Printf.sprintf "Write error caching running config: %s" msg
+ in Error msg
+
+let write_session_cache w config =
+ let vc = w.vyconf_config in
+ try
+ let () =
+ IC.write_internal
+ config
+ (FP.concat vc.session_dir vc.session_cache);
+ in Ok ()
+ with
+ Vyos1x.Internal.Write_error msg ->
+ let msg =
+ Printf.sprintf "Write error caching session config: %s" msg
+ in Error msg
+
+let prepare_commit ?(dry_run=false) w s config id =
+ let opt_running = write_running_cache w in
+ let opt_session = write_session_cache w config in
+ match opt_running, opt_session with
+ | Ok (), Ok () ->
+ Ok (CC.make_commit_data
+ ~dry_run:dry_run
+ w.reference_tree
+ w.running_config
+ config
+ id
+ s.client_pid
+ s.client_sudo_user
+ s.client_user)
+ | Error msg, Ok () -> Error msg
+ | Ok (), Error msg -> Error msg
+ | Error msg1, Error msg2 -> Error (Printf.sprintf "%s\n %s" msg1 msg2)
let post_process_commit w s ((c_data: CC.commit_data), proposed_config) =
let ident n v y =
diff --git a/src/session.mli b/src/session.mli
index a08f873..1750f6c 100644
--- a/src/session.mli
+++ b/src/session.mli
@@ -69,7 +69,11 @@ val list_children : world -> session_data -> string list -> string list
val string_of_op : cfg_op -> string
-val prepare_commit : ?dry_run:bool -> world -> Vyos1x.Config_tree.t -> string -> int32 -> string -> string -> Commitd_client.Commit.commit_data
+val write_running_cache : world -> (unit, string) result
+
+val write_session_cache : world -> Vyos1x.Config_tree.t -> (unit, string) result
+
+val prepare_commit : ?dry_run:bool -> world -> session_data -> Vyos1x.Config_tree.t -> string -> (Commitd_client.Commit.commit_data, string) result
val post_process_commit : world -> session_data -> Commitd_client.Commit.commit_data * Vyos1x.Config_tree.t -> Vyos1x.Config_tree.t * Vyos1x.Config_tree.t
diff --git a/src/startup.ml b/src/startup.ml
index 20882cb..e8b2639 100644
--- a/src/startup.ml
+++ b/src/startup.ml
@@ -94,6 +94,16 @@ let load_config_failsafe main fallback =
| Error msg -> panic (Printf.sprintf "Failed to load fallback config %s: %s, exiting" fallback msg)
end
+module IC = Vyos1x.Internal.Make(Vyos1x.Config_tree)
+
+let load_config_cache cache_file =
+ try
+ let cached_config = IC.read_internal cache_file in
+ log_info @@ Printf.sprintf "Reading active config from %s" cache_file;
+ Ok cached_config
+ with Vyos1x.Internal.Read_error msg ->
+ Error (Printf.sprintf "Failed to load active config %s: %s, exiting" cache_file msg)
+
(* Load interface definitions from a directory into a reference tree *)
let load_interface_definitions dir =
let open Vyos1x.Reference_tree in
@@ -111,11 +121,11 @@ let load_interface_definitions dir =
| Error msg -> Error msg end
with Bad_interface_definition msg -> Error msg
-module I = Vyos1x.Internal.Make(Vyos1x.Reference_tree)
+module IR = Vyos1x.Internal.Make(Vyos1x.Reference_tree)
let read_reference_tree file =
try
- let reftree = I.read_internal file in
+ let reftree = IR.read_internal file in
log_info @@ Printf.sprintf "Reading interface definitions from %s" file;
Ok reftree
- with Sys_error msg -> Error msg
+ with Vyos1x.Internal.Read_error msg -> Error msg
diff --git a/src/startup.mli b/src/startup.mli
index 1415953..41c6251 100644
--- a/src/startup.mli
+++ b/src/startup.mli
@@ -14,6 +14,8 @@ val create_server :
(Lwt_unix.file_descr * Lwt_unix.sockaddr -> unit Lwt.t) ->
Lwt_unix.file_descr -> unit -> 'a Lwt.t
+val load_config_cache : string -> (Vyos1x.Config_tree.t, string) result
+
val load_config_failsafe : string -> string -> Vyos1x.Config_tree.t
val load_interface_definitions : string -> (Vyos1x.Reference_tree.t, string) result
diff --git a/src/vyconfd.ml b/src/vyconfd.ml
index 05cd693..a0fe76d 100644
--- a/src/vyconfd.ml
+++ b/src/vyconfd.ml
@@ -25,6 +25,7 @@ let config_file = ref defaults.config_file
let basepath = ref "/"
let log_file = ref None
let legacy_config_path = ref false
+let reload_active_config = ref false
(* Global data *)
let sessions : (string, Session.session_data) Hashtbl.t = Hashtbl.create 10
@@ -43,6 +44,7 @@ let args = [
("--version", Arg.Unit (fun () -> print_endline @@ Version.version_info (); exit 0), "Print version and exit");
("--legacy-config-path", Arg.Unit (fun () -> legacy_config_path := true),
(Printf.sprintf "Load config file from legacy path %s" defaults.legacy_config_path));
+ ("--reload-active-config", Arg.Unit (fun () -> reload_active_config := true), "Reload active config file");
]
let usage = "Usage: " ^ Sys.argv.(0) ^ " [options]"
@@ -274,16 +276,13 @@ let commit world token (req: request_commit) =
let proposed_config = Session.get_proposed_config world s in
let req_dry_run = Option.value req.dry_run ~default:false in
let commit_data =
- Session.prepare_commit
- ~dry_run:req_dry_run
- world
- proposed_config
- token
- s.client_pid
- s.client_sudo_user
- s.client_user
+ Session.prepare_commit ~dry_run:req_dry_run world s proposed_config token
in
- let%lwt received_commit_data = VC.do_commit commit_data in
+ match commit_data with
+ | Error msg ->
+ Lwt.return {response_tmpl with status=Internal_error; error=(Some msg)}
+ | Ok c_data ->
+ let%lwt received_commit_data = VC.do_commit c_data in
let%lwt result_commit_data =
Lwt.return (CC.commit_update received_commit_data)
in
@@ -314,12 +313,25 @@ let commit world token (req: request_commit) =
world.Session.running_config
post_proposed;
aux_changeset = []; }
- in Hashtbl.replace sessions token session
+ in
+ Hashtbl.replace sessions token session
else ();
- let success, msg_str =
+ let write_msg =
+ if not req_dry_run then
+ match Session.write_running_cache world with
+ | Ok () -> ""
+ | Error msg -> msg
+ else ""
+ in
+ let success, result_msg =
result_commit_data.result.success, result_commit_data.result.out
in
+ let msg_str =
+ match write_msg with
+ | "" -> result_msg
+ | _ -> Printf.sprintf "%s\n %s" result_msg write_msg
+ in
match success with
| true -> Lwt.return {response_tmpl with status=Success; output=(Some msg_str)}
| false -> Lwt.return {response_tmpl with status=Fail; output=(Some msg_str)}
@@ -426,6 +438,14 @@ let read_reference_tree file =
| Ok r -> r
| Error s -> Startup.panic s
+let init_write_cache world =
+ (* initial cache of running config; this will be unnecessary once
+ vyconfd is started at boot *)
+ let res = Session.write_running_cache world in
+ match res with
+ | Ok _ -> ()
+ | Error msg -> (Lwt_log.error msg) |> Lwt.ignore_result
+
let make_world config dirs =
let open Session in
(* the reference_tree json file is generated at vyos-1x build time *)
@@ -446,8 +466,23 @@ let () =
| false -> (FP.concat vc.config_dir vc.primary_config)
in
let failsafe_config = (FP.concat vc.config_dir vc.fallback_config) in
+ let restart_cache = (FP.concat vc.session_dir vc.running_cache) in
let config =
- Startup.load_config_failsafe primary_config failsafe_config
+ match !reload_active_config with
+ | true -> let res = Startup.load_config_cache restart_cache in
+ begin
+ match res with
+ | Ok c -> c
+ | Error msg ->
+ let () = (Lwt_log.error msg) |> Lwt.ignore_result in
+ Startup.load_config_failsafe primary_config failsafe_config
+ end
+ | false -> Startup.load_config_failsafe primary_config failsafe_config
in
let world = Session.{world with running_config=config} in
+ let () =
+ match !reload_active_config with
+ | true -> ()
+ | false -> init_write_cache world
+ in
Lwt_main.run @@ main_loop !basepath world ()