summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--_oasis4
-rw-r--r--data/examples/vyconfd.conf17
-rw-r--r--src/vyconf_config.ml66
-rw-r--r--src/vyconf_config.mli7
4 files changed, 87 insertions, 7 deletions
diff --git a/_oasis b/_oasis
index 58eae3f..4dbbb3e 100644
--- a/_oasis
+++ b/_oasis
@@ -53,7 +53,7 @@ Library "vyconf_config"
Path: src
Modules: Vyconf_config
FindlibParent: vyconf
- BuildDepends: ppx_deriving_yojson
+ BuildDepends: toml, ppx_deriving.show
Library "message"
Path: src
@@ -65,7 +65,7 @@ Executable "vyconfd"
Path: src
MainIs: vyconfd.ml
CompiledObject: best
- BuildDepends: ppx_deriving.runtime, ppx_deriving_yojson.runtime, lwt, lwt.unix, lwt.ppx, vyconf
+ BuildDepends: ppx_deriving.runtime, ppx_deriving_yojson.runtime, lwt, lwt.unix, lwt.ppx, toml, vyconf
Executable "vytree_test"
Path: test
diff --git a/data/examples/vyconfd.conf b/data/examples/vyconfd.conf
new file mode 100644
index 0000000..85a4523
--- /dev/null
+++ b/data/examples/vyconfd.conf
@@ -0,0 +1,17 @@
+[appliance]
+
+name = "Test Appliance"
+
+data_dir = "/usr/share/testappliance"
+program_dir = "/usr/libexec/testappliance"
+config_dir = "/etc/testappliance"
+
+# paths relative to config_dir
+primary_config = "config.boot"
+fallback_config = "config.failsafe"
+
+[vyconf]
+
+socket = "/var/run/vyconfd.sock"
+pid_file = "/var/run/vyconfd.pid"
+log_file = "/var/log/vyconfd.log"
diff --git a/src/vyconf_config.ml b/src/vyconf_config.ml
index 92fcbb0..21c23ee 100644
--- a/src/vyconf_config.ml
+++ b/src/vyconf_config.ml
@@ -1,14 +1,72 @@
+exception Missing_field of string
+
type vyconf_config = {
app_name: string;
- app_dir: string;
+ data_dir: string;
+ program_dir: string;
config_dir: string;
primary_config: string;
fallback_config: string;
socket: string;
-} [@@deriving yojson]
+ pid_file: string;
+ log_file: string option;
+} [@@deriving show]
+
+(* XXX: there should be a better way than to fully initialize it
+ with garbage just to update it later *)
+let empty_config = {
+ app_name = "";
+ data_dir = "";
+ program_dir = "";
+ config_dir = "";
+ primary_config = "";
+ fallback_config = "";
+ socket = "";
+ pid_file = "";
+ log_file = None;
+}
+
+
+(* XXX: We assume that nesting in TOML config files never goes beyond two levels *)
+
+let get_field conf tbl_name field_name =
+ (* NB: TomlLenses module uses "table" and "field" names for function names,
+ hence tbl_name and field_name
+ *)
+ TomlLenses.(get conf (key tbl_name |-- table |-- key field_name |-- string))
+
+let mandatory_field conf table field =
+ let value = get_field conf table field in
+ match value with
+ | Some value -> value
+ | None -> raise @@ Missing_field (Printf.sprintf "Invalid config: Missing mandatory field \"%s\" in section [%s]" field table)
+let optional_field default conf table field =
+ let value = get_field conf table field in
+ match value with
+ | Some value -> value
+ | None -> default
let load filename =
- try Yojson.Safe.from_file filename |> vyconf_config_of_yojson
- with Sys_error msg -> Result.Error msg
+ try
+ let open Defaults in
+ let conf_toml = Toml.Parser.from_filename filename |> Toml.Parser.unsafe in
+ let conf = empty_config in
+ (* Mandatory fields *)
+ 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 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
+ (* Optional fields *)
+ let conf = {conf with pid_file = optional_field defaults.pid_file conf_toml "vyconf" "pid_file"} in
+ let conf = {conf with socket = optional_field defaults.socket conf_toml "vyconf" "socket"} in
+ (* log_file is already string option, so we don't need to unwrap *)
+ let conf = {conf with log_file = get_field conf_toml "vyconf" "log_file"} in
+ Result.Ok conf
+ with
+ | Sys_error msg -> Result.Error msg
+ | Toml.Parser.Error (msg, _) -> Result.Error msg
+let dump = show_vyconf_config
diff --git a/src/vyconf_config.mli b/src/vyconf_config.mli
index 30d8ea7..bd70652 100644
--- a/src/vyconf_config.mli
+++ b/src/vyconf_config.mli
@@ -1,10 +1,15 @@
type vyconf_config = {
app_name: string;
- app_dir: string;
+ data_dir: string;
+ program_dir: string;
config_dir: string;
primary_config: string;
fallback_config: string;
socket: string;
+ pid_file: string;
+ log_file: string option;
}
val load : string -> (vyconf_config, string) Result.result
+
+val dump : vyconf_config -> string