|
| 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 | + |
| 15 | +module D=Debug.Make(struct let name="xapi" end) |
| 16 | +open D |
| 17 | + |
| 18 | +open Db_filter |
| 19 | +open Record_util |
| 20 | +open Threadext |
| 21 | +open Api_errors |
| 22 | + |
| 23 | +let all_operations = [ `ha_enable; `ha_disable ] |
| 24 | + |
| 25 | +(** Returns a table of operations -> API error options (None if the operation would be ok) *) |
| 26 | +let valid_operations ~__context record _ref' = |
| 27 | + let _ref = Ref.string_of _ref' in |
| 28 | + let current_ops = List.map snd record.Db_actions.pool_current_operations in |
| 29 | + |
| 30 | + let table = Hashtbl.create 10 in |
| 31 | + List.iter (fun x -> Hashtbl.replace table x None) all_operations; |
| 32 | + let set_errors (code: string) (params: string list) (ops: API.pool_allowed_operations_set) = |
| 33 | + List.iter (fun op -> |
| 34 | + if Hashtbl.find table op = None |
| 35 | + then Hashtbl.replace table op (Some(code, params))) ops in |
| 36 | + |
| 37 | + (* HA enable or disable cannot run if HA enable is in progress *) |
| 38 | + if List.mem `ha_enable current_ops |
| 39 | + then begin |
| 40 | + set_errors Api_errors.ha_enable_in_progress [] [ `ha_enable ]; |
| 41 | + set_errors Api_errors.ha_enable_in_progress [] [ `ha_disable ] |
| 42 | + end; |
| 43 | + (* HA enable or disable cannot run if HA disable is in progress *) |
| 44 | + if List.mem `ha_disable current_ops |
| 45 | + then begin |
| 46 | + set_errors Api_errors.ha_disable_in_progress [] [ `ha_enable ]; |
| 47 | + set_errors Api_errors.ha_disable_in_progress [] [ `ha_disable ] |
| 48 | + end; |
| 49 | + |
| 50 | + (* HA disable cannot run if HA is already disabled on a pool *) |
| 51 | + (* HA enable cannot run if HA is already enabled on a pool *) |
| 52 | + let ha_enabled = Db.Pool.get_ha_enabled ~__context ~self:(Helpers.get_pool ~__context) in |
| 53 | + if ha_enabled then |
| 54 | + set_errors Api_errors.ha_is_enabled [] [ `ha_enable ] |
| 55 | + else |
| 56 | + set_errors Api_errors.ha_not_enabled [] [ `ha_disable ]; |
| 57 | + |
| 58 | + table |
| 59 | + |
| 60 | +let throw_error table op = |
| 61 | + if not(Hashtbl.mem table op) |
| 62 | + then raise (Api_errors.Server_error(Api_errors.internal_error, [ Printf.sprintf "xapi_pool_helpers.assert_operation_valid unknown operation: %s" (pool_operation_to_string op) ])); |
| 63 | + |
| 64 | + match Hashtbl.find table op with |
| 65 | + | Some (code, params) -> raise (Api_errors.Server_error(code, params)) |
| 66 | + | None -> () |
| 67 | + |
| 68 | +let assert_operation_valid ~__context ~self ~(op:API.pool_allowed_operations) = |
| 69 | + let all = Db.Pool.get_record_internal ~__context ~self in |
| 70 | + let table = valid_operations ~__context all self in |
| 71 | + throw_error table op |
| 72 | + |
| 73 | +let update_allowed_operations ~__context ~self : unit = |
| 74 | + let all = Db.Pool.get_record_internal ~__context ~self in |
| 75 | + let valid = valid_operations ~__context all self in |
| 76 | + let keys = Hashtbl.fold (fun k v acc -> if v = None then k :: acc else acc) valid [] in |
| 77 | + Db.Pool.set_allowed_operations ~__context ~self ~value:keys |
| 78 | + |
| 79 | +(* Checks whether HA enable is in progress *) |
| 80 | +let ha_enable_in_progress ~__context = |
| 81 | + let pool = Helpers.get_pool ~__context in |
| 82 | + let current_ops = Db.Pool.get_current_operations ~__context ~self:pool in |
| 83 | + if List.exists (fun (_, x) -> x = `ha_enable) current_ops then true else false |
| 84 | + |
| 85 | +(* Checks whether HA disable is in progress *) |
| 86 | +let ha_disable_in_progress ~__context = |
| 87 | + let pool = Helpers.get_pool ~__context in |
| 88 | + let current_ops = Db.Pool.get_current_operations ~__context ~self:pool in |
| 89 | + if List.exists (fun (_, x) -> x = `ha_disable) current_ops then true else false |
| 90 | + |
0 commit comments