-
-
Notifications
You must be signed in to change notification settings - Fork 158
/
crm.rb
129 lines (113 loc) · 4.52 KB
/
crm.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# frozen_string_literal: false
begin
require 'puppet_x/voxpupuli/corosync/provider/crmsh'
rescue LoadError
require 'pathname' # WORKAROUND #14073, #7788 and SERVER-973
corosync = Puppet::Module.find('corosync')
raise(LoadError, "Unable to find corosync module in modulepath #{Puppet[:basemodulepath] || Puppet[:modulepath]}") unless corosync
require File.join corosync.path, 'lib/puppet_x/voxpupuli/corosync/provider/crmsh'
end
Puppet::Type.type(:cs_clone).provide(:crm, parent: PuppetX::Voxpupuli::Corosync::Provider::Crmsh) do
desc 'Provider to add, delete, manipulate primitive clones.'
# Path to the crm binary for interacting with the cluster configuration.
# Decided to just go with relative.
commands crm: 'crm'
commands crm_attribute: 'crm_attribute'
mk_resource_methods
def self.instances
block_until_ready
instances = []
cmd = [command(:crm), 'configure', 'show', 'xml']
raw, = run_command_in_cib(cmd)
doc = REXML::Document.new(raw)
REXML::XPath.each(doc, '//resources//clone') do |e|
items = nvpairs_to_hash(e.elements['meta_attributes'])
clone_instance = {
name: e.attributes['id'],
ensure: :present,
clone_max: items['clone-max'],
clone_node_max: items['clone-node-max'],
notify_clones: items['notify'],
globally_unique: items['globally-unique'],
ordered: items['ordered'],
interleave: items['interleave'],
promotable: items['promotable'],
promoted_max: items['promoted-max'],
promoted_node_max: items['promoted-node-max'],
existing_resource: :true
}
clone_instance[:primitive] = e.elements['primitive'].attributes['id'] if e.elements['primitive']
clone_instance[:group] = e.elements['group'].attributes['id'] if e.elements['group']
instances << new(clone_instance)
end
instances
end
# Create just adds our resource to the property_hash and flush will take care
# of actually doing the work.
def create
@property_hash = {
name: @resource[:name],
ensure: :present,
primitive: @resource[:primitive],
clone_max: @resource[:clone_max],
clone_node_max: @resource[:clone_node_max],
notify_clones: @resource[:notify_clones],
globally_unique: @resource[:globally_unique],
ordered: @resource[:ordered],
interleave: @resource[:interleave],
cib: @resource[:cib],
promotable: @resource[:promotable],
promoted_max: @resource[:promoted_max],
promoted_node_max: @resource[:promoted_node_max],
existing_resource: :false
}
end
# Unlike create we actually immediately delete the item.
def destroy
debug('Removing clone')
cmd = [command(:crm), '-w', 'resource', 'stop', @resource[:name]]
self.class.run_command_in_cib(cmd, @resource[:cib], false)
cmd = [command(:crm), 'configure', 'delete', @resource[:name]]
self.class.run_command_in_cib(cmd, @resource[:cib])
@property_hash.clear
end
# Flush is triggered on anything that has been detected as being
# modified in the property_hash. It generates a temporary file with
# the updates that need to be made. The temporary file is then used
# as stdin for the crm command.
def flush
return if @property_hash.empty?
if @resource.should(:primitive)
target = @resource.should(:primitive)
elsif @resource.should(:group)
target = @resource.should(:group)
else
raise Puppet::Error, 'No primitive or group'
end
updated = 'clone '
updated << "#{@resource.value(:name)} "
updated << "#{target} "
meta = []
{
clone_max: 'clone-max',
clone_node_max: 'clone-node-max',
notify_clones: 'notify',
globally_unique: 'globally-unique',
ordered: 'ordered',
interleave: 'interleave',
promotable: 'promotable',
promoted_max: 'promoted-max',
promoted_node_max: 'promoted-node-max'
}.each do |property, clone_property|
meta << "#{clone_property}=#{@resource.should(property)}" unless @resource.should(property) == :absent
end
updated << 'meta ' << meta.join(' ') unless meta.empty?
debug "Update: #{updated}"
Tempfile.open('puppet_crm_update') do |tmpfile|
tmpfile.write(updated)
tmpfile.flush
cmd = [command(:crm), 'configure', 'load', 'update', tmpfile.path.to_s]
self.class.run_command_in_cib(cmd, @resource.value(:cib))
end
end
end