Class: PuppetX::Voxpupuli::Corosync::Provider::CibHelper

Inherits:
Puppet::Provider
  • Object
show all
Defined in:
lib/puppet_x/voxpupuli/corosync/provider/cib_helper.rb

Direct Known Subclasses

Crmsh, Pcs

Class Method Summary collapse

Class Method Details

._get_epoch(cmd, cib = nil) ⇒ Object



114
115
116
117
118
119
120
121
122
# File 'lib/puppet_x/voxpupuli/corosync/provider/cib_helper.rb', line 114

def self._get_epoch(cmd, cib = nil)
  raw, status = run_command_in_cib(cmd, cib, false)
  return :absent if status.nonzero?
  doc = REXML::Document.new(raw)
  current_epoch = REXML::XPath.first(doc, '/cib').attributes['epoch']
  current_admin_epoch = REXML::XPath.first(doc, '/cib').attributes['admin_epoch']
  currentvalue = "#{current_admin_epoch}.#{current_epoch}" if current_epoch && current_admin_epoch
  currentvalue || :absent
end

._run_command_in_cib(cmd, cib = nil, failonfail = true, custom_environment = { combine: true }) ⇒ Object

Raises:

  • (Puppet::Error)


14
15
16
17
18
19
20
21
22
# File 'lib/puppet_x/voxpupuli/corosync/provider/cib_helper.rb', line 14

def self._run_command_in_cib(cmd, cib = nil, failonfail = true, custom_environment = { combine: true })
  debug("Executing #{cmd} in the CIB") if cib.nil?
  debug("Executing #{cmd} in the shadow CIB \"#{cib}\"") unless cib.nil?
  raw = Puppet::Util::Execution.execute(cmd, { failonfail: failonfail }.merge(custom_environment))
  status = raw.exitstatus
  return raw, status if status.zero? || failonfail == false
  raise Puppet::Error, "Command #{cmd.join(' ')} failed" if cib.nil?
  raise Puppet::Error, "Command #{cmd.join(' ')} failed in the shadow CIB \"#{cib}\"" unless cib.nil?
end

.node2hash(node, anon_hash_nodes = []) ⇒ Object

The node2hash method maps resource locations from XML into hashes. An anonymous hash is returned for node names given in ‘anon_hash_nodes`.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/puppet_x/voxpupuli/corosync/provider/cib_helper.rb', line 39

def self.node2hash(node, anon_hash_nodes = [])
  attr = {}
  name = ''

  return nil unless node.instance_of? REXML::Element

  # Add attributes from the node
  node.attributes.each do |key, val|
    if key == 'id'
      name = val
    else
      attr[key] = val
    end
  end

  # Traverse elements in the XML tree recursively
  node.elements.each do |child|
    attr[child.name] = [] unless attr[child.name].is_a? Array
    attr[child.name] << node2hash(child, anon_hash_nodes)
  end

  # Return only the attributes if requested and a hash otherwise
  anon_hash_nodes.include?(node.name) ? attr : { name => attr }
end

.nvpairs_to_hash(e) ⇒ Object

given an XML element containing some <nvpair>s, return a hash. Return an empty hash if ‘e` is nil.



26
27
28
29
30
31
32
33
34
35
# File 'lib/puppet_x/voxpupuli/corosync/provider/cib_helper.rb', line 26

def self.nvpairs_to_hash(e)
  return {} if e.nil?

  hash = {}
  e.each_element do |i|
    hash[i.attributes['name']] = i.attributes['value'].strip
  end

  hash
end

.rule_expression(rulename, expressions, boolean_op = 'and') ⇒ Object

Generate a string with the rule expression

  • rulename is the name of the rule (used in error messages)

  • expressions is an array of expressions as returned by node2hash()

  • boolean_op is the operator; this must be either ‘and’ or ‘or’



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/puppet_x/voxpupuli/corosync/provider/cib_helper.rb', line 68

def self.rule_expression(rulename, expressions, boolean_op = 'and')
  rule_parameters = []
  count = 0

  if boolean_op != 'and' && boolean_op != 'or'
    raise Puppet::Error, "boolean-op must be 'and' or 'or' in rule #{rulename}"
  end

  expressions.each do |expr|
    rule_parameters << boolean_op if count > 0
    count += 1

    if expr['attribute'].nil?
      raise Puppet::Error, "attribute must be defined for expression #{count} in rule #{rulename}"
    end

    if expr['operation'].nil?
      raise Puppet::Error, "operation must be defined for expression #{count} in rule #{rulename}"
    end

    attribute = expr['attribute']
    operation = expr['operation']

    case operation
    when 'defined', 'not_defined'
      rule_parameters << operation
      rule_parameters << attribute

    when 'lt', 'gt', 'lte', 'gte', 'eq', 'ne'
      if expr['value'].nil?
        raise Puppet::Error, "value must be defined for expression #{count} in rule #{rulename}"
      end

      rule_parameters << attribute
      rule_parameters << operation
      rule_parameters << expr['value']

    else
      # FIXME: time- and date-based expressions not yet implemented
      raise Puppet::Error, "illegal operation '#{operation}' for expression #{count} in rule #{rulename}"
    end
  end

  rule_parameters
end

.wait_for_nonzero_epoch(shadow_cib) ⇒ Object

This function waits for the epoch to be different than 0.0 different than :absent. Returns the value of the epoch as soon an it is present and different that 0.0 or eventually returns the value after a certain time.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/puppet_x/voxpupuli/corosync/provider/cib_helper.rb', line 127

def self.wait_for_nonzero_epoch(shadow_cib)
  begin
    Timeout.timeout(60) do
      if shadow_cib
        epoch = get_epoch
        while epoch == :absent || epoch.start_with?('0.')
          sleep 2
          epoch = get_epoch
        end
      else
        sleep 2 while ['0.0', :absent].include?(get_epoch)
      end
    end
  rescue Timeout::Error
    debug('Timeout reached while fetching a relevant epoch')
  end
  get_epoch
end