boot: Allow template to specify custom libvirt XML.
[mclu.git] / utils.ml
1 (* mclu: Mini Cloud
2  * Copyright (C) 2014-2015 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *)
18
19 (* Miscellaneous utility functions. *)
20
21 open Scanf
22 open Printf
23
24 module D = Libvirt.Domain
25
26 let (//) = Filename.concat
27 let quote = Filename.quote
28
29 let ( +^ ) = Int64.add
30 let ( -^ ) = Int64.sub
31 let ( *^ ) = Int64.mul
32 let ( /^ ) = Int64.div
33 let ( &^ ) = Int64.logand
34 let ( ~^ ) = Int64.lognot
35
36 let rec filter_map f = function
37   | [] -> []
38   | x :: xs ->
39       match f x with
40       | Some y -> y :: filter_map f xs
41       | None -> filter_map f xs
42
43 let human_size i =
44   let sign, i = if i < 0L then "-", Int64.neg i else "", i in
45
46   if i < 1024L then
47     sprintf "%s%Ld" sign i
48   else (
49     let f = Int64.to_float i /. 1024. in
50     let i = i /^ 1024L in
51     if i < 1024L then
52       sprintf "%s%.1fK" sign f
53     else (
54       let f = Int64.to_float i /. 1024. in
55       let i = i /^ 1024L in
56       if i < 1024L then
57         sprintf "%s%.1fM" sign f
58       else (
59         let f = Int64.to_float i /. 1024. in
60         (*let i = i /^ 1024L in*)
61         sprintf "%s%.1fG" sign f
62       )
63     )
64   )
65
66 let bytes_of_human_size s =
67   try sscanf s "%Ld%[Gg]" (fun b _ -> b *^ 1024L *^ 1024L *^ 1024L)
68   with Scan_failure _ ->
69     try sscanf s "%Ld%[Mm]" (fun b _ -> b *^ 1024L *^ 1024L)
70     with Scan_failure _ ->
71       try sscanf s "%Ld%[Kk]" (fun b _ -> b *^ 1024L)
72       with Scan_failure _ ->
73         try sscanf s "%Ld%[Bb]" (fun b _ -> b)
74         with Scan_failure _ ->
75           raise Not_found
76
77 let string_of_dom_state = function
78   | D.InfoNoState -> "unknown"
79   | D.InfoRunning -> "running"
80   | D.InfoBlocked -> "blocked"
81   | D.InfoPaused -> "paused"
82   | D.InfoShutdown -> "shutdown"
83   | D.InfoShutoff -> "shutoff"
84   | D.InfoCrashed -> "crashed"
85
86 let regexp_of_glob s =
87   let len = String.length s in
88   let buf = Buffer.create len in
89   Buffer.add_char buf '^';
90   for i = 0 to len-1 do
91     match String.unsafe_get s i with
92     (* Wildcard characters converted to regular expressions. *)
93     | '?' -> Buffer.add_char buf '.'
94     | '*' -> Buffer.add_string buf ".*"
95     (* Must escape any character which is special for PCRE - see
96      * pcrepattern(3).  However ignore [..] because they are
97      * (approximately) the same for globs and regexps.
98      *)
99     | ('\\' | '^' | '$' | '.' | '|' | '(' | ')'
100           | '+' | '{') as c ->
101       Buffer.add_char buf '\\'; Buffer.add_char buf c
102     | c -> Buffer.add_char buf c
103   done;
104   Buffer.add_char buf '$';
105   Buffer.contents buf
106
107 let string_random8 =
108   let chars = "abcdefghijklmnopqrstuvwxyz0123456789" in
109   fun () ->
110     String.concat "" (
111       List.map (
112         fun _ ->
113           let c = Random.int 36 in
114           let c = chars.[c] in
115           String.make 1 c
116       ) [1;2;3;4;5;6;7;8]
117     )
118
119 let name_parse name =
120   let i = try Some (String.index name ':') with Not_found -> None in
121   match i with
122   | None -> None, name
123   | Some i ->
124     Some (String.sub name 0 i),
125     String.sub name (i+1) (String.length name - i - 1)