Skip to content

Commit 2482e3f

Browse files
authored
Merge pull request #34 from jestabro/restart-from-cache
T7980: cache running config on commit completion and add option --reload-active-config
2 parents 304e4d2 + f372408 commit 2482e3f

File tree

5 files changed

+111
-32
lines changed

5 files changed

+111
-32
lines changed

src/session.ml

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -251,23 +251,51 @@ let save w s file =
251251
| Error e -> raise (Session_error (Printf.sprintf "Error saving config: %s" e))
252252
| Ok () -> s
253253

254-
let prepare_commit ?(dry_run=false) w config id pid sudo_user user =
255-
let at = w.running_config in
256-
let rt = w.reference_tree in
254+
let write_running_cache w =
257255
let vc = w.vyconf_config in
258-
let () =
259-
try
260-
IC.write_internal at (FP.concat vc.session_dir vc.running_cache)
261-
with
262-
Vyos1x.Internal.Write_error msg -> raise (Session_error msg)
263-
in
264-
let () =
265-
try
266-
IC.write_internal config (FP.concat vc.session_dir vc.session_cache)
267-
with
268-
Vyos1x.Internal.Write_error msg -> raise (Session_error msg)
269-
in
270-
CC.make_commit_data ~dry_run:dry_run rt at config id pid sudo_user user
256+
try
257+
let () =
258+
IC.write_internal_atomic
259+
w.running_config
260+
(FP.concat vc.session_dir vc.running_cache);
261+
in Ok ()
262+
with
263+
Vyos1x.Internal.Write_error msg ->
264+
let msg =
265+
Printf.sprintf "Write error caching running config: %s" msg
266+
in Error msg
267+
268+
let write_session_cache w config =
269+
let vc = w.vyconf_config in
270+
try
271+
let () =
272+
IC.write_internal
273+
config
274+
(FP.concat vc.session_dir vc.session_cache);
275+
in Ok ()
276+
with
277+
Vyos1x.Internal.Write_error msg ->
278+
let msg =
279+
Printf.sprintf "Write error caching session config: %s" msg
280+
in Error msg
281+
282+
let prepare_commit ?(dry_run=false) w s config id =
283+
let opt_running = write_running_cache w in
284+
let opt_session = write_session_cache w config in
285+
match opt_running, opt_session with
286+
| Ok (), Ok () ->
287+
Ok (CC.make_commit_data
288+
~dry_run:dry_run
289+
w.reference_tree
290+
w.running_config
291+
config
292+
id
293+
s.client_pid
294+
s.client_sudo_user
295+
s.client_user)
296+
| Error msg, Ok () -> Error msg
297+
| Ok (), Error msg -> Error msg
298+
| Error msg1, Error msg2 -> Error (Printf.sprintf "%s\n %s" msg1 msg2)
271299

272300
let post_process_commit w s ((c_data: CC.commit_data), proposed_config) =
273301
let ident n v y =

src/session.mli

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ val list_children : world -> session_data -> string list -> string list
6969

7070
val string_of_op : cfg_op -> string
7171

72-
val prepare_commit : ?dry_run:bool -> world -> Vyos1x.Config_tree.t -> string -> int32 -> string -> string -> Commitd_client.Commit.commit_data
72+
val write_running_cache : world -> (unit, string) result
73+
74+
val write_session_cache : world -> Vyos1x.Config_tree.t -> (unit, string) result
75+
76+
val prepare_commit : ?dry_run:bool -> world -> session_data -> Vyos1x.Config_tree.t -> string -> (Commitd_client.Commit.commit_data, string) result
7377

7478
val post_process_commit : world -> session_data -> Commitd_client.Commit.commit_data * Vyos1x.Config_tree.t -> Vyos1x.Config_tree.t * Vyos1x.Config_tree.t
7579

src/startup.ml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ let load_config_failsafe main fallback =
9494
| Error msg -> panic (Printf.sprintf "Failed to load fallback config %s: %s, exiting" fallback msg)
9595
end
9696

97+
module IC = Vyos1x.Internal.Make(Vyos1x.Config_tree)
98+
99+
let load_config_cache cache_file =
100+
try
101+
let cached_config = IC.read_internal cache_file in
102+
log_info @@ Printf.sprintf "Reading active config from %s" cache_file;
103+
Ok cached_config
104+
with Vyos1x.Internal.Read_error msg ->
105+
Error (Printf.sprintf "Failed to load active config %s: %s, exiting" cache_file msg)
106+
97107
(* Load interface definitions from a directory into a reference tree *)
98108
let load_interface_definitions dir =
99109
let open Vyos1x.Reference_tree in
@@ -111,11 +121,11 @@ let load_interface_definitions dir =
111121
| Error msg -> Error msg end
112122
with Bad_interface_definition msg -> Error msg
113123

114-
module I = Vyos1x.Internal.Make(Vyos1x.Reference_tree)
124+
module IR = Vyos1x.Internal.Make(Vyos1x.Reference_tree)
115125

116126
let read_reference_tree file =
117127
try
118-
let reftree = I.read_internal file in
128+
let reftree = IR.read_internal file in
119129
log_info @@ Printf.sprintf "Reading interface definitions from %s" file;
120130
Ok reftree
121-
with Sys_error msg -> Error msg
131+
with Vyos1x.Internal.Read_error msg -> Error msg

