(* 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