fd92b790ac8e9bade84df6de4eb5fbfcba440cb0
[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 human_size i =
37   let sign, i = if i < 0L then "-", Int64.neg i else "", i in
38
39   if i < 1024L then
40     sprintf "%s%Ld" sign i
41   else (
42     let f = Int64.to_float i /. 1024. in
43     let i = i /^ 1024L in
44     if i < 1024L then
45       sprintf "%s%.1fK" sign f
46     else (
47       let f = Int64.to_float i /. 1024. in
48       let i = i /^ 1024L in
49       if i < 1024L then
50         sprintf "%s%.1fM" sign f
51       else (
52         let f = Int64.to_float i /. 1024. in
53         (*let i = i /^ 1024L in*)
54         sprintf "%s%.1fG" sign f
55       )
56     )
57   )
58
59 let bytes_of_human_size s =
60   try sscanf s "%Ld%[Gg]" (fun b _ -> b *^ 1024L *^ 1024L *^ 1024L)
61   with Scan_failure _ ->
62     try sscanf s "%Ld%[Mm]" (fun b _ -> b *^ 1024L *^ 1024L)
63     with Scan_failure _ ->
64       try sscanf s "%Ld%[Kk]" (fun b _ -> b *^ 1024L)
65       with Scan_failure _ ->
66         try sscanf s "%Ld%[Bb]" (fun b _ -> b)
67         with Scan_failure _ ->
68           raise Not_found
69
70 let string_of_dom_state = function
71   | D.InfoNoState -> "unknown"
72   | D.InfoRunning -> "running"
73   | D.InfoBlocked -> "blocked"
74   | D.InfoPaused -> "paused"
75   | D.InfoShutdown -> "shutdown"
76   | D.InfoShutoff -> "shutoff"
77   | D.InfoCrashed -> "crashed"
78
79 let regexp_of_glob s =
80   let len = String.length s in
81   let buf = Buffer.create len in
82   Buffer.add_char buf '^';
83   for i = 0 to len-1 do
84     match String.unsafe_get s i with
85     (* Wildcard characters converted to regular expressions. *)
86     | '?' -> Buffer.add_char buf '.'
87     | '*' -> Buffer.add_string buf ".*"
88     (* Must escape any character which is special for PCRE - see
89      * pcrepattern(3).  However ignore [..] because they are
90      * (approximately) the same for globs and regexps.
91      *)
92     | ('\\' | '^' | '$' | '.' | '|' | '(' | ')'
93           | '+' | '{') as c ->
94       Buffer.add_char buf '\\'; Buffer.add_char buf c
95     | c -> Buffer.add_char buf c
96   done;
97   Buffer.add_char buf '$';
98   Buffer.contents buf
99
100 let string_random8 =
101   let chars = "abcdefghijklmnopqrstuvwxyz0123456789" in
102   fun () ->
103     String.concat "" (
104       List.map (
105         fun _ ->
106           let c = Random.int 36 in
107           let c = chars.[c] in
108           String.make 1 c
109       ) [1;2;3;4;5;6;7;8]
110     )
111
112 let name_parse name =
113   let i = try Some (String.index name ':') with Not_found -> None in
114   match i with
115   | None -> None, name
116   | Some i ->
117     Some (String.sub name 0 i),
118     String.sub name (i+1) (String.length name - i - 1)