summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@vyos.io>2025-09-18 12:32:18 +0100
committerGitHub <noreply@github.com>2025-09-18 12:32:18 +0100
commit304e4d2a172fe1baf2c1df7f61b7a0a8e40f7d5d (patch)
tree4a415189068819e7914ae1352a69abe08eb45c60 /src
parent2da0981501a9bec8b69d29f1e52c10db90571aa4 (diff)
parentbca62a7bd1da4e78497fdce3882421609ce28c00 (diff)
downloadvyconf-304e4d2a172fe1baf2c1df7f61b7a0a8e40f7d5d.tar.gz
vyconf-304e4d2a172fe1baf2c1df7f61b7a0a8e40f7d5d.zip
Merge pull request #31 from jestabro/interstitial-set
T7737: add analogue of configfs for config tree updates during commit
Diffstat (limited to 'src')
-rw-r--r--src/commit.ml54
-rw-r--r--src/commit.mli7
-rw-r--r--src/message.ml4
-rw-r--r--src/message.mli2
-rw-r--r--src/session.ml98
-rw-r--r--src/session.mli24
-rw-r--r--src/vycall_client.ml3
-rw-r--r--src/vycall_pbt.ml72
-rw-r--r--src/vycall_pbt.mli6
-rw-r--r--src/vycli.ml10
-rw-r--r--src/vyconf_cli.ml10
-rw-r--r--src/vyconf_client.ml10
-rw-r--r--src/vyconf_client.mli2
-rw-r--r--src/vyconf_client_session.ml12
-rw-r--r--src/vyconf_pbt.ml362
-rw-r--r--src/vyconf_pbt.mli94
-rw-r--r--src/vyconfd.ml91
17 files changed, 687 insertions, 174 deletions
diff --git a/src/commit.ml b/src/commit.ml
index 8913ceb..7b04c36 100644
--- a/src/commit.ml
+++ b/src/commit.ml
@@ -12,10 +12,20 @@ let tree_source_to_yojson = function
| ADD -> `String "ADD"
type status = {
- success : bool;
- out : string;
+ success : bool;
+ out : string;
} [@@deriving to_yojson]
+let default_status = {
+ success = true;
+ out = "";
+}
+
+let fail_status msg =
+ { success = false;
+ out = msg;
+ }
+
type node_data = {
script_name: string;
priority: int;
@@ -39,6 +49,9 @@ let default_node_data = {
type commit_data = {
session_id: string;
+ session_pid: int32;
+ sudo_user: string;
+ user: string;
dry_run: bool;
atomic: bool;
background: bool;
@@ -49,21 +62,6 @@ type commit_data = {
result : status;
} [@@deriving to_yojson]
-let default_commit_data = {
- session_id = "";
- dry_run = false;
- atomic = false;
- background = false;
- init = None;
- node_list = [];
- config_diff = CT.default;
- config_result = CT.default;
- result = { success = true; out = ""; };
-}
-
-let fail_status msg =
- { success=false; out=msg }
-
let lex_order c1 c2 =
let c = Vyos1x.Util.lex_order c1.path c2.path in
match c with
@@ -224,25 +222,31 @@ let config_result_update c_data n_data =
let commit_update c_data =
match c_data.init with
| None ->
- { default_commit_data with
- init=Some (fail_status "commitd failure: no init status provided")
+ { c_data with
+ init = Some (fail_status "commitd failure: no init status provided")
}
| Some _ ->
let func acc_data nd =
match nd.reply with
| None ->
- { default_commit_data with
- init=Some (fail_status"commitd failure: no reply status provided")
+ { c_data with
+ init = Some (fail_status "commitd failure: no reply status provided")
}
| Some _ -> config_result_update acc_data nd
in List.fold_left func c_data c_data.node_list
-let make_commit_data ?(dry_run=false) rt at wt id =
+let make_commit_data ?(dry_run=false) rt at wt id pid sudo_user user =
let diff = CD.diff_tree [] at wt in
let del_list, add_list = calculate_priority_lists rt diff in
- { default_commit_data with
- session_id = id;
+ { session_id = id;
+ session_pid = pid;
+ sudo_user = sudo_user;
+ user = user;
dry_run = dry_run;
+ atomic = false;
+ background = false;
+ init = None;
config_diff = diff;
config_result = CT.get_subtree diff ["inter"];
- node_list = del_list @ add_list; }
+ node_list = del_list @ add_list;
+ result = default_status; }
diff --git a/src/commit.mli b/src/commit.mli
index 01022ec..ee38768 100644
--- a/src/commit.mli
+++ b/src/commit.mli
@@ -17,6 +17,9 @@ type node_data = {
type commit_data = {
session_id: string;
+ session_pid: int32;
+ sudo_user: string;
+ user: string;
dry_run: bool;
atomic: bool;
background: bool;
@@ -33,9 +36,7 @@ val tree_source_to_yojson : tree_source -> [> `String of string ]
val default_node_data : node_data
-val default_commit_data : commit_data
-
-val make_commit_data : ?dry_run:bool -> Vyos1x.Reference_tree.t -> Vyos1x.Config_tree.t -> Vyos1x.Config_tree.t -> string -> commit_data
+val make_commit_data : ?dry_run:bool -> Vyos1x.Reference_tree.t -> Vyos1x.Config_tree.t -> Vyos1x.Config_tree.t -> string -> int32 -> string -> string -> commit_data
val calculate_priority_lists : Vyos1x.Reference_tree.t -> Vyos1x.Config_tree.t -> node_data list * node_data list
diff --git a/src/message.ml b/src/message.ml
index d4cc374..5b508eb 100644
--- a/src/message.ml
+++ b/src/message.ml
@@ -13,18 +13,14 @@ let read ic =
let header = Bytes.create 4 in
let%lwt () = Lwt_io.read_into_exactly ic header 0 4 in
let length = EndianBytes.BigEndian.get_int32 header 0 |> Int32.to_int in
- Lwt_log.debug (Printf.sprintf "Read length: %d\n" length) |> Lwt.ignore_result;
if length < 0 then failwith (Printf.sprintf "Bad message length: %d" length) else
let buffer = Bytes.create length in
let%lwt () = Lwt_io.read_into_exactly ic buffer 0 length in
- Lwt_log.debug (hexdump buffer |> Printf.sprintf "Read mesage: %s") |> Lwt.ignore_result;
Lwt.return buffer
let write oc msg =
let length = Bytes.length msg in
let length' = Int32.of_int length in
- Lwt_log.debug (Printf.sprintf "Write length: %d\n" length) |> Lwt.ignore_result;
- Lwt_log.debug (hexdump msg |> Printf.sprintf "Write message: %s") |> Lwt.ignore_result;
if length' < 0l then failwith (Printf.sprintf "Bad message length: %d" length) else
let header = Bytes.create 4 in
let () = EndianBytes.BigEndian.set_int32 header 0 length' in
diff --git a/src/message.mli b/src/message.mli
index ec44c56..2d5baa7 100644
--- a/src/message.mli
+++ b/src/message.mli
@@ -1,3 +1,5 @@
val read : Lwt_io.input_channel -> bytes Lwt.t
val write : Lwt_io.output_channel -> bytes -> unit Lwt.t
+
+val hexdump : bytes -> string
diff --git a/src/session.ml b/src/session.ml
index 5efc9f5..5f70feb 100644
--- a/src/session.ml
+++ b/src/session.ml
@@ -3,6 +3,7 @@ module IC = Vyos1x.Internal.Make(CT)
module CC = Commitd_client.Commit
module CD = Vyos1x.Config_diff
module VT = Vyos1x.Vytree
+module VL = Vyos1x.Vylist
module RT = Vyos1x.Reference_tree
module D = Directories
module FP = FilePath
@@ -12,6 +13,7 @@ exception Session_error of string
type cfg_op =
| CfgSet of string list * string option * CT.value_behaviour
| CfgDelete of string list * string option
+ [@@deriving yojson]
type world = {
mutable running_config: CT.t;
@@ -20,23 +22,34 @@ type world = {
dirs: Directories.t
}
+type aux_op = {
+ script_name: string;
+ tag_value: string option;
+ changeset: cfg_op list;
+} [@@deriving yojson]
+
+
type session_data = {
proposed_config : CT.t;
modified: bool;
conf_mode: bool;
changeset: cfg_op list;
+ mutable aux_changeset: aux_op list;
client_app: string;
- user: string;
client_pid: int32;
+ client_user: string;
+ client_sudo_user: string;
}
-let make world client_app user pid = {
+let make world client_app sudo_user user pid = {
proposed_config = world.running_config;
modified = false;
conf_mode = false;
changeset = [];
+ aux_changeset = [];
client_app = client_app;
- user = user;
+ client_user = user;
+ client_sudo_user = sudo_user;
client_pid = pid;
}
@@ -53,6 +66,10 @@ let string_of_op op =
| None -> Printf.sprintf "delete %s" path_str
| Some v -> Printf.sprintf "delete %s \"%s\"" path_str v)
+let sprint_changeset ss =
+ let ss = List.map (fun x -> aux_op_to_yojson x) ss in
+ Yojson.Safe.to_string (`List ss)
+
let set_modified s =
if s.modified = true then s
else {s with modified = true}
@@ -142,6 +159,51 @@ let delete w s path =
let changeset' = update_delete w s.changeset path in
{ s with changeset = changeset' }
+let aux_set w s path name tagval =
+ let _ = validate w s path in
+ let aux = s.aux_changeset in
+ let ident y =
+ if (y.script_name <> name || y.tag_value <> tagval) then false
+ else true
+ in
+ let op' = VL.find ident aux in
+ let changeset' =
+ match op' with
+ | None ->
+ update_set w [] path
+ | Some o ->
+ update_set w o.changeset path
+ in
+ let op =
+ { script_name = name; tag_value = tagval; changeset = changeset' }
+ in
+ let aux_changeset' =
+ VL.replace ~force:true ident op aux
+ in
+ s.aux_changeset <- aux_changeset'
+
+let aux_delete w s path name tagval =
+ let aux = s.aux_changeset in
+ let ident y =
+ if (y.script_name <> name || y.tag_value <> tagval) then false
+ else true
+ in
+ let op' = VL.find ident aux in
+ let changeset' =
+ match op' with
+ | None ->
+ update_delete w [] path
+ | Some o ->
+ update_delete w o.changeset path
+ in
+ let op =
+ { script_name = name; tag_value = tagval; changeset = changeset' }
+ in
+ let aux_changeset' =
+ VL.replace ~force:true ident op aux
+ in
+ s.aux_changeset <- aux_changeset'
+
let discard _w s =
{ s with changeset = []; }
@@ -189,7 +251,7 @@ 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 =
+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 vc = w.vyconf_config in
@@ -205,7 +267,33 @@ let prepare_commit ?(dry_run=false) w config id =
with
Vyos1x.Internal.Write_error msg -> raise (Session_error msg)
in
- CC.make_commit_data ~dry_run:dry_run rt at config id
+ CC.make_commit_data ~dry_run:dry_run rt at config id pid sudo_user user
+
+let post_process_commit w s ((c_data: CC.commit_data), proposed_config) =
+ let ident n v y =
+ if (y.script_name <> n || y.tag_value <> v) then false
+ else true
+ in
+ let func (running, proposed) (n_data: CC.node_data) =
+ match n_data.reply with
+ | None -> (running, proposed)
+ | Some reply ->
+ match reply.success with
+ | false -> (running, proposed)
+ | true ->
+ begin
+ let post =
+ VL.find
+ (ident n_data.script_name n_data.tag_value)
+ s.aux_changeset
+ in
+ match post with
+ | None -> (running, proposed)
+ | Some p ->
+ (apply_changes w p.changeset running, apply_changes w p.changeset proposed)
+ end
+ in
+ List.fold_left func (c_data.config_result, proposed_config) c_data.node_list
let get_config w s id =
let at = w.running_config in
diff --git a/src/session.mli b/src/session.mli
index abe5165..a08f873 100644
--- a/src/session.mli
+++ b/src/session.mli
@@ -9,19 +9,29 @@ type world = {
dirs: Directories.t
}
+type aux_op = {
+ script_name: string;
+ tag_value: string option;
+ changeset: cfg_op list;
+} [@@deriving yojson]
+
type session_data = {
proposed_config : Vyos1x.Config_tree.t;
modified: bool;
conf_mode: bool;
changeset: cfg_op list;
+ mutable aux_changeset: aux_op list;
client_app: string;
- user: string;
- client_pid: int32
+ client_pid: int32;
+ client_user: string;
+ client_sudo_user: string;
}
exception Session_error of string
-val make : world -> string -> string -> int32 -> session_data
+val sprint_changeset : aux_op list -> string
+
+val make : world -> string -> string -> string -> int32 -> session_data
val set_modified : session_data -> session_data
@@ -33,6 +43,10 @@ val set : world -> session_data -> string list -> session_data
val delete : world -> session_data -> string list -> session_data
+val aux_set : world -> session_data -> string list -> string -> string option -> unit
+
+val aux_delete : world -> session_data -> string list -> string -> string option -> unit
+
val get_proposed_config : world -> session_data -> Vyos1x.Config_tree.t
val discard : world -> session_data -> session_data
@@ -55,7 +69,9 @@ 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 -> Commitd_client.Commit.commit_data
+val prepare_commit : ?dry_run:bool -> world -> Vyos1x.Config_tree.t -> string -> int32 -> string -> string -> Commitd_client.Commit.commit_data
+
+val post_process_commit : world -> session_data -> Commitd_client.Commit.commit_data * Vyos1x.Config_tree.t -> Vyos1x.Config_tree.t * Vyos1x.Config_tree.t
val get_config : world -> session_data -> string -> string
diff --git a/src/vycall_client.ml b/src/vycall_client.ml
index 11bbe3f..515f5df 100644
--- a/src/vycall_client.ml
+++ b/src/vycall_client.ml
@@ -31,6 +31,9 @@ let call_to_node_data ((c: call), (nd: node_data)) =
let commit_data_to_commit_proto cd =
{ session_id = cd.session_id;
+ session_pid = cd.session_pid;
+ sudo_user = cd.sudo_user;
+ user = cd.user;
dry_run = cd.dry_run;
atomic = cd.atomic;
background = cd.background;
diff --git a/src/vycall_pbt.ml b/src/vycall_pbt.ml
index 715c453..89d2c67 100644
--- a/src/vycall_pbt.ml
+++ b/src/vycall_pbt.ml
@@ -14,6 +14,9 @@ type call = {
type commit = {
session_id : string;
+ session_pid : int32;
+ sudo_user : string;
+ user : string;
dry_run : bool;
atomic : bool;
background : bool;
@@ -43,6 +46,9 @@ let rec default_call
let rec default_commit
?session_id:((session_id:string) = "")
+ ?session_pid:((session_pid:int32) = 0l)
+ ?sudo_user:((sudo_user:string) = "")
+ ?user:((user:string) = "")
?dry_run:((dry_run:bool) = false)
?atomic:((atomic:bool) = false)
?background:((background:bool) = false)
@@ -50,6 +56,9 @@ let rec default_commit
?calls:((calls:call list) = [])
() : commit = {
session_id;
+ session_pid;
+ sudo_user;
+ user;
dry_run;
atomic;
background;
@@ -83,6 +92,9 @@ let default_call_mutable () : call_mutable = {
type commit_mutable = {
mutable session_id : string;
+ mutable session_pid : int32;
+ mutable sudo_user : string;
+ mutable user : string;
mutable dry_run : bool;
mutable atomic : bool;
mutable background : bool;
@@ -92,6 +104,9 @@ type commit_mutable = {
let default_commit_mutable () : commit_mutable = {
session_id = "";
+ session_pid = 0l;
+ sudo_user = "";
+ user = "";
dry_run = false;
atomic = false;
background = false;
@@ -122,6 +137,9 @@ let rec pp_call fmt (v:call) =
let rec pp_commit fmt (v:commit) =
let pp_i fmt () =
Pbrt.Pp.pp_record_field ~first:true "session_id" Pbrt.Pp.pp_string fmt v.session_id;
+ Pbrt.Pp.pp_record_field ~first:false "session_pid" Pbrt.Pp.pp_int32 fmt v.session_pid;
+ Pbrt.Pp.pp_record_field ~first:false "sudo_user" Pbrt.Pp.pp_string fmt v.sudo_user;
+ Pbrt.Pp.pp_record_field ~first:false "user" Pbrt.Pp.pp_string fmt v.user;
Pbrt.Pp.pp_record_field ~first:false "dry_run" Pbrt.Pp.pp_bool fmt v.dry_run;
Pbrt.Pp.pp_record_field ~first:false "atomic" Pbrt.Pp.pp_bool fmt v.atomic;
Pbrt.Pp.pp_record_field ~first:false "background" Pbrt.Pp.pp_bool fmt v.background;
@@ -167,21 +185,27 @@ let rec encode_pb_call (v:call) encoder =
let rec encode_pb_commit (v:commit) encoder =
Pbrt.Encoder.string v.session_id encoder;
Pbrt.Encoder.key 1 Pbrt.Bytes encoder;
+ Pbrt.Encoder.int32_as_varint v.session_pid encoder;
+ Pbrt.Encoder.key 2 Pbrt.Varint encoder;
+ Pbrt.Encoder.string v.sudo_user encoder;
+ Pbrt.Encoder.key 3 Pbrt.Bytes encoder;
+ Pbrt.Encoder.string v.user encoder;
+ Pbrt.Encoder.key 4 Pbrt.Bytes encoder;
Pbrt.Encoder.bool v.dry_run encoder;
- Pbrt.Encoder.key 4 Pbrt.Varint encoder;
- Pbrt.Encoder.bool v.atomic encoder;
Pbrt.Encoder.key 5 Pbrt.Varint encoder;
- Pbrt.Encoder.bool v.background encoder;
+ Pbrt.Encoder.bool v.atomic encoder;
Pbrt.Encoder.key 6 Pbrt.Varint encoder;
+ Pbrt.Encoder.bool v.background encoder;
+ Pbrt.Encoder.key 7 Pbrt.Varint encoder;
begin match v.init with
| Some x ->
Pbrt.Encoder.nested encode_pb_status x encoder;
- Pbrt.Encoder.key 7 Pbrt.Bytes encoder;
+ Pbrt.Encoder.key 8 Pbrt.Bytes encoder;
| None -> ();
end;
Pbrt.List_util.rev_iter_with (fun x encoder ->
Pbrt.Encoder.nested encode_pb_call x encoder;
- Pbrt.Encoder.key 8 Pbrt.Bytes encoder;
+ Pbrt.Encoder.key 9 Pbrt.Bytes encoder;
) v.calls encoder;
()
@@ -261,6 +285,9 @@ let rec decode_pb_commit d =
let background_is_set = ref false in
let atomic_is_set = ref false in
let dry_run_is_set = ref false in
+ let user_is_set = ref false in
+ let sudo_user_is_set = ref false in
+ let session_pid_is_set = ref false in
let session_id_is_set = ref false in
while !continue__ do
match Pbrt.Decoder.key d with
@@ -272,39 +299,60 @@ let rec decode_pb_commit d =
end
| Some (1, pk) ->
Pbrt.Decoder.unexpected_payload "Message(commit), field(1)" pk
- | Some (4, Pbrt.Varint) -> begin
- v.dry_run <- Pbrt.Decoder.bool d; dry_run_is_set := true;
+ | Some (2, Pbrt.Varint) -> begin
+ v.session_pid <- Pbrt.Decoder.int32_as_varint d; session_pid_is_set := true;
+ end
+ | Some (2, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(commit), field(2)" pk
+ | Some (3, Pbrt.Bytes) -> begin
+ v.sudo_user <- Pbrt.Decoder.string d; sudo_user_is_set := true;
+ end
+ | Some (3, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(commit), field(3)" pk
+ | Some (4, Pbrt.Bytes) -> begin
+ v.user <- Pbrt.Decoder.string d; user_is_set := true;
end
| Some (4, pk) ->
Pbrt.Decoder.unexpected_payload "Message(commit), field(4)" pk
| Some (5, Pbrt.Varint) -> begin
- v.atomic <- Pbrt.Decoder.bool d; atomic_is_set := true;
+ v.dry_run <- Pbrt.Decoder.bool d; dry_run_is_set := true;
end
| Some (5, pk) ->
Pbrt.Decoder.unexpected_payload "Message(commit), field(5)" pk
| Some (6, Pbrt.Varint) -> begin
- v.background <- Pbrt.Decoder.bool d; background_is_set := true;
+ v.atomic <- Pbrt.Decoder.bool d; atomic_is_set := true;
end
| Some (6, pk) ->
Pbrt.Decoder.unexpected_payload "Message(commit), field(6)" pk
- | Some (7, Pbrt.Bytes) -> begin
- v.init <- Some (decode_pb_status (Pbrt.Decoder.nested d));
+ | Some (7, Pbrt.Varint) -> begin
+ v.background <- Pbrt.Decoder.bool d; background_is_set := true;
end
| Some (7, pk) ->
Pbrt.Decoder.unexpected_payload "Message(commit), field(7)" pk
| Some (8, Pbrt.Bytes) -> begin
- v.calls <- (decode_pb_call (Pbrt.Decoder.nested d)) :: v.calls;
+ v.init <- Some (decode_pb_status (Pbrt.Decoder.nested d));
end
| Some (8, pk) ->
Pbrt.Decoder.unexpected_payload "Message(commit), field(8)" pk
+ | Some (9, Pbrt.Bytes) -> begin
+ v.calls <- (decode_pb_call (Pbrt.Decoder.nested d)) :: v.calls;
+ end
+ | Some (9, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(commit), field(9)" pk
| Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
done;
begin if not !background_is_set then Pbrt.Decoder.missing_field "background" end;
begin if not !atomic_is_set then Pbrt.Decoder.missing_field "atomic" end;
begin if not !dry_run_is_set then Pbrt.Decoder.missing_field "dry_run" end;
+ begin if not !user_is_set then Pbrt.Decoder.missing_field "user" end;
+ begin if not !sudo_user_is_set then Pbrt.Decoder.missing_field "sudo_user" end;
+ begin if not !session_pid_is_set then Pbrt.Decoder.missing_field "session_pid" end;
begin if not !session_id_is_set then Pbrt.Decoder.missing_field "session_id" end;
({
session_id = v.session_id;
+ session_pid = v.session_pid;
+ sudo_user = v.sudo_user;
+ user = v.user;
dry_run = v.dry_run;
atomic = v.atomic;
background = v.background;
diff --git a/src/vycall_pbt.mli b/src/vycall_pbt.mli
index f389302..fd39a0c 100644
--- a/src/vycall_pbt.mli
+++ b/src/vycall_pbt.mli
@@ -21,6 +21,9 @@ type call = {
type commit = {
session_id : string;
+ session_pid : int32;
+ sudo_user : string;
+ user : string;
dry_run : bool;
atomic : bool;
background : bool;
@@ -49,6 +52,9 @@ val default_call :
val default_commit :
?session_id:string ->
+ ?session_pid:int32 ->
+ ?sudo_user:string ->
+ ?user:string ->
?dry_run:bool ->
?atomic:bool ->
?background:bool ->
diff --git a/src/vycli.ml b/src/vycli.ml
index 174d6f4..6b13bdd 100644
--- a/src/vycli.ml
+++ b/src/vycli.ml
@@ -68,7 +68,15 @@ let main socket op path out_format config_format =
end
| OpSetupSession ->
let pid = Int32.of_int (Unix.getppid ()) in
- let%lwt resp = setup_session client "vycli" pid in
+ let user =
+ try Sys.getenv "USER"
+ with Not_found -> ""
+ in
+ let sudo_user =
+ try Sys.getenv "SUDO_USER"
+ with Not_found -> ""
+ in
+ let%lwt resp = setup_session client "vycli" sudo_user user pid in
begin
match resp with
| Ok c -> get_token c
diff --git a/src/vyconf_cli.ml b/src/vyconf_cli.ml
index 0d1535e..b2ee630 100644
--- a/src/vyconf_cli.ml
+++ b/src/vyconf_cli.ml
@@ -39,6 +39,14 @@ let in_cli_config_session () =
let get_session () =
let pid = Int32.of_int (Unix.getppid()) in
+ let user =
+ try Sys.getenv "USER"
+ with Not_found -> ""
+ in
+ let sudo_user =
+ try Sys.getenv "SUDO_USER"
+ with Not_found -> ""
+ in
let socket = "/var/run/vyconfd.sock" in
let config_format = config_format_of_string "curly" in
let out_format = output_format_of_string "plain" in
@@ -47,7 +55,7 @@ let get_session () =
in
let%lwt resp = session_of_pid client pid in
match resp with
- | Error _ -> setup_session client "vyconf_cli" pid
+ | Error _ -> setup_session client "vyconf_cli" sudo_user user pid
| _ as c -> c |> Lwt.return
let close_session () =
diff --git a/src/vyconf_client.ml b/src/vyconf_client.ml
index 05b5548..25b923f 100644
--- a/src/vyconf_client.ml
+++ b/src/vyconf_client.ml
@@ -53,10 +53,16 @@ let prompt client =
let%lwt resp = do_request client req in
Lwt.return resp
-let setup_session ?(on_behalf_of=None) client client_app pid =
+let setup_session ?(on_behalf_of=None) client client_app sudo_user user pid =
if Option.is_some client.session then Lwt.return (Error "Client is already associated with a session") else
let id = on_behalf_of |> (function None -> None | Some x -> (Some (Int32.of_int x))) in
- let req = Setup_session {client_application=(Some client_app); on_behalf_of=id; client_pid=pid} in
+ let req =
+ Setup_session { client_application=(Some client_app);
+ on_behalf_of=id;
+ client_sudo_user=Some sudo_user;
+ client_user=Some user;
+ client_pid=pid; }
+ in
let%lwt resp = do_request client req in
match resp.status with
| Success ->
diff --git a/src/vyconf_client.mli b/src/vyconf_client.mli
index 762495d..9c63652 100644
--- a/src/vyconf_client.mli
+++ b/src/vyconf_client.mli
@@ -8,7 +8,7 @@ val shutdown : t -> t Lwt.t
val prompt : t -> Vyconf_connect.Vyconf_pbt.response Lwt.t
-val setup_session : ?on_behalf_of:(int option) -> t -> string -> int32 -> (t, string) result Lwt.t
+val setup_session : ?on_behalf_of:(int option) -> t -> string -> string -> string -> int32 -> (t, string) result Lwt.t
val session_of_pid : t -> int32 -> (t, string) result Lwt.t
diff --git a/src/vyconf_client_session.ml b/src/vyconf_client_session.ml
index 93068fa..035f191 100644
--- a/src/vyconf_client_session.ml
+++ b/src/vyconf_client_session.ml
@@ -34,7 +34,17 @@ let call_op ?(out_format="plain") ?(config_format="curly") socket token op path
match o with
| OpSetupSession ->
let pid = Int32.of_int (Unix.getppid ()) in
- let%lwt resp = Vyconf_client.setup_session client "vyconf_client_session" pid in
+ let user =
+ try Sys.getenv "USER"
+ with Not_found -> ""
+ in
+ let sudo_user =
+ try Sys.getenv "SUDO_USER"
+ with Not_found -> ""
+ in
+ let%lwt resp =
+ Vyconf_client.setup_session client "vyconf_client_session" sudo_user user pid
+ in
begin
match resp with
| Ok c -> Vyconf_client.get_token c
diff --git a/src/vyconf_pbt.ml b/src/vyconf_pbt.ml
index 913fcea..1fbbf75 100644
--- a/src/vyconf_pbt.ml
+++ b/src/vyconf_pbt.ml
@@ -14,14 +14,16 @@ type request_setup_session = {
client_pid : int32;
client_application : string option;
on_behalf_of : int32 option;
+ client_user : string option;
+ client_sudo_user : string option;
}
type request_session_of_pid = {
client_pid : int32;
}
-type request_session_update_pid = {
- client_pid : int32;
+type request_session_exists = {
+ dummy : int32 option;
}
type request_get_config = {
@@ -45,6 +47,18 @@ type request_delete = {
path : string list;
}
+type request_aux_set = {
+ path : string list;
+ script_name : string;
+ tag_value : string option;
+}
+
+type request_aux_delete = {
+ path : string list;
+ script_name : string;
+ tag_value : string option;
+}
+
type request_discard = {
dummy : int32 option;
}
@@ -55,14 +69,14 @@ type request_session_changed = {
type request_rename = {
edit_level : string list;
- from : string;
- to_ : string;
+ source : string;
+ destination : string;
}
type request_copy = {
edit_level : string list;
- from : string;
- to_ : string;
+ source : string;
+ destination : string;
}
type request_comment = {
@@ -168,8 +182,10 @@ type request =
| Discard of request_discard
| Session_changed of request_session_changed
| Session_of_pid of request_session_of_pid
- | Session_update_pid of request_session_update_pid
+ | Session_exists of request_session_exists
| Get_config of request_get_config
+ | Aux_set of request_aux_set
+ | Aux_delete of request_aux_delete
type request_envelope = {
token : string option;
@@ -205,10 +221,14 @@ let rec default_request_setup_session
?client_pid:((client_pid:int32) = 0l)
?client_application:((client_application:string option) = None)
?on_behalf_of:((on_behalf_of:int32 option) = None)
+ ?client_user:((client_user:string option) = None)
+ ?client_sudo_user:((client_sudo_user:string option) = None)
() : request_setup_session = {
client_pid;
client_application;
on_behalf_of;
+ client_user;
+ client_sudo_user;
}
let rec default_request_session_of_pid
@@ -217,10 +237,10 @@ let rec default_request_session_of_pid
client_pid;
}
-let rec default_request_session_update_pid
- ?client_pid:((client_pid:int32) = 0l)
- () : request_session_update_pid = {
- client_pid;
+let rec default_request_session_exists
+ ?dummy:((dummy:int32 option) = None)
+ () : request_session_exists = {
+ dummy;
}
let rec default_request_get_config
@@ -255,6 +275,26 @@ let rec default_request_delete
path;
}
+let rec default_request_aux_set
+ ?path:((path:string list) = [])
+ ?script_name:((script_name:string) = "")
+ ?tag_value:((tag_value:string option) = None)
+ () : request_aux_set = {
+ path;
+ script_name;
+ tag_value;
+}
+
+let rec default_request_aux_delete
+ ?path:((path:string list) = [])
+ ?script_name:((script_name:string) = "")
+ ?tag_value:((tag_value:string option) = None)
+ () : request_aux_delete = {
+ path;
+ script_name;
+ tag_value;
+}
+
let rec default_request_discard
?dummy:((dummy:int32 option) = None)
() : request_discard = {
@@ -269,22 +309,22 @@ let rec default_request_session_changed
let rec default_request_rename
?edit_level:((edit_level:string list) = [])
- ?from:((from:string) = "")
- ?to_:((to_:string) = "")
+ ?source:((source:string) = "")
+ ?destination:((destination:string) = "")
() : request_rename = {
edit_level;
- from;
- to_;
+ source;
+ destination;
}
let rec default_request_copy
?edit_level:((edit_level:string list) = [])
- ?from:((from:string) = "")
- ?to_:((to_:string) = "")
+ ?source:((source:string) = "")
+ ?destination:((destination:string) = "")
() : request_copy = {
edit_level;
- from;
- to_;
+ source;
+ destination;
}
let rec default_request_comment
@@ -433,12 +473,16 @@ type request_setup_session_mutable = {
mutable client_pid : int32;
mutable client_application : string option;
mutable on_behalf_of : int32 option;
+ mutable client_user : string option;
+ mutable client_sudo_user : string option;
}
let default_request_setup_session_mutable () : request_setup_session_mutable = {
client_pid = 0l;
client_application = None;
on_behalf_of = None;
+ client_user = None;
+ client_sudo_user = None;
}
type request_session_of_pid_mutable = {
@@ -449,12 +493,12 @@ let default_request_session_of_pid_mutable () : request_session_of_pid_mutable =
client_pid = 0l;
}
-type request_session_update_pid_mutable = {
- mutable client_pid : int32;
+type request_session_exists_mutable = {
+ mutable dummy : int32 option;
}
-let default_request_session_update_pid_mutable () : request_session_update_pid_mutable = {
- client_pid = 0l;
+let default_request_session_exists_mutable () : request_session_exists_mutable = {
+ dummy = None;
}
type request_get_config_mutable = {
@@ -499,6 +543,30 @@ let default_request_delete_mutable () : request_delete_mutable = {
path = [];
}
+type request_aux_set_mutable = {
+ mutable path : string list;
+ mutable script_name : string;
+ mutable tag_value : string option;
+}
+
+let default_request_aux_set_mutable () : request_aux_set_mutable = {
+ path = [];
+ script_name = "";
+ tag_value = None;
+}
+
+type request_aux_delete_mutable = {
+ mutable path : string list;
+ mutable script_name : string;
+ mutable tag_value : string option;
+}
+
+let default_request_aux_delete_mutable () : request_aux_delete_mutable = {
+ path = [];
+ script_name = "";
+ tag_value = None;
+}
+
type request_discard_mutable = {
mutable dummy : int32 option;
}
@@ -517,26 +585,26 @@ let default_request_session_changed_mutable () : request_session_changed_mutable
type request_rename_mutable = {
mutable edit_level : string list;
- mutable from : string;
- mutable to_ : string;
+ mutable source : string;
+ mutable destination : string;
}
let default_request_rename_mutable () : request_rename_mutable = {
edit_level = [];
- from = "";
- to_ = "";
+ source = "";
+ destination = "";
}
type request_copy_mutable = {
mutable edit_level : string list;
- mutable from : string;
- mutable to_ : string;
+ mutable source : string;
+ mutable destination : string;
}
let default_request_copy_mutable () : request_copy_mutable = {
edit_level = [];
- from = "";
- to_ = "";
+ source = "";
+ destination = "";
}
type request_comment_mutable = {
@@ -730,6 +798,8 @@ let rec pp_request_setup_session fmt (v:request_setup_session) =
Pbrt.Pp.pp_record_field ~first:true "client_pid" Pbrt.Pp.pp_int32 fmt v.client_pid;
Pbrt.Pp.pp_record_field ~first:false "client_application" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.client_application;
Pbrt.Pp.pp_record_field ~first:false "on_behalf_of" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.on_behalf_of;
+ Pbrt.Pp.pp_record_field ~first:false "client_user" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.client_user;
+ Pbrt.Pp.pp_record_field ~first:false "client_sudo_user" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.client_sudo_user;
in
Pbrt.Pp.pp_brk pp_i fmt ()
@@ -739,9 +809,9 @@ let rec pp_request_session_of_pid fmt (v:request_session_of_pid) =
in
Pbrt.Pp.pp_brk pp_i fmt ()
-let rec pp_request_session_update_pid fmt (v:request_session_update_pid) =
+let rec pp_request_session_exists fmt (v:request_session_exists) =
let pp_i fmt () =
- Pbrt.Pp.pp_record_field ~first:true "client_pid" Pbrt.Pp.pp_int32 fmt v.client_pid;
+ Pbrt.Pp.pp_record_field ~first:true "dummy" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.dummy;
in
Pbrt.Pp.pp_brk pp_i fmt ()
@@ -776,6 +846,22 @@ let rec pp_request_delete fmt (v:request_delete) =
in
Pbrt.Pp.pp_brk pp_i fmt ()
+let rec pp_request_aux_set fmt (v:request_aux_set) =
+ let pp_i fmt () =
+ Pbrt.Pp.pp_record_field ~first:true "path" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.path;
+ Pbrt.Pp.pp_record_field ~first:false "script_name" Pbrt.Pp.pp_string fmt v.script_name;
+ Pbrt.Pp.pp_record_field ~first:false "tag_value" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.tag_value;
+ in
+ Pbrt.Pp.pp_brk pp_i fmt ()
+
+let rec pp_request_aux_delete fmt (v:request_aux_delete) =
+ let pp_i fmt () =
+ Pbrt.Pp.pp_record_field ~first:true "path" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.path;
+ Pbrt.Pp.pp_record_field ~first:false "script_name" Pbrt.Pp.pp_string fmt v.script_name;
+ Pbrt.Pp.pp_record_field ~first:false "tag_value" (Pbrt.Pp.pp_option Pbrt.Pp.pp_string) fmt v.tag_value;
+ in
+ Pbrt.Pp.pp_brk pp_i fmt ()
+
let rec pp_request_discard fmt (v:request_discard) =
let pp_i fmt () =
Pbrt.Pp.pp_record_field ~first:true "dummy" (Pbrt.Pp.pp_option Pbrt.Pp.pp_int32) fmt v.dummy;
@@ -791,16 +877,16 @@ let rec pp_request_session_changed fmt (v:request_session_changed) =
let rec pp_request_rename fmt (v:request_rename) =
let pp_i fmt () =
Pbrt.Pp.pp_record_field ~first:true "edit_level" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.edit_level;
- Pbrt.Pp.pp_record_field ~first:false "from" Pbrt.Pp.pp_string fmt v.from;
- Pbrt.Pp.pp_record_field ~first:false "to_" Pbrt.Pp.pp_string fmt v.to_;
+ Pbrt.Pp.pp_record_field ~first:false "source" Pbrt.Pp.pp_string fmt v.source;
+ Pbrt.Pp.pp_record_field ~first:false "destination" Pbrt.Pp.pp_string fmt v.destination;
in
Pbrt.Pp.pp_brk pp_i fmt ()
let rec pp_request_copy fmt (v:request_copy) =
let pp_i fmt () =
Pbrt.Pp.pp_record_field ~first:true "edit_level" (Pbrt.Pp.pp_list Pbrt.Pp.pp_string) fmt v.edit_level;
- Pbrt.Pp.pp_record_field ~first:false "from" Pbrt.Pp.pp_string fmt v.from;
- Pbrt.Pp.pp_record_field ~first:false "to_" Pbrt.Pp.pp_string fmt v.to_;
+ Pbrt.Pp.pp_record_field ~first:false "source" Pbrt.Pp.pp_string fmt v.source;
+ Pbrt.Pp.pp_record_field ~first:false "destination" Pbrt.Pp.pp_string fmt v.destination;
in
Pbrt.Pp.pp_brk pp_i fmt ()
@@ -944,8 +1030,10 @@ let rec pp_request fmt (v:request) =
| Discard x -> Format.fprintf fmt "@[<hv2>Discard(@,%a)@]" pp_request_discard x
| Session_changed x -> Format.fprintf fmt "@[<hv2>Session_changed(@,%a)@]" pp_request_session_changed x
| Session_of_pid x -> Format.fprintf fmt "@[<hv2>Session_of_pid(@,%a)@]" pp_request_session_of_pid x
- | Session_update_pid x -> Format.fprintf fmt "@[<hv2>Session_update_pid(@,%a)@]" pp_request_session_update_pid x
+ | Session_exists x -> Format.fprintf fmt "@[<hv2>Session_exists(@,%a)@]" pp_request_session_exists x
| Get_config x -> Format.fprintf fmt "@[<hv2>Get_config(@,%a)@]" pp_request_get_config x
+ | Aux_set x -> Format.fprintf fmt "@[<hv2>Aux_set(@,%a)@]" pp_request_aux_set x
+ | Aux_delete x -> Format.fprintf fmt "@[<hv2>Aux_delete(@,%a)@]" pp_request_aux_delete x
let rec pp_request_envelope fmt (v:request_envelope) =
let pp_i fmt () =
@@ -1008,6 +1096,18 @@ let rec encode_pb_request_setup_session (v:request_setup_session) encoder =
Pbrt.Encoder.key 3 Pbrt.Varint encoder;
| None -> ();
end;
+ begin match v.client_user with
+ | Some x ->
+ Pbrt.Encoder.string x encoder;
+ Pbrt.Encoder.key 4 Pbrt.Bytes encoder;
+ | None -> ();
+ end;
+ begin match v.client_sudo_user with
+ | Some x ->
+ Pbrt.Encoder.string x encoder;
+ Pbrt.Encoder.key 5 Pbrt.Bytes encoder;
+ | None -> ();
+ end;
()
let rec encode_pb_request_session_of_pid (v:request_session_of_pid) encoder =
@@ -1015,9 +1115,13 @@ let rec encode_pb_request_session_of_pid (v:request_session_of_pid) encoder =
Pbrt.Encoder.key 1 Pbrt.Varint encoder;
()
-let rec encode_pb_request_session_update_pid (v:request_session_update_pid) encoder =
- Pbrt.Encoder.int32_as_varint v.client_pid encoder;
- Pbrt.Encoder.key 1 Pbrt.Varint encoder;
+let rec encode_pb_request_session_exists (v:request_session_exists) encoder =
+ begin match v.dummy with
+ | Some x ->
+ Pbrt.Encoder.int32_as_varint x encoder;
+ Pbrt.Encoder.key 1 Pbrt.Varint encoder;
+ | None -> ();
+ end;
()
let rec encode_pb_request_get_config (v:request_get_config) encoder =
@@ -1065,6 +1169,36 @@ let rec encode_pb_request_delete (v:request_delete) encoder =
) v.path encoder;
()
+let rec encode_pb_request_aux_set (v:request_aux_set) encoder =
+ Pbrt.List_util.rev_iter_with (fun x encoder ->
+ Pbrt.Encoder.string x encoder;
+ Pbrt.Encoder.key 1 Pbrt.Bytes encoder;
+ ) v.path encoder;
+ Pbrt.Encoder.string v.script_name encoder;
+ Pbrt.Encoder.key 2 Pbrt.Bytes encoder;
+ begin match v.tag_value with
+ | Some x ->
+ Pbrt.Encoder.string x encoder;
+ Pbrt.Encoder.key 3 Pbrt.Bytes encoder;
+ | None -> ();
+ end;
+ ()
+
+let rec encode_pb_request_aux_delete (v:request_aux_delete) encoder =
+ Pbrt.List_util.rev_iter_with (fun x encoder ->
+ Pbrt.Encoder.string x encoder;
+ Pbrt.Encoder.key 1 Pbrt.Bytes encoder;
+ ) v.path encoder;
+ Pbrt.Encoder.string v.script_name encoder;
+ Pbrt.Encoder.key 2 Pbrt.Bytes encoder;
+ begin match v.tag_value with
+ | Some x ->
+ Pbrt.Encoder.string x encoder;
+ Pbrt.Encoder.key 3 Pbrt.Bytes encoder;
+ | None -> ();
+ end;
+ ()
+
let rec encode_pb_request_discard (v:request_discard) encoder =
begin match v.dummy with
| Some x ->
@@ -1088,9 +1222,9 @@ let rec encode_pb_request_rename (v:request_rename) encoder =
Pbrt.Encoder.string x encoder;
Pbrt.Encoder.key 1 Pbrt.Bytes encoder;
) v.edit_level encoder;
- Pbrt.Encoder.string v.from encoder;
+ Pbrt.Encoder.string v.source encoder;
Pbrt.Encoder.key 2 Pbrt.Bytes encoder;
- Pbrt.Encoder.string v.to_ encoder;
+ Pbrt.Encoder.string v.destination encoder;
Pbrt.Encoder.key 3 Pbrt.Bytes encoder;
()
@@ -1099,9 +1233,9 @@ let rec encode_pb_request_copy (v:request_copy) encoder =
Pbrt.Encoder.string x encoder;
Pbrt.Encoder.key 1 Pbrt.Bytes encoder;
) v.edit_level encoder;
- Pbrt.Encoder.string v.from encoder;
+ Pbrt.Encoder.string v.source encoder;
Pbrt.Encoder.key 2 Pbrt.Bytes encoder;
- Pbrt.Encoder.string v.to_ encoder;
+ Pbrt.Encoder.string v.destination encoder;
Pbrt.Encoder.key 3 Pbrt.Bytes encoder;
()
@@ -1360,12 +1494,18 @@ let rec encode_pb_request (v:request) encoder =
| Session_of_pid x ->
Pbrt.Encoder.nested encode_pb_request_session_of_pid x encoder;
Pbrt.Encoder.key 27 Pbrt.Bytes encoder;
- | Session_update_pid x ->
- Pbrt.Encoder.nested encode_pb_request_session_update_pid x encoder;
+ | Session_exists x ->
+ Pbrt.Encoder.nested encode_pb_request_session_exists x encoder;
Pbrt.Encoder.key 28 Pbrt.Bytes encoder;
| Get_config x ->
Pbrt.Encoder.nested encode_pb_request_get_config x encoder;
Pbrt.Encoder.key 29 Pbrt.Bytes encoder;
+ | Aux_set x ->
+ Pbrt.Encoder.nested encode_pb_request_aux_set x encoder;
+ Pbrt.Encoder.key 30 Pbrt.Bytes encoder;
+ | Aux_delete x ->
+ Pbrt.Encoder.nested encode_pb_request_aux_delete x encoder;
+ Pbrt.Encoder.key 31 Pbrt.Bytes encoder;
end
let rec encode_pb_request_envelope (v:request_envelope) encoder =
@@ -1460,6 +1600,16 @@ let rec decode_pb_request_setup_session d =
end
| Some (3, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_setup_session), field(3)" pk
+ | Some (4, Pbrt.Bytes) -> begin
+ v.client_user <- Some (Pbrt.Decoder.string d);
+ end
+ | Some (4, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_setup_session), field(4)" pk
+ | Some (5, Pbrt.Bytes) -> begin
+ v.client_sudo_user <- Some (Pbrt.Decoder.string d);
+ end
+ | Some (5, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_setup_session), field(5)" pk
| Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
done;
begin if not !client_pid_is_set then Pbrt.Decoder.missing_field "client_pid" end;
@@ -1467,6 +1617,8 @@ let rec decode_pb_request_setup_session d =
client_pid = v.client_pid;
client_application = v.client_application;
on_behalf_of = v.on_behalf_of;
+ client_user = v.client_user;
+ client_sudo_user = v.client_sudo_user;
} : request_setup_session)
let rec decode_pb_request_session_of_pid d =
@@ -1489,25 +1641,23 @@ let rec decode_pb_request_session_of_pid d =
client_pid = v.client_pid;
} : request_session_of_pid)
-let rec decode_pb_request_session_update_pid d =
- let v = default_request_session_update_pid_mutable () in
+let rec decode_pb_request_session_exists d =
+ let v = default_request_session_exists_mutable () in
let continue__= ref true in
- let client_pid_is_set = ref false in
while !continue__ do
match Pbrt.Decoder.key d with
| None -> (
); continue__ := false
| Some (1, Pbrt.Varint) -> begin
- v.client_pid <- Pbrt.Decoder.int32_as_varint d; client_pid_is_set := true;
+ v.dummy <- Some (Pbrt.Decoder.int32_as_varint d);
end
| Some (1, pk) ->
- Pbrt.Decoder.unexpected_payload "Message(request_session_update_pid), field(1)" pk
+ Pbrt.Decoder.unexpected_payload "Message(request_session_exists), field(1)" pk
| Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
done;
- begin if not !client_pid_is_set then Pbrt.Decoder.missing_field "client_pid" end;
({
- client_pid = v.client_pid;
- } : request_session_update_pid)
+ dummy = v.dummy;
+ } : request_session_exists)
let rec decode_pb_request_get_config d =
let v = default_request_get_config_mutable () in
@@ -1608,6 +1758,72 @@ let rec decode_pb_request_delete d =
path = v.path;
} : request_delete)
+let rec decode_pb_request_aux_set d =
+ let v = default_request_aux_set_mutable () in
+ let continue__= ref true in
+ let script_name_is_set = ref false in
+ while !continue__ do
+ match Pbrt.Decoder.key d with
+ | None -> (
+ v.path <- List.rev v.path;
+ ); continue__ := false
+ | Some (1, Pbrt.Bytes) -> begin
+ v.path <- (Pbrt.Decoder.string d) :: v.path;
+ end
+ | Some (1, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_aux_set), field(1)" pk
+ | Some (2, Pbrt.Bytes) -> begin
+ v.script_name <- Pbrt.Decoder.string d; script_name_is_set := true;
+ end
+ | Some (2, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_aux_set), field(2)" pk
+ | Some (3, Pbrt.Bytes) -> begin
+ v.tag_value <- Some (Pbrt.Decoder.string d);
+ end
+ | Some (3, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_aux_set), field(3)" pk
+ | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
+ done;
+ begin if not !script_name_is_set then Pbrt.Decoder.missing_field "script_name" end;
+ ({
+ path = v.path;
+ script_name = v.script_name;
+ tag_value = v.tag_value;
+ } : request_aux_set)
+
+let rec decode_pb_request_aux_delete d =
+ let v = default_request_aux_delete_mutable () in
+ let continue__= ref true in
+ let script_name_is_set = ref false in
+ while !continue__ do
+ match Pbrt.Decoder.key d with
+ | None -> (
+ v.path <- List.rev v.path;
+ ); continue__ := false
+ | Some (1, Pbrt.Bytes) -> begin
+ v.path <- (Pbrt.Decoder.string d) :: v.path;
+ end
+ | Some (1, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_aux_delete), field(1)" pk
+ | Some (2, Pbrt.Bytes) -> begin
+ v.script_name <- Pbrt.Decoder.string d; script_name_is_set := true;
+ end
+ | Some (2, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_aux_delete), field(2)" pk
+ | Some (3, Pbrt.Bytes) -> begin
+ v.tag_value <- Some (Pbrt.Decoder.string d);
+ end
+ | Some (3, pk) ->
+ Pbrt.Decoder.unexpected_payload "Message(request_aux_delete), field(3)" pk
+ | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
+ done;
+ begin if not !script_name_is_set then Pbrt.Decoder.missing_field "script_name" end;
+ ({
+ path = v.path;
+ script_name = v.script_name;
+ tag_value = v.tag_value;
+ } : request_aux_delete)
+
let rec decode_pb_request_discard d =
let v = default_request_discard_mutable () in
let continue__= ref true in
@@ -1647,8 +1863,8 @@ let rec decode_pb_request_session_changed d =
let rec decode_pb_request_rename d =
let v = default_request_rename_mutable () in
let continue__= ref true in
- let to__is_set = ref false in
- let from_is_set = ref false in
+ let destination_is_set = ref false in
+ let source_is_set = ref false in
while !continue__ do
match Pbrt.Decoder.key d with
| None -> (
@@ -1660,30 +1876,30 @@ let rec decode_pb_request_rename d =
| Some (1, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_rename), field(1)" pk
| Some (2, Pbrt.Bytes) -> begin
- v.from <- Pbrt.Decoder.string d; from_is_set := true;
+ v.source <- Pbrt.Decoder.string d; source_is_set := true;
end
| Some (2, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_rename), field(2)" pk
| Some (3, Pbrt.Bytes) -> begin
- v.to_ <- Pbrt.Decoder.string d; to__is_set := true;
+ v.destination <- Pbrt.Decoder.string d; destination_is_set := true;
end
| Some (3, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_rename), field(3)" pk
| Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
done;
- begin if not !to__is_set then Pbrt.Decoder.missing_field "to_" end;
- begin if not !from_is_set then Pbrt.Decoder.missing_field "from" end;
+ begin if not !destination_is_set then Pbrt.Decoder.missing_field "destination" end;
+ begin if not !source_is_set then Pbrt.Decoder.missing_field "source" end;
({
edit_level = v.edit_level;
- from = v.from;
- to_ = v.to_;
+ source = v.source;
+ destination = v.destination;
} : request_rename)
let rec decode_pb_request_copy d =
let v = default_request_copy_mutable () in
let continue__= ref true in
- let to__is_set = ref false in
- let from_is_set = ref false in
+ let destination_is_set = ref false in
+ let source_is_set = ref false in
while !continue__ do
match Pbrt.Decoder.key d with
| None -> (
@@ -1695,23 +1911,23 @@ let rec decode_pb_request_copy d =
| Some (1, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_copy), field(1)" pk
| Some (2, Pbrt.Bytes) -> begin
- v.from <- Pbrt.Decoder.string d; from_is_set := true;
+ v.source <- Pbrt.Decoder.string d; source_is_set := true;
end
| Some (2, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_copy), field(2)" pk
| Some (3, Pbrt.Bytes) -> begin
- v.to_ <- Pbrt.Decoder.string d; to__is_set := true;
+ v.destination <- Pbrt.Decoder.string d; destination_is_set := true;
end
| Some (3, pk) ->
Pbrt.Decoder.unexpected_payload "Message(request_copy), field(3)" pk
| Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind
done;
- begin if not !to__is_set then Pbrt.Decoder.missing_field "to_" end;
- begin if not !from_is_set then Pbrt.Decoder.missing_field "from" end;
+ begin if not !destination_is_set then Pbrt.Decoder.missing_field "destination" end;
+ begin if not !source_is_set then Pbrt.Decoder.missing_field "source" end;
({
edit_level = v.edit_level;
- from = v.from;
- to_ = v.to_;
+ source = v.source;
+ destination = v.destination;
} : request_copy)
let rec decode_pb_request_comment d =
@@ -2133,8 +2349,10 @@ let rec decode_pb_request d =
| Some (25, _) -> (Discard (decode_pb_request_discard (Pbrt.Decoder.nested d)) : request)
| Some (26, _) -> (Session_changed (decode_pb_request_session_changed (Pbrt.Decoder.nested d)) : request)
| Some (27, _) -> (Session_of_pid (decode_pb_request_session_of_pid (Pbrt.Decoder.nested d)) : request)
- | Some (28, _) -> (Session_update_pid (decode_pb_request_session_update_pid (Pbrt.Decoder.nested d)) : request)
+ | Some (28, _) -> (Session_exists (decode_pb_request_session_exists (Pbrt.Decoder.nested d)) : request)
| Some (29, _) -> (Get_config (decode_pb_request_get_config (Pbrt.Decoder.nested d)) : request)
+ | Some (30, _) -> (Aux_set (decode_pb_request_aux_set (Pbrt.Decoder.nested d)) : request)
+ | Some (31, _) -> (Aux_delete (decode_pb_request_aux_delete (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 c9a7530..d63962e 100644
--- a/src/vyconf_pbt.mli
+++ b/src/vyconf_pbt.mli
@@ -21,14 +21,16 @@ type request_setup_session = {
client_pid : int32;
client_application : string option;
on_behalf_of : int32 option;
+ client_user : string option;
+ client_sudo_user : string option;
}
type request_session_of_pid = {
client_pid : int32;
}
-type request_session_update_pid = {
- client_pid : int32;
+type request_session_exists = {
+ dummy : int32 option;
}
type request_get_config = {
@@ -52,6 +54,18 @@ type request_delete = {
path : string list;
}
+type request_aux_set = {
+ path : string list;
+ script_name : string;
+ tag_value : string option;
+}
+
+type request_aux_delete = {
+ path : string list;
+ script_name : string;
+ tag_value : string option;
+}
+
type request_discard = {
dummy : int32 option;
}
@@ -62,14 +76,14 @@ type request_session_changed = {
type request_rename = {
edit_level : string list;
- from : string;
- to_ : string;
+ source : string;
+ destination : string;
}
type request_copy = {
edit_level : string list;
- from : string;
- to_ : string;
+ source : string;
+ destination : string;
}
type request_comment = {
@@ -175,8 +189,10 @@ type request =
| Discard of request_discard
| Session_changed of request_session_changed
| Session_of_pid of request_session_of_pid
- | Session_update_pid of request_session_update_pid
+ | Session_exists of request_session_exists
| Get_config of request_get_config
+ | Aux_set of request_aux_set
+ | Aux_delete of request_aux_delete
type request_envelope = {
token : string option;
@@ -218,6 +234,8 @@ val default_request_setup_session :
?client_pid:int32 ->
?client_application:string option ->
?on_behalf_of:int32 option ->
+ ?client_user:string option ->
+ ?client_sudo_user:string option ->
unit ->
request_setup_session
(** [default_request_setup_session ()] is the default value for type [request_setup_session] *)
@@ -228,11 +246,11 @@ val default_request_session_of_pid :
request_session_of_pid
(** [default_request_session_of_pid ()] is the default value for type [request_session_of_pid] *)
-val default_request_session_update_pid :
- ?client_pid:int32 ->
+val default_request_session_exists :
+ ?dummy:int32 option ->
unit ->
- request_session_update_pid
-(** [default_request_session_update_pid ()] is the default value for type [request_session_update_pid] *)
+ request_session_exists
+(** [default_request_session_exists ()] is the default value for type [request_session_exists] *)
val default_request_get_config :
?dummy:int32 option ->
@@ -265,6 +283,22 @@ val default_request_delete :
request_delete
(** [default_request_delete ()] is the default value for type [request_delete] *)
+val default_request_aux_set :
+ ?path:string list ->
+ ?script_name:string ->
+ ?tag_value:string option ->
+ unit ->
+ request_aux_set
+(** [default_request_aux_set ()] is the default value for type [request_aux_set] *)
+
+val default_request_aux_delete :
+ ?path:string list ->
+ ?script_name:string ->
+ ?tag_value:string option ->
+ unit ->
+ request_aux_delete
+(** [default_request_aux_delete ()] is the default value for type [request_aux_delete] *)
+
val default_request_discard :
?dummy:int32 option ->
unit ->
@@ -279,16 +313,16 @@ val default_request_session_changed :
val default_request_rename :
?edit_level:string list ->
- ?from:string ->
- ?to_:string ->
+ ?source:string ->
+ ?destination:string ->
unit ->
request_rename
(** [default_request_rename ()] is the default value for type [request_rename] *)
val default_request_copy :
?edit_level:string list ->
- ?from:string ->
- ?to_:string ->
+ ?source:string ->
+ ?destination:string ->
unit ->
request_copy
(** [default_request_copy ()] is the default value for type [request_copy] *)
@@ -438,8 +472,8 @@ val pp_request_setup_session : Format.formatter -> request_setup_session -> unit
val pp_request_session_of_pid : Format.formatter -> request_session_of_pid -> unit
(** [pp_request_session_of_pid v] formats v *)
-val pp_request_session_update_pid : Format.formatter -> request_session_update_pid -> unit
-(** [pp_request_session_update_pid v] formats v *)
+val pp_request_session_exists : Format.formatter -> request_session_exists -> unit
+(** [pp_request_session_exists v] formats v *)
val pp_request_get_config : Format.formatter -> request_get_config -> unit
(** [pp_request_get_config v] formats v *)
@@ -456,6 +490,12 @@ val pp_request_set : Format.formatter -> request_set -> unit
val pp_request_delete : Format.formatter -> request_delete -> unit
(** [pp_request_delete v] formats v *)
+val pp_request_aux_set : Format.formatter -> request_aux_set -> unit
+(** [pp_request_aux_set v] formats v *)
+
+val pp_request_aux_delete : Format.formatter -> request_aux_delete -> unit
+(** [pp_request_aux_delete v] formats v *)
+
val pp_request_discard : Format.formatter -> request_discard -> unit
(** [pp_request_discard v] formats v *)
@@ -546,8 +586,8 @@ val encode_pb_request_setup_session : request_setup_session -> Pbrt.Encoder.t ->
val encode_pb_request_session_of_pid : request_session_of_pid -> Pbrt.Encoder.t -> unit
(** [encode_pb_request_session_of_pid v encoder] encodes [v] with the given [encoder] *)
-val encode_pb_request_session_update_pid : request_session_update_pid -> Pbrt.Encoder.t -> unit
-(** [encode_pb_request_session_update_pid v encoder] encodes [v] with the given [encoder] *)
+val encode_pb_request_session_exists : request_session_exists -> Pbrt.Encoder.t -> unit
+(** [encode_pb_request_session_exists v encoder] encodes [v] with the given [encoder] *)
val encode_pb_request_get_config : request_get_config -> Pbrt.Encoder.t -> unit
(** [encode_pb_request_get_config v encoder] encodes [v] with the given [encoder] *)
@@ -564,6 +604,12 @@ val encode_pb_request_set : request_set -> Pbrt.Encoder.t -> unit
val encode_pb_request_delete : request_delete -> Pbrt.Encoder.t -> unit
(** [encode_pb_request_delete v encoder] encodes [v] with the given [encoder] *)
+val encode_pb_request_aux_set : request_aux_set -> Pbrt.Encoder.t -> unit
+(** [encode_pb_request_aux_set v encoder] encodes [v] with the given [encoder] *)
+
+val encode_pb_request_aux_delete : request_aux_delete -> Pbrt.Encoder.t -> unit
+(** [encode_pb_request_aux_delete v encoder] encodes [v] with the given [encoder] *)
+
val encode_pb_request_discard : request_discard -> Pbrt.Encoder.t -> unit
(** [encode_pb_request_discard v encoder] encodes [v] with the given [encoder] *)
@@ -654,8 +700,8 @@ val decode_pb_request_setup_session : Pbrt.Decoder.t -> request_setup_session
val decode_pb_request_session_of_pid : Pbrt.Decoder.t -> request_session_of_pid
(** [decode_pb_request_session_of_pid decoder] decodes a [request_session_of_pid] binary value from [decoder] *)
-val decode_pb_request_session_update_pid : Pbrt.Decoder.t -> request_session_update_pid
-(** [decode_pb_request_session_update_pid decoder] decodes a [request_session_update_pid] binary value from [decoder] *)
+val decode_pb_request_session_exists : Pbrt.Decoder.t -> request_session_exists
+(** [decode_pb_request_session_exists decoder] decodes a [request_session_exists] binary value from [decoder] *)
val decode_pb_request_get_config : Pbrt.Decoder.t -> request_get_config
(** [decode_pb_request_get_config decoder] decodes a [request_get_config] binary value from [decoder] *)
@@ -672,6 +718,12 @@ val decode_pb_request_set : Pbrt.Decoder.t -> request_set
val decode_pb_request_delete : Pbrt.Decoder.t -> request_delete
(** [decode_pb_request_delete decoder] decodes a [request_delete] binary value from [decoder] *)
+val decode_pb_request_aux_set : Pbrt.Decoder.t -> request_aux_set
+(** [decode_pb_request_aux_set decoder] decodes a [request_aux_set] binary value from [decoder] *)
+
+val decode_pb_request_aux_delete : Pbrt.Decoder.t -> request_aux_delete
+(** [decode_pb_request_aux_delete decoder] decodes a [request_aux_delete] binary value from [decoder] *)
+
val decode_pb_request_discard : Pbrt.Decoder.t -> request_discard
(** [decode_pb_request_discard decoder] decodes a [request_discard] binary value from [decoder] *)
diff --git a/src/vyconfd.ml b/src/vyconfd.ml
index f1b1694..05cd693 100644
--- a/src/vyconfd.ml
+++ b/src/vyconfd.ml
@@ -29,9 +29,9 @@ let legacy_config_path = ref false
(* Global data *)
let sessions : (string, Session.session_data) Hashtbl.t = Hashtbl.create 10
-let commit_lock : string option ref = ref None
+let commit_lock : int32 option ref = ref None
-let conf_mode_lock : string option ref = ref None
+let conf_mode_lock : int32 option ref = ref None
(* Command line arguments *)
let args = [
@@ -67,9 +67,18 @@ let make_session_token () =
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 user =
+ match req.client_user with
+ | None -> ""
+ | Some u -> u
+ in
+ let sudo_user =
+ match req.client_sudo_user with
+ | None -> ""
+ | Some u -> u
+ in
let client_app = Option.value req.client_application ~default:"unknown client" in
- let () = Hashtbl.add sessions token (Session.make world client_app user pid) in
+ let () = Hashtbl.add sessions token (Session.make world client_app sudo_user user pid) in
{response_tmpl with output=(Some token)}
let session_of_pid _world (req: request_session_of_pid) =
@@ -77,15 +86,9 @@ let session_of_pid _world (req: request_session_of_pid) =
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
+let session_exists _world token (_req: request_session_exists) =
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;
+ let _ = Hashtbl.find sessions token in
{response_tmpl with output=(Some token)}
with Not_found -> {response_tmpl with status=Fail; output=None}
@@ -100,14 +103,14 @@ let enter_conf_mode req token =
let lock = !conf_mode_lock in
let session = Hashtbl.find sessions token in
match lock with
- | Some user ->
+ | Some pid ->
if req.override_exclusive then aux token session
else
{response_tmpl with
status=Configuration_locked;
- error=Some (Printf.sprintf "Configuration was locked by %s" user)}
+ error=Some (Printf.sprintf "Configuration was locked by %ld" pid)}
| None ->
- if req.exclusive then (conf_mode_lock := Some session.user; aux token session)
+ if req.exclusive then (conf_mode_lock := Some session.client_pid; aux token session)
else aux token session
let exit_conf_mode world token =
@@ -207,6 +210,34 @@ let delete world token (req: request_delete) =
response_tmpl
with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)}
+let aux_set world token (req: request_aux_set) =
+ try
+ let () = (Lwt_log.debug @@ Printf.sprintf "[%s]\n" (Vyos1x.Util.string_of_list req.path)) |> Lwt.ignore_result in
+ let () =
+ Session.aux_set
+ world
+ (find_session token)
+ req.path
+ req.script_name
+ req.tag_value
+ in
+ response_tmpl
+ with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)}
+
+let aux_delete world token (req: request_aux_delete) =
+ try
+ let () = (Lwt_log.debug @@ Printf.sprintf "[%s]\n" (Vyos1x.Util.string_of_list req.path)) |> Lwt.ignore_result in
+ let () =
+ Session.aux_delete
+ world
+ (find_session token)
+ req.path
+ req.script_name
+ req.tag_value
+ in
+ response_tmpl
+ with Session.Session_error msg -> {response_tmpl with status=Fail; error=(Some msg)}
+
let discard world token (_req: request_discard) =
try
let session = Session.discard world (find_session token)
@@ -242,8 +273,15 @@ let commit world token (req: request_commit) =
let s = find_session token in
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
+ 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
in
let%lwt received_commit_data = VC.do_commit commit_data in
let%lwt result_commit_data =
@@ -257,20 +295,27 @@ let commit world token (req: request_commit) =
let res, out =
init_data.success, init_data.out
in
+ let () =
+ (Lwt_log.debug @@ Printf.sprintf "aux_changeset: %s" (Session.sprint_changeset s.aux_changeset)) |> Lwt.ignore_result
+ in
match res with
| false ->
Lwt.return {response_tmpl with status=Internal_error; error=(Some out)}
| true ->
- (* partial commit *)
if not req_dry_run then
- world.Session.running_config <- result_commit_data.config_result;
+ let post_running, post_proposed =
+ Session.post_process_commit world s (result_commit_data, proposed_config)
+ in
+ world.Session.running_config <- post_running;
let session =
{ s with changeset =
Session.get_changeset
world
world.Session.running_config
- proposed_config }
- in Hashtbl.replace sessions token session;
+ post_proposed;
+ aux_changeset = []; }
+ in Hashtbl.replace sessions token session
+ else ();
let success, msg_str =
result_commit_data.result.success, result_commit_data.result.out
@@ -320,7 +365,7 @@ let rec handle_connection world ic oc () =
| _, 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, Session_update_pid r -> session_update_pid world t r
+ | Some t, Session_exists r -> session_exists 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
@@ -332,6 +377,8 @@ let rec handle_connection world ic oc () =
| Some t, Validate r -> validate world t r
| Some t, Set r -> set world t r
| Some t, Delete r -> delete world t r
+ | Some t, Aux_set r -> aux_set world t r
+ | Some t, Aux_delete r -> aux_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