summaryrefslogtreecommitdiff
path: root/src/vyconfd.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/vyconfd.ml')
-rw-r--r--src/vyconfd.ml95
1 files changed, 74 insertions, 21 deletions
diff --git a/src/vyconfd.ml b/src/vyconfd.ml
index 885fd20..a0be019 100644
--- a/src/vyconfd.ml
+++ b/src/vyconfd.ml
@@ -24,6 +24,7 @@ let daemonize = ref true
let config_file = ref defaults.config_file
let basepath = ref "/"
let log_file = ref None
+let legacy_config_path = ref false
(* Global data *)
let sessions : (string, Session.session_data) Hashtbl.t = Hashtbl.create 10
@@ -39,23 +40,54 @@ let args = [
(Printf.sprintf "<string> Configuration file, default is %s" defaults.config_file));
("--log-file", Arg.String (fun s -> log_file := Some s), "<string> Log file");
("--base-path", Arg.String (fun s -> basepath := s), "<string> Appliance base path");
- ("--version", Arg.Unit (fun () -> print_endline @@ Version.version_info (); exit 0), "Print version and exit")
+ ("--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));
]
let usage = "Usage: " ^ Sys.argv.(0) ^ " [options]"
let response_tmpl = {status=Success; output=None; error=None; warning=None}
+let find_session token = Hashtbl.find sessions token
+
+let find_session_by_pid pid =
+ let exception E of string in
+ let find_k k v acc =
+ if v.Session.client_pid = pid then
+ raise_notrace (E k)
+ else acc
+ in
+ try
+ Hashtbl.fold find_k sessions None
+ with E x -> Some x
+
let make_session_token () =
Sha1.string (string_of_int (Random.bits ())) |> Sha1.to_hex
-let setup_session world req =
+let setup_session world (req: request_setup_session) =
let token = make_session_token () in
+ let pid = req.client_pid in
let user = "unknown user" in
let client_app = Option.value req.client_application ~default:"unknown client" in
- let () = Hashtbl.add sessions token (Session.make world client_app user) in
+ let () = Hashtbl.add sessions token (Session.make world client_app user pid) in
{response_tmpl with output=(Some token)}
-let find_session token = Hashtbl.find sessions token
+let session_of_pid _world (req: request_session_of_pid) =
+ let pid = req.client_pid in
+ let extant = find_session_by_pid pid in
+ {response_tmpl with output=extant}
+
+let session_update_pid _world token (req: request_session_update_pid) =
+ let pid = req.client_pid in
+ try
+ begin
+ let s = Hashtbl.find sessions token in
+ if s.client_pid <> pid then
+ let session = {s with client_pid=pid} in
+ Hashtbl.replace sessions token session
+ end;
+ {response_tmpl with output=(Some token)}
+ with Not_found -> {response_tmpl with status=Fail; output=None}
let enter_conf_mode req token =
let open Session in
@@ -88,9 +120,10 @@ let exit_conf_mode world token =
in Hashtbl.replace sessions token session;
response_tmpl
-let teardown token =
+let teardown world token =
try
- Hashtbl.remove sessions token;
+ let () = Hashtbl.remove sessions token in
+ let () = Session.cleanup_config world token in
{response_tmpl with status=Success}
with Not_found ->
{response_tmpl with status=Fail; error=(Some "Session not found")}
@@ -99,6 +132,13 @@ let session_changed world token (_req: request_session_changed) =
if Session.session_changed world (find_session token) then response_tmpl
else {response_tmpl with status=Fail}
+let get_config world token (_req: request_get_config) =
+ try
+ let id =
+ Session.get_config world (find_session token) token
+ in {response_tmpl with output=(Some id)}
+ with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)}
+
let exists world token (req: request_exists) =
if Session.exists world (find_session token) req.path then response_tmpl
else {response_tmpl with status=Fail}
@@ -177,7 +217,15 @@ let discard world token (_req: request_discard) =
let load world token (req: request_load) =
try
- let session = Session.load world (find_session token) req.location
+ let session = Session.load world (find_session token) req.location req.cached
+ in
+ Hashtbl.replace sessions token session;
+ response_tmpl
+ with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)}
+
+let merge world token (req: request_merge) =
+ try
+ let session = Session.merge world (find_session token) req.location req.destructive
in
Hashtbl.replace sessions token session;
response_tmpl
@@ -192,15 +240,10 @@ let save world token (req: request_save) =
let commit world token (req: request_commit) =
let s = find_session token in
- let at = world.Session.running_config in
- let wt = s.proposed_config in
- let rt = world.reference_tree in
- let vc = world.vyconf_config in
- let () = IC.write_internal at (FP.concat vc.session_dir vc.running_cache) in
- let () = IC.write_internal wt (FP.concat vc.session_dir vc.session_cache) in
-
let req_dry_run = Option.value req.dry_run ~default:false in
- let commit_data = CC.make_commit_data ~dry_run:req_dry_run rt at wt token in
+
+ let commit_data = Session.prepare_commit ~dry_run:req_dry_run world s token
+ in
let%lwt received_commit_data = VC.do_commit commit_data in
let%lwt result_commit_data =
Lwt.return (CC.commit_update received_commit_data)
@@ -265,11 +308,13 @@ let rec handle_connection world ic oc () =
(match req with
| _, Prompt -> response_tmpl
| _, Setup_session r -> setup_session world r
+ | _, Session_of_pid r -> session_of_pid 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
- | Some t, Exit_configure -> exit_conf_mode world t
+ | Some t, Session_update_pid r -> session_update_pid world t r
+ | Some t, Teardown _ -> teardown world t
+ | Some t, Enter_configuration_mode r -> enter_conf_mode r t
+ | Some t, Exit_configuration_mode -> exit_conf_mode world t
| Some t, Exists r -> exists world t r
| Some t, Get_value r -> get_value world t r
| Some t, Get_values r -> get_values world t r
@@ -280,7 +325,9 @@ let rec handle_connection world ic oc () =
| Some t, Delete r -> delete world t r
| Some t, Discard r -> discard world t r
| Some t, Session_changed r -> session_changed world t r
+ | Some t, Get_config r -> get_config world t r
| Some t, Load r -> load world t r
+ | Some t, Merge r -> merge world t r
| Some t, Save r -> save world t r
| _ -> failwith "Unimplemented"
) |> Lwt.return
@@ -337,8 +384,14 @@ let () =
let dirs = Directories.make !basepath vc in
Startup.check_validators_dir dirs;
let world = make_world vc dirs in
- let config = Startup.load_config_failsafe
- (FP.concat vc.config_dir vc.primary_config)
- (FP.concat vc.config_dir vc.fallback_config) in
+ let primary_config =
+ match !legacy_config_path with
+ | true -> defaults.legacy_config_path
+ | false -> (FP.concat vc.config_dir vc.primary_config)
+ in
+ let failsafe_config = (FP.concat vc.config_dir vc.fallback_config) in
+ let config =
+ Startup.load_config_failsafe primary_config failsafe_config
+ in
let world = Session.{world with running_config=config} in
Lwt_main.run @@ main_loop !basepath world ()