src/startup.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ val create_server :
1414
(Lwt_unix.file_descr * Lwt_unix.sockaddr -> unit Lwt.t) ->
1515
Lwt_unix.file_descr -> unit -> 'a Lwt.t
1616

17+
val load_config_cache : string -> (Vyos1x.Config_tree.t, string) result
18+
1719
val load_config_failsafe : string -> string -> Vyos1x.Config_tree.t
1820

1921
val load_interface_definitions : string -> (Vyos1x.Reference_tree.t, string) result

src/vyconfd.ml

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ let config_file = ref defaults.config_file
2525
let basepath = ref "/"
2626
let log_file = ref None
2727
let legacy_config_path = ref false
28+
let reload_active_config = ref false
2829

2930
(* Global data *)
3031
let sessions : (string, Session.session_data) Hashtbl.t = Hashtbl.create 10
@@ -43,6 +44,7 @@ let args = [
4344
("--version", Arg.Unit (fun () -> print_endline @@ Version.version_info (); exit 0), "Print version and exit");
4445
("--legacy-config-path", Arg.Unit (fun () -> legacy_config_path := true),
4546
(Printf.sprintf "Load config file from legacy path %s" defaults.legacy_config_path));
47+
("--reload-active-config", Arg.Unit (fun () -> reload_active_config := true), "Reload active config file");
4648
]
4749
let usage = "Usage: " ^ Sys.argv.(0) ^ " [options]"
4850

@@ -274,16 +276,13 @@ let commit world token (req: request_commit) =
274276
let proposed_config = Session.get_proposed_config world s in
275277
let req_dry_run = Option.value req.dry_run ~default:false in
276278
let commit_data =
277-
Session.prepare_commit
278-
~dry_run:req_dry_run
279-
world
280-
proposed_config
281-
token
282-
s.client_pid
283-
s.client_sudo_user
284-
s.client_user
279+
Session.prepare_commit ~dry_run:req_dry_run world s proposed_config token
285280
in
286-
let%lwt received_commit_data = VC.do_commit commit_data in
281+
match commit_data with
282+
| Error msg ->
283+
Lwt.return {response_tmpl with status=Internal_error; error=(Some msg)}
284+
| Ok c_data ->
285+
let%lwt received_commit_data = VC.do_commit c_data in
287286
let%lwt result_commit_data =
288287
Lwt.return (CC.commit_update received_commit_data)
289288
in
@@ -314,12 +313,25 @@ let commit world token (req: request_commit) =
314313
world.Session.running_config
315314
post_proposed;
316315
aux_changeset = []; }
317-
in Hashtbl.replace sessions token session
316+
in
317+
Hashtbl.replace sessions token session
318318
else ();
319319

320-
let success, msg_str =
320+
let write_msg =
321+
if not req_dry_run then
322+
match Session.write_running_cache world with
323+
| Ok () -> ""
324+
| Error msg -> msg
325+
else ""
326+
in
327+
let success, result_msg =
321328
result_commit_data.result.success, result_commit_data.result.out
322329
in
330+
let msg_str =
331+
match write_msg with
332+
| "" -> result_msg
333+
| _ -> Printf.sprintf "%s\n %s" result_msg write_msg
334+
in
323335
match success with
324336
| true -> Lwt.return {response_tmpl with status=Success; output=(Some msg_str)}
325337
| false -> Lwt.return {response_tmpl with status=Fail; output=(Some msg_str)}
@@ -426,6 +438,14 @@ let read_reference_tree file =
426438
| Ok r -> r
427439
| Error s -> Startup.panic s
428440

441+
let init_write_cache world =
442+
(* initial cache of running config; this will be unnecessary once
443+
vyconfd is started at boot *)
444+
let res = Session.write_running_cache world in
445+
match res with
446+
| Ok _ -> ()
447+
| Error msg -> (Lwt_log.error msg) |> Lwt.ignore_result
448+
429449
let make_world config dirs =
430450
let open Session in
431451
(* the reference_tree json file is generated at vyos-1x build time *)
@@ -446,8 +466,23 @@ let () =
446466
| false -> (FP.concat vc.config_dir vc.primary_config)
447467
in
448468
let failsafe_config = (FP.concat vc.config_dir vc.fallback_config) in
469+
let restart_cache = (FP.concat vc.session_dir vc.running_cache) in
449470
let config =
450-
Startup.load_config_failsafe primary_config failsafe_config
471+
match !reload_active_config with
472+
| true -> let res = Startup.load_config_cache restart_cache in
473+
begin
474+
match res with
475+
| Ok c -> c
476+
| Error msg ->
477+
let () = (Lwt_log.error msg) |> Lwt.ignore_result in
478+
Startup.load_config_failsafe primary_config failsafe_config
479+
end
480+
| false -> Startup.load_config_failsafe primary_config failsafe_config
451481
in
452482
let world = Session.{world with running_config=config} in
483+
let () =
484+
match !reload_active_config with
485+
| true -> ()
486+
| false -> init_write_cache world
487+
in
453488
Lwt_main.run @@ main_loop !basepath world ()

0 commit comments

Comments
 (0)