~ubuntu-branches/ubuntu/quantal/xen-api/quantal

« back to all changes in this revision

Viewing changes to ocaml/xapi/xha_interface.ml

  • Committer: Package Import Robot
  • Author(s): Jon Ludlam
  • Date: 2011-07-07 21:50:18 UTC
  • Revision ID: package-import@ubuntu.com-20110707215018-3t9ekbh7qy5y2b1p
Tags: upstream-1.3
ImportĀ upstreamĀ versionĀ 1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(*
 
2
 * Copyright (C) 2006-2009 Citrix Systems Inc.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU Lesser General Public License as published
 
6
 * by the Free Software Foundation; version 2.1 only. with the special
 
7
 * exception on linking described in file LICENSE.
 
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 Lesser General Public License for more details.
 
13
 *)
 
14
open API
 
15
open Hashtblext
 
16
open Pervasiveext
 
17
open Stringext
 
18
open Listext
 
19
 
 
20
(* === Common XML operations === *)
 
21
 
 
22
(** Generates an XML leaf element of the form: *)
 
23
(**     <name>value</name>                     *)
 
24
let xml_leaf_element name value =
 
25
        Xml.Element (
 
26
                name, [], [Xml.PCData value]
 
27
        )
 
28
 
 
29
(** Returns true iff. the given element matches the given name. *)
 
30
let xml_element_has_name name element =
 
31
        match element with
 
32
                | Xml.Element (name_, _, _) -> name = name_
 
33
                | _                         -> false
 
34
 
 
35
(** Returns a sub-list of the given element list, containing *)
 
36
(** only those elements with the specified name.             *)
 
37
let xml_elements_with_name elements name =
 
38
        List.filter (xml_element_has_name name) elements
 
39
 
 
40
(** Returns the first element with the specified name from *)
 
41
(** the given element list.                                *)
 
42
let first_xml_element_with_name elements name =
 
43
        try
 
44
                Some (List.find (xml_element_has_name name) elements)
 
45
        with
 
46
                Not_found -> None
 
47
 
 
48
(** Parses an XML element of the form "<name>value</value>".  *)
 
49
(** Returns a (name, value) string pair, where the arguments  *)
 
50
(** are stripped of leading and trailing whitespace.          *)
 
51
let hash_table_entry_of_leaf_xml_element = function
 
52
        | Xml.Element (name, _, Xml.PCData (value) :: values) ->
 
53
                Some (
 
54
                        String.strip String.isspace name, 
 
55
                        String.strip String.isspace value
 
56
                )
 
57
        | Xml.Element (name, _, []) -> Some (String.strip String.isspace name, "")
 
58
        | _ -> None
 
59
 
 
60
(** Parses a list of XML elements of the form:    *)
 
61
(**     <name0>value0</name0>                     *)
 
62
(**     <name1>value1</name1>                     *)
 
63
(**     <name2>value2</name2>                     *)
 
64
(**     ...                                       *)
 
65
(** Returns a string hash table with an entry for *)
 
66
(** each element matched:                         *)
 
67
(**     (name0 -> value0)                         *)
 
68
(**     (name1 -> value1)                         *)
 
69
(**     (name2 -> value2)                         *)
 
70
(**     ...                                       *)
 
71
let hash_table_of_leaf_xml_element_list list =
 
72
        Hashtbl.of_list (
 
73
                List.filter_map hash_table_entry_of_leaf_xml_element list
 
74
        )
 
75
 
 
76
(* === Daemon configuration === *)
 
77
 
 
78
module DaemonConfiguration = struct
 
