--- /dev/null
+(* mclu: Mini Cloud
+ * Copyright (C) 2014-2015 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(* Parsing /etc/mclu.conf *)
+
+open Printf
+
+(* blank line *)
+let is_blank_line =
+ let rex = Pcre.regexp "^\\s*$" in
+ Pcre.pmatch ~rex
+
+(* comment *)
+let is_comment =
+ let rex = Pcre.regexp "^\\s*#" in
+ Pcre.pmatch ~rex
+
+(* [header] *)
+let is_header =
+ let rex = Pcre.regexp "^\\s*\\[(\\w+)\\]\\s*$" in
+ fun line ->
+ try
+ let subs = Pcre.exec ~rex line in
+ Some (Pcre.get_substring subs 1)
+ with
+ Not_found -> None
+
+let ws_rex = Pcre.regexp "\\s+"
+
+type node = {
+ hostname : string;
+ libvirt_uri : string;
+ mac_addr : string option;
+}
+
+let _nodes : node list ref = ref []
+
+let load_configuration config_file =
+ let chan =
+ try open_in config_file
+ with Sys_error msg ->
+ eprintf "mclu: %s: cannot open configuration file: %s\n" config_file msg;
+ exit 1 in
+ let rec loop section =
+ let line = input_line chan in
+ if is_blank_line line || is_comment line then
+ loop section
+ else (
+ match is_header line with
+ | Some "nodes" ->
+ loop `Nodes
+ | Some section ->
+ (* Ignore unknown sections and keep going. *)
+ printf "mclu: %s: warning: ignoring unknown section [%s]\n"
+ config_file section;
+ loop `Unknown
+ | None ->
+ (* How we parse lines within sections depends on the header. *)
+ match section with
+ | `Nodes ->
+ (* If we're in the [nodes] section, parse "hostname [key=value].." *)
+ (match Pcre.split ~rex:ws_rex line with
+ | [] -> assert false
+ | hostname :: defs ->
+ let node = {
+ hostname = hostname;
+ libvirt_uri = sprintf "qemu+ssh://root@%s/system" hostname;
+ mac_addr = None
+ } in
+ let node = List.fold_left (
+ fun node def ->
+ match Pcre.split ~pat:"=" ~max:2 def with
+ | ["mac"; value] -> { node with mac_addr = Some value }
+ | ["uri"; value] -> { node with libvirt_uri = value }
+ | [_] -> node (* key with no value - ignore *)
+ | [_; _] -> node (* unknown key=value - ignore *)
+ | _ -> assert false
+ ) node defs in
+ _nodes := node :: !_nodes;
+ loop section
+ )
+ | `Global
+ | `Unknown ->
+ (* Ignore the line. *)
+ printf "mclu: %s: warning: ignoring `%s'\n" config_file line;
+ loop section
+ )
+ in
+ (try
+ loop `Global
+ with End_of_file -> ()
+ );
+ close_in chan;
+
+ _nodes := List.rev !_nodes
+
+(* Get list of nodes. *)
+let nodes () = !_nodes