79
 
 
80
        (* Taken from Marathon's spec section 4.1.4.4 *)
 
81
        let filename = "/etc/xensource/xhad.conf"
 
82
 
 
83
        module Host = struct
 
84
 
 
85
                type t = {
 
86
                        uuid : string;
 
87
                        address : string
 
88
                }
 
89
 
 
90
                (** Simple type convertor. *)
 
91
                let of_host_t host_t = {
 
92
                        uuid    = host_t.host_uuid   ;
 
93
                        address = host_t.host_address;
 
94
                }
 
95
 
 
96
                (** Converts the given HA daemon host configuration *)
 
97
                (** into an XML element tree.                       *)
 
98
                let to_xml_element host = 
 
99
                        Xml.Element (
 
100
                                "host", [], [
 
101
                                        (xml_leaf_element "HostID"    host.uuid   );
 
102
                                        (xml_leaf_element "IPaddress" host.address);
 
103
                                ]
 
104
                        )
 
105
 
 
106
        end
 
107
 
 
108
        type t = {
 
109
                common_generation_uuid : string;
 
110
                common_udp_port : int;
 
111
                common_hosts : Host.t list;
 
112
                local_host_uuid : string;
 
113
                local_heart_beat_interface : string;
 
114
                local_heart_beat_physical_interface : string;
 
115
                local_state_file : string;
 
116
                heart_beat_interval : int option;
 
117
                state_file_interval : int option;
 
118
                heart_beat_timeout : int option;
 
119
                state_file_timeout : int option;
 
120
                heart_beat_watchdog_timeout : int option;
 
121
                state_file_watchdog_timeout : int option;
 
122
                boot_join_timeout : int option;
 
123
                enable_join_timeout : int option;
 
124
                xapi_healthcheck_interval : int option;
 
125
                xapi_healthcheck_timeout : int option;
 
126
                xapi_restart_attempts : int option;
 
127
                xapi_restart_timeout : int option;
 
128
                xapi_licensecheck_timeout : int option;
 
129
        }
 
130
 
 
131
        (** See interface. *)
 
132
        let create
 
133
                ?(common_udp_port = 49154)
 
134
                ?heart_beat_interval
 
135
                ?state_file_interval
 
136
                ?heart_beat_timeout
 
137
                ?state_file_timeout
 
138
                ?heart_beat_watchdog_timeout
 
139
                ?state_file_watchdog_timeout
 
140
                ?boot_join_timeout
 
141
                ?enable_join_timeout
 
142
                ?xapi_healthcheck_interval
 
143
                ?xapi_healthcheck_timeout
 
144
                ?xapi_restart_attempts
 
145
                ?xapi_restart_timeout
 
146
                ?xapi_licensecheck_timeout
 
147
                ~common_generation_uuid
 
148
                ~local_heart_beat_interface
 
149
                ~local_heart_beat_physical_interface
 
150
                ~local_state_file
 
151
                ~__context
 
152
                () =
 
153
                        let records = Db.Host.get_all_records ~__context in
 
154
                        let common_hosts = List.map
 
155
                                (fun (_, host) -> Host.of_host_t host)
 
156
                                records in
 
157
                        let local_host_uuid = 
 
158
                                Db.Host.get_uuid 
 
159
                                ~__context ~self:!Xapi_globs.localhost_ref in
 
160
                        {
 
161
                                common_hosts                = common_hosts;
 
162
                                common_generation_uuid      = (Uuid.to_string common_generation_uuid);
 
163
                                common_udp_port             = common_udp_port;
 
164
                                local_host_uuid             = local_host_uuid;
 
165
                                local_heart_beat_interface  = local_heart_beat_interface;
 
166
                                local_heart_beat_physical_interface = local_heart_beat_physical_interface;
 
167
                                local_state_file            = local_state_file;
 
168
                                heart_beat_interval         = heart_beat_interval;
 
169
                                state_file_interval         = state_file_interval;
 
170
                                heart_beat_timeout          = heart_beat_timeout;
 
171
                                state_file_timeout          = state_file_timeout;
 
172
                                heart_beat_watchdog_timeout = heart_beat_watchdog_timeout;
 
173
                                state_file_watchdog_timeout = state_file_watchdog_timeout;
 
174
                                boot_join_timeout           = boot_join_timeout;
 
175
                                enable_join_timeout         = enable_join_timeout;
 
176
                                xapi_healthcheck_interval   = xapi_healthcheck_interval;
 
177
                                xapi_healthcheck_timeout    = xapi_healthcheck_timeout;
 
178
                                xapi_restart_attempts       = xapi_restart_attempts;
 
179
                                xapi_restart_timeout        = xapi_restart_timeout;
 
180
                                xapi_licensecheck_timeout   = xapi_licensecheck_timeout;
 
181
                        }
 
182
 
 
183
        let int_parameter (name, param) = 
 
184
                Opt.default [] (Opt.map (fun x -> [ xml_leaf_element name (string_of_int x) ]) param) 
 
185
 
 
186
        (** Converts the given HA daemon configuration *)
 
187
        (** into an XML element tree.                  *)
 
188
        let to_xml_element config = Xml.Element (
 
189
                "xhad-config",
 
190
                [("version", "1.0")],
 
191
                [
 
192
                        Xml.Element (
 
193
                                "common-config", [],
 
194
                                xml_leaf_element "GenerationUUID" (              config.common_generation_uuid) ::
 
195
                                xml_leaf_element "UDPport"        (string_of_int config.common_udp_port       ) ::
 
196
                                List.map Host.to_xml_element config.common_hosts @
 
197
                                [
 
198
                                        Xml.Element ("parameters", [],
 
199
                                                     List.concat (List.map int_parameter
 
200
                                                                    [ "HeartbeatInterval",        config.heart_beat_interval;
 
201
                                                                      "HeartbeatTimeout",         config.heart_beat_timeout;
 
202
                                                                      "StateFileInterval",        config.state_file_interval;
 
203
                                                                      "StateFileTimeout",         config.state_file_timeout;
 
204
                                                                      "HeartbeatWatchdogTimeout", config.heart_beat_watchdog_timeout;
 
205
                                                                      "StateFileWatchdogTimeout", config.state_file_watchdog_timeout;
 
206
                                                                      "BootJoinTimeout",          config.boot_join_timeout;
 
207
                                                                      "EnableJoinTimeout",        config.enable_join_timeout;
 
208
                                                                      "XapiHealthCheckInterval",  config.xapi_healthcheck_interval;
 
209
                                                                      "XapiHealthCheckTimeout",   config.xapi_healthcheck_timeout;
 
210
                                                                      "XapiRestartAttempts",      config.xapi_restart_attempts;
 
211
                                                                      "XapiRestartTimeout",       config.xapi_restart_timeout;
 
212
                                                                      "XapiLicenseCheckTimeout",  config.xapi_licensecheck_timeout;
 
213
                                                                    ])
 
214
                                                    )
 
215
                                ]
 
216
                        );
 
217
                        Xml.Element (
 
218
                                "local-config", [],
 
219
                                [
 
220
                                        Xml.Element (
 
221
                                                "localhost", [],
 
222
                                                [
 
223
                                                        xml_leaf_element "HostID"             config.local_host_uuid           ;
 
224
                                                        xml_leaf_element "HeartbeatInterface" config.local_heart_beat_interface;
 
225
                                                        xml_leaf_element "HeartbeatPhysicalInterface" config.local_heart_beat_physical_interface;
 
226
                                                        xml_leaf_element "StateFile"          config.local_state_file          ;
 
227
                                                ]
 
228
                                        )
 
229
                                ]
 
230
                        )
 
231
                ]
 
232
        )
 
233
 
 
234
        (** Converts the given HA daemon configuration *)
 
235
        (** into an XML string.                        *)
 
236
        let to_xml_string config =
 
237
                "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" ^ (
 
238
                        Xml.to_string_fmt (
 
239
                                to_xml_element config
 
240
                        )
 
241
                )
 
242
 
 
243
end
 
244
 
 
245
(* === Live Set Information === *)
 
246
 
 
247
module LiveSetInformation = struct
 
248
 
 
249
        module Status = struct
 
250
 
 
251
                type t = Online | Offline | Starting
 
252
 
 
253
                let of_string string =
 
254
                        match String.lowercase string with
 
255
                                | "online" -> Some (Online)
 
256
                                | "offline" -> Some (Offline)
 
257
                                | "starting" -> Some Starting
 
258
                                | _ -> invalid_arg "Invalid status string."
 
259
 
 
260
                let to_string = function
 
261
                        | Online -> "online"
 
262
                        | Offline -> "offline"
 
263
                        | Starting -> "starting"
 
264
 
 
265
        end
 
266
 
 
267
        module Host = struct
 
268
 
 
269
                type t = {
 
270
                        id: [`host] Uuid.t;
 
271
                        liveness: bool;
 
272
                        master: bool;
 
273
                        state_file_access: bool;
 
274
                        state_file_corrupted: bool;
 
275
                        excluded: bool
 
276
                }
 
277
 
 
278
                (** Creates a new host record from a host XML element. *)
 
279
                (** The element must contain valid child elements for  *)
 
280
                (** each member of the host record type.               *)
 
281
                let of_xml_element = function
 
282
                        | Xml.Element ("host", _, children) ->
 
283
                                begin
 
284
                                        let table = hash_table_of_leaf_xml_element_list children in
 
285
                                        let find x = 
 
286
                                                try Hashtbl.find table x 
 
287
                                                with Not_found ->
 
288
                                                        invalid_arg (Printf.sprintf "Missig entry '%s' within 'host' element" x) in
 
289
                                        let bool s = 
 
290
                                                try bool_of_string (String.lowercase s) 
 
291
                                                with Invalid_argument _ ->
 
292
                                                        invalid_arg (Printf.sprintf "Invalid boolean value '%s' within 'host' element" s) in
 
293
 
 
294
                                        let uuid = Uuid.of_string in
 
295
                                        Some ({
 
296
                                                id                   = uuid (find "HostID"             );
 
297
                                                liveness             = bool (find "liveness"           );
 
298
                                                master               = bool (find "master"             );
 
299
                                                state_file_access    = bool (find "statefile_access"   );
 
300
                                                state_file_corrupted = bool (find "statefile_corrupted");
 
301
                                                excluded             = bool (find "excluded"           )
 
302
                                        })
 
303
                                end
 
304
                        | _ -> 
 
305
                                None
 
306
 
 
307
        end
 
308
 
 
309
        module HostRawData = struct
 
310
                type t = {
 
311
                        id: [`host] Uuid.t;
 
312
                        time_since_last_update_on_statefile: int;
 
313
                        time_since_last_heartbeat: int;
 
314
                        time_since_xapi_restart_first_attempted: int;
 
315
                        heartbeat_active_list_on_heartbeat: [`host] Uuid.t list;
 
316
                        heartbeat_active_list_on_statefile: [`host] Uuid.t list;
 
317
                        (* ... *)
 
318
                }
 
319
                let of_xml_element = function
 
320
                        | Xml.Element("host_raw_data", _, children) ->
 
321
                                let table = hash_table_of_leaf_xml_element_list children in                         
 
322
                                let find x = 
 
323
                                        try Hashtbl.find table x 
 
324
                                        with Not_found ->
 
325
                                                invalid_arg (Printf.sprintf "Missing entry '%s' within 'host_raw_data' element" x) in
 
326
                                let int s = 
 
327
                                        try int_of_string (String.lowercase s) 
 
328
                                        with Invalid_argument _ ->
 
329
                                                invalid_arg (Printf.sprintf "Invalid integer value '%s' within 'host_raw_data' element" s) in
 
330
                                let uuid = Uuid.of_string in
 
331
                                let set f x = List.map f (String.split_f String.isspace x) in
 
332
                                Some ({
 
333
                                        id = uuid (find "HostID");
 
334
                                        time_since_last_update_on_statefile     = int (find "time_since_last_update_on_statefile"    );
 
335
                                        time_since_last_heartbeat               = int (find "time_since_last_heartbeat"              ); 
 
336
                                        time_since_xapi_restart_first_attempted = int (find "time_since_xapi_restart_first_attempted"); 
 
337
                                        heartbeat_active_list_on_heartbeat      = set uuid (find "heartbeat_active_list_on_heartbeat");
 
338
                                        heartbeat_active_list_on_statefile      = set uuid (find "heartbeat_active_list_on_statefile");
 
339
                                      })
 
340
                        | _ -> None 
 
341
 
 
342
        end
 
343
 
 
344
        module Warning = struct
 
345
                type t = {
 
346
                        statefile_lost: bool;
 
347
                        heartbeat_approaching_timeout: bool;
 
348
                        statefile_approaching_timeout: bool;
 
349
                        xapi_healthcheck_approaching_timeout: bool;
 
350
                        network_bonding_error: bool;
 
351
                }
 
352
                let of_xml_element = function
 
353
                        | Xml.Element("warning_on_local_host", _, children) ->
 
354
                                begin
 
355
                                        let table = hash_table_of_leaf_xml_element_list children in
 
356
                                        let find x = 
 
357
                                                try Hashtbl.find table x 
 
358
                                                with Not_found ->
 
359
                                                        invalid_arg (Printf.sprintf "Missing entry '%s' within 'warning_on_local_host' element" x) in             
 
360
                                        let bool x = find x = "TRUE" in
 
361
                                        Some({
 
362
                                                statefile_lost                        = bool "statefile_lost";
 
363
                                                heartbeat_approaching_timeout         = bool "heartbeat_approaching_timeout";
 
364
                                                statefile_approaching_timeout         = bool "statefile_approaching_timeout";
 
365
                                                xapi_healthcheck_approaching_timeout  = bool "Xapi_healthcheck_approaching_timeout";
 
366
                                                network_bonding_error                 = bool "network_bonding_error";
 
367
                                             })
 
368
                                end
 
369
                        | _ ->
 
370
                                None
 
371
        end
 
372
 
 
373
        module RawStatus = struct
 
374
                type t = {
 
375
                        statefile_latency: int;
 
376
                        statefile_min: int;
 
377
                        statefile_max: int;
 
378
                        heartbeat_latency: int;
 
379
                        heartbeat_min: int;
 
380
                        heartbeat_max: int;
 
381
                        xapi_healthcheck_latency: int;
 
382
                        xapi_healthcheck_min: int;
 
383
                        xapi_healthcheck_max: int;
 
384
                        host_raw_data: ([`host] Uuid.t, HostRawData.t) Hashtbl.t;
 
385
                }
 
386
                let of_xml_element = function
 
387
                        | Xml.Element("raw_status_on_local_host", _, children) ->
 
388
                                begin
 
389
                                        let table = hash_table_of_leaf_xml_element_list children in
 
390
                                        let find x = 
 
391
                                                try Hashtbl.find table x 
 
392
                                                with Not_found ->
 
393
                                                        invalid_arg (Printf.sprintf "Missing entry '%s' within 'raw_status_on_local_host' element" x) in
 
394
                                        let int s = 
 
395
                                                try int_of_string (String.lowercase s) 
 
396
                                                with Invalid_argument _ ->
 
397
                                                        invalid_arg (Printf.sprintf "Invalid integer value '%s' within 'raw_status_on_local_host' element" s) in
 
398
                                        let host_raw_data = Hashtbl.of_list (
 
399
                                                List.map
 
400
                                                        (fun host -> (host.HostRawData.id, host))
 
401
                                                        (List.filter_map HostRawData.of_xml_element children)
 
402
                                        ) in
 
403
 
 
404
                                        Some({
 
405
                                                statefile_latency        = int (find "statefile_latency"           );
 
406
                                                statefile_min            = int (find "statefile_latency_min"       );
 
407
                                                statefile_max            = int (find "statefile_latency_max"       );
 
408
                                                heartbeat_latency        = int (find "heartbeat_latency"           );
 
409
                                                heartbeat_min            = int (find "heartbeat_latency_min"       );
 
410
                                                heartbeat_max            = int (find "heartbeat_latency_max"       );
 
411
                                                xapi_healthcheck_latency = int (find "Xapi_healthcheck_latency"    );
 
412
                                                xapi_healthcheck_min     = int (find "Xapi_healthcheck_latency_min");
 
413
                                                xapi_healthcheck_max     = int (find "Xapi_healthcheck_latency_max");
 
414
                                                host_raw_data            = host_raw_data;
 
415
                                        })                                
 
416
                                end
 
417
                        | _ ->
 
418
                                None
 
419
        end
 
420
 
 
421
 
 
422
 
 
423
        type t = {
 
424
                status: Status.t;
 
425
                local_host_id: [`host] Uuid.t;
 
426
                hosts: ([`host] Uuid.t, Host.t) Hashtbl.t;
 
427
                raw_status_on_local_host: RawStatus.t option;
 
428
                warning_on_local_host: Warning.t option;
 
429
        }
 
430
 
 
431
        (** Creates a new HA live set information record *)
 
432
        (** from the given list of XML elements.         *)
 
433
        let of_xml_element_list elements = {
 
434
                hosts = Hashtbl.of_list (
 
435
                        List.map
 
436
                                (fun host -> (host.Host.id, host))
 
437
                                (List.filter_map Host.of_xml_element elements)
 
438
                );
 
439
                local_host_id = (
 
440
                        match first_xml_element_with_name elements "localhost" with
 
441
                                | Some Xml.Element
 
442
                                        (_, _ , [Xml.Element ("HostID", _, [Xml.PCData (local_host_id)])]) ->
 
443
                                                Uuid.of_string local_host_id
 
444
                                | _ ->
 
445
                                        invalid_arg "Invalid or missing 'localhost' element."
 
446
                );
 
447
                status = (
 
448
                        let status_option =
 
449
                                match first_xml_element_with_name elements "status" with
 
450
                                        | Some Xml.Element (_, _, [Xml.PCData (status_string)]) ->
 
451
                                                Status.of_string status_string
 
452
                                        | _ ->
 
453
                                                None in
 
454
                        match status_option with
 
455
                                | Some (status) -> status
 
456
                                | _ -> invalid_arg "Invalid or missing 'status' element."
 
457
                );
 
458
                raw_status_on_local_host = (
 
459
                        match first_xml_element_with_name elements "raw_status_on_local_host" with
 
460
                                | Some x -> RawStatus.of_xml_element x
 
461
                                | None -> None
 
462
                );
 
463
                warning_on_local_host = (
 
464
                        match first_xml_element_with_name elements "warning_on_local_host" with
 
465
                                | Some x -> Warning.of_xml_element x
 
466
                                | None -> None
 
467
                );
 
468
        }
 
469
 
 
470
        (** Creates a new HA live set information record *)
 
471
        (** from the given root XML element.             *)
 
472
        let of_xml_element = function
 
473
                | Xml.Element ("ha_liveset_info", _, children) ->
 
474
                        of_xml_element_list children
 
475
                | _ ->
 
476
                        invalid_arg "Invalid or missing 'ha_liveset_info' element."
 
477
 
 
478
        (** See interface. *)
 
479
        let of_xml_string string =
 
480
                of_xml_element (Xml.parse_string string)
 
481
 
 
482
        (** See interface. *)
 
483
        let to_summary_string t = 
 
484
                let status = Status.to_string t.status in
 
485
                let host h = Printf.sprintf "%s [%s%s%s%s%s%s]" 
 
486
                        (Uuid.string_of_uuid h.Host.id)
 
487
                        (if h.Host.id = t.local_host_id then "*" else " ")
 
488
                        (if h.Host.liveness             then "L" else " ")
 
489
                        (if h.Host.master               then "M" else " ")
 
490
                        (if h.Host.excluded             then "X" else " ")
 
491
                        (if h.Host.state_file_access    then "A" else " ")
 
492
                        (if h.Host.state_file_corrupted then "X" else " ") in
 
493
                status ^ " " ^ (Hashtbl.fold (fun _ h acc -> host h ^ "; " ^ acc) t.hosts "")
 
494
 
 
495
end
 
496
 
 
497
(* === Common I/O operations === *)
 
498
(*
 
499
(** Reads all lines from a input channel. *)
 
500
let string_of_channel input_channel =
 
501
        let rec string_of_channel input_channel input =
 
502
                try
 
503
                        let line = input_line input_channel in
 
504
                        string_of_channel input_channel (input ^ line ^ "\n")
 
505
                with End_of_file ->
 
506
                        input
 
507
        in
 
508
                string_of_channel input_channel ""
 
509
 
 
510
(** Reads all lines from a file. *)
 
511
let string_of_file file_path=
 
512
        let input_channel = open_in file_path in
 
513
        string_of_channel input_channel
 
514
*)
 
515
(* === Daemon configuration test === *)
 
516
(*
 
517
module DaemonConfigurationTest = struct
 
518
 
 
519
        include DaemonConfiguration
 
520
 
 
521
        module HostTest = struct
 
522
 
 
523
                include Host
 
524
 
 
525
                let mock_host_0 = {
 
526
                        uuid = "3a0d6864-42c6-4f82-8df9-d4cf3d747e2c";
 
527
                        address = "0.0.0.0"
 
528
                }
 
529
                let mock_host_1 = {
 
530
                        uuid = "96044fa9-2b43-444a-b764-f94fe10a5dec";
 
531
                        address = "0.0.0.1"
 
532
                }
 
533
                let mock_host_2 = {
 
534
                        uuid = "0447c77b-dc3f-4e75-8b97-eafb79a350fe";
 
535
                        address = "0.0.0.2"
 
536
                }
 
537
                let mock_host_3 = {
 
538
                        uuid = "7d9217cf-d59c-4b72-8116-7f860d4089c1";
 
539
                        address = "0.0.0.3"
 
540
                }
 
541
                let mock_hosts = [mock_host_0; mock_host_1; mock_host_2; mock_host_3]
 
542
 
 
543
        end
 
544
 
 
545
        let ($) a b = b a
 
546
        
 
547
        let _ =
 
548
                {
 
549
                        common_hosts               = HostTest.mock_hosts                   ;
 
550
                        common_generation_uuid     = "bac1a32e-8598-4aea-ba21-e13682e436d6";
 
551
                        common_udp_port            = 1234                                  ;
 
552
                        local_host_uuid            ="d45bd9d2-e0db-4a91-80f8-371de132c33e" ;
 
553
                        local_heart_beat_interface = "xebr0"                               ;
 
554
                        local_state_file           ="/dev/xvde"                            ;
 
555
                }
 
556
                $ DaemonConfiguration.to_xml_string
 
557
                $ print_endline
 
558
 
 
559
end
 
560
*)
 
561
(* === Live set information test === *)
 
562
(*
 
563
module LiveSetInformationTest = struct
 
564
 
 
565
        include LiveSetInformation
 
566
 
 
567
        module HostTest = struct
 
568
 
 
569
                include Host
 
570
 
 
571
                let to_string host =
 
572
                        "host {" ^
 
573
                                "id = "                   ^ (Uuid.to_string host.id                  ) ^ "; " ^
 
574
                                "liveness = "             ^ (string_of_bool host.liveness            ) ^ "; " ^
 
575
                                "master = "               ^ (string_of_bool host.master              ) ^ "; " ^
 
576
                                "state_file_access = "    ^ (string_of_bool host.state_file_access   ) ^ "; " ^
 
577
                                "state_file_corrupted = " ^ (string_of_bool host.state_file_corrupted) ^ "; " ^
 
578
                                "excluded = "             ^ (string_of_bool host.excluded            ) ^
 
579
                        "}"
 
580
 
 
581
        end
 
582
 
 
583
        let to_string info =
 
584
                "info {" ^
 
585
                        "status        = " ^ (Status.to_string info.status         ) ^ "; " ^
 
586
                        "local_host_id = " ^ (Uuid.to_string   info.local_host_id  ) ^ "; " ^
 
587
                        "hosts = [" ^
 
588
                                String.concat "; " (
 
589
                                        List.map (HostTest.to_string) (Hashtbl.fold_values info.hosts)
 
590
                                ) ^
 
591
                        "]" ^
 
592
                "}"
 
593
 
 
594
        let ($) f a = a f
 
595
        
 
596
        let _ =
 
597
                if Array.length Sys.argv != 2 then
 
598
                        print_endline "usage: xha_interface <path-to-xml-file>"
 
599
                else
 
600
                        Sys.argv. (1)
 
601
                        $ string_of_file
 
602
                        $ LiveSetInformation.of_xml_string
 
603
                        $ to_string
 
604
                        $ print_endline
 
605
 
 
606
end
 
607
